mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
Merge branch 'dev/djui' into dev/unstable
This commit is contained in:
commit
4e0a3e3e57
260 changed files with 7168 additions and 2170 deletions
6
Makefile
6
Makefile
|
@ -316,7 +316,7 @@ LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
|
|||
|
||||
# Hi, I'm a PC
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes
|
||||
SRC_DIRS += src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils
|
||||
SRC_DIRS += src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils src/pc/djui
|
||||
ASM_DIRS :=
|
||||
|
||||
#ifeq ($(DISCORDRPC),1)
|
||||
|
@ -858,9 +858,6 @@ $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in
|
|||
$(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in
|
||||
$(TEXTCONV) charmap_menu.txt $< $@
|
||||
|
||||
$(BUILD_DIR)/include/text_options_strings.h: include/text_options_strings.h.in
|
||||
$(TEXTCONV) charmap.txt $< $@
|
||||
|
||||
ifeq ($(VERSION),eu)
|
||||
TEXT_DIRS := text/de text/us text/fr
|
||||
|
||||
|
@ -899,7 +896,6 @@ ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GOD
|
|||
DUMMY != mkdir -p $(ALL_DIRS)
|
||||
|
||||
$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h
|
||||
$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_options_strings.h
|
||||
|
||||
ifeq ($(VERSION),eu)
|
||||
$(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
|
||||
|
|
|
@ -193,6 +193,7 @@ SKY_FILES := $(patsubst %.png,%.inc.c,$(wildcard $(TEXTURE_DI
|
|||
MACHINE_FILES := $(patsubst %.png,%.inc.c,$(wildcard $(TEXTURE_DIR)/machine/*.png))
|
||||
MOUNTAIN_FILES := $(patsubst %.png,%.inc.c,$(wildcard $(TEXTURE_DIR)/mountain/*.png))
|
||||
GRASS_FILES := $(patsubst %.png,%.inc.c,$(wildcard $(TEXTURE_DIR)/grass/*.png))
|
||||
CUSTOM_FONT_TITLE_FILES := $(patsubst %.png,%.inc.c,$(wildcard $(TEXTURE_DIR)/custom_font_title/*.png))
|
||||
|
||||
# Texture Files
|
||||
$(BUILD_DIR)/bin/segment2.o: $(addprefix $(BUILD_DIR)/,$(SEGMENT2_FILES))
|
||||
|
@ -210,6 +211,7 @@ $(BUILD_DIR)/bin/sky.o: $(addprefix $(BUILD_DIR)/,$(SKY_FILES))
|
|||
$(BUILD_DIR)/bin/machine.o: $(addprefix $(BUILD_DIR)/,$(MACHINE_FILES))
|
||||
$(BUILD_DIR)/bin/mountain.o: $(addprefix $(BUILD_DIR)/,$(MOUNTAIN_FILES))
|
||||
$(BUILD_DIR)/bin/grass.o: $(addprefix $(BUILD_DIR)/,$(GRASS_FILES))
|
||||
$(BUILD_DIR)/bin/custom_font_title.o: $(addprefix $(BUILD_DIR)/,$(CUSTOM_FONT_TITLE_FILES))
|
||||
|
||||
# Others
|
||||
$(BUILD_DIR)/bin/segment2.elf: SEGMENT_ADDRESS := 0x02000000
|
||||
|
@ -228,6 +230,7 @@ $(BUILD_DIR)/bin/sky.elf: SEGMENT_ADDRESS := 0x09000000
|
|||
$(BUILD_DIR)/bin/machine.elf: SEGMENT_ADDRESS := 0x09000000
|
||||
$(BUILD_DIR)/bin/mountain.elf: SEGMENT_ADDRESS := 0x09000000
|
||||
$(BUILD_DIR)/bin/grass.elf: SEGMENT_ADDRESS := 0x09000000
|
||||
$(BUILD_DIR)/bin/custom_font_title.elf: SEGMENT_ADDRESS := 0x09000000
|
||||
|
||||
# EU segment 19 translations
|
||||
$(BUILD_DIR)/bin/eu/translation_de.elf: SEGMENT_ADDRESS := 0x19000000
|
||||
|
|
499
bin/custom_font_title.c
Normal file
499
bin/custom_font_title.c
Normal file
|
@ -0,0 +1,499 @@
|
|||
#include <ultra64.h>
|
||||
#include "sm64.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "make_const_nonconst.h"
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_01[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_01.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_02[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_02.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_03[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_03.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_04[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_04.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_05[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_05.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_06[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_06.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_07[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_07.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_08[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_08.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_09[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_09.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_10[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_10.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_11[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_11.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_12[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_12.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_13[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_13.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_14[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_14.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_15[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_15.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_16[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_16.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_17[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_17.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_18[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_18.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_19[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_19.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_20[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_20.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_21[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_21.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_22[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_22.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_23[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_23.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_24[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_24.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_25[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_25.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_26[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_26.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_27[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_27.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_28[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_28.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_29[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_29.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_30[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_30.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_31[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_31.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_32[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_32.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_33[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_33.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_34[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_34.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_35[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_35.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_36[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_36.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_37[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_37.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_38[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_38.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_39[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_39.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_40[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_40.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_41[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_41.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_42[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_42.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_43[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_43.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_44[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_44.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_45[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_45.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_46[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_46.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_47[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_47.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_48[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_48.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_49[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_49.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_50[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_50.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_51[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_51.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_52[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_52.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_53[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_53.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_54[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_54.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_55[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_55.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_56[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_56.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_57[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_57.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_58[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_58.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_59[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_59.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_60[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_60.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_61[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_61.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_62[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_62.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_63[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_63.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_64[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_64.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_65[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_65.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_66[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_66.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_67[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_67.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_68[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_68.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_69[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_69.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_70[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_70.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_71[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_71.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_72[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_72.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_73[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_73.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_74[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_74.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_75[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_75.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_76[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_76.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_77[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_77.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_78[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_78.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_79[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_79.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_80[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_80.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_81[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_81.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_82[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_82.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_83[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_83.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_84[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_84.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_85[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_85.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_86[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_86.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_87[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_87.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_88[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_88.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_89[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_89.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_90[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_90.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_91[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_91.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_92[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_92.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_93[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_93.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_94[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_94.rgba32.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_title_char_95[] = {
|
||||
#include "textures/custom_font_title/custom_font_title_95.rgba32.inc.c"
|
||||
};
|
||||
|
||||
const u8* const font_title_chars[] = {
|
||||
texture_font_title_char_01, // !
|
||||
texture_font_title_char_02, // "
|
||||
texture_font_title_char_03, // #
|
||||
texture_font_title_char_04, // $
|
||||
texture_font_title_char_05, // %
|
||||
texture_font_title_char_06, // &
|
||||
texture_font_title_char_07, // '
|
||||
texture_font_title_char_08, // (
|
||||
texture_font_title_char_09, // )
|
||||
texture_font_title_char_10, // *
|
||||
texture_font_title_char_11, // +
|
||||
texture_font_title_char_12, // ,
|
||||
texture_font_title_char_13, // -
|
||||
texture_font_title_char_14, // .
|
||||
texture_font_title_char_15, // /
|
||||
texture_font_title_char_16, // 0
|
||||
texture_font_title_char_17, // 1
|
||||
texture_font_title_char_18, // 2
|
||||
texture_font_title_char_19, // 3
|
||||
texture_font_title_char_20, // 4
|
||||
texture_font_title_char_21, // 5
|
||||
texture_font_title_char_22, // 6
|
||||
texture_font_title_char_23, // 7
|
||||
texture_font_title_char_24, // 8
|
||||
texture_font_title_char_25, // 9
|
||||
texture_font_title_char_26, // :
|
||||
texture_font_title_char_27, // ;
|
||||
texture_font_title_char_28, // <
|
||||
texture_font_title_char_29, // =
|
||||
texture_font_title_char_30, // >
|
||||
texture_font_title_char_31, // ?
|
||||
texture_font_title_char_32, // @
|
||||
texture_font_title_char_33, // A
|
||||
texture_font_title_char_34, // B
|
||||
texture_font_title_char_35, // C
|
||||
texture_font_title_char_36, // D
|
||||
texture_font_title_char_37, // E
|
||||
texture_font_title_char_38, // F
|
||||
texture_font_title_char_39, // G
|
||||
texture_font_title_char_40, // H
|
||||
texture_font_title_char_41, // I
|
||||
texture_font_title_char_42, // J
|
||||
texture_font_title_char_43, // K
|
||||
texture_font_title_char_44, // L
|
||||
texture_font_title_char_45, // M
|
||||
texture_font_title_char_46, // N
|
||||
texture_font_title_char_47, // O
|
||||
texture_font_title_char_48, // P
|
||||
texture_font_title_char_49, // Q
|
||||
texture_font_title_char_50, // R
|
||||
texture_font_title_char_51, // S
|
||||
texture_font_title_char_52, // T
|
||||
texture_font_title_char_53, // U
|
||||
texture_font_title_char_54, // V
|
||||
texture_font_title_char_55, // W
|
||||
texture_font_title_char_56, // X
|
||||
texture_font_title_char_57, // Y
|
||||
texture_font_title_char_58, // Z
|
||||
texture_font_title_char_59, // [
|
||||
texture_font_title_char_60, // \ //
|
||||
texture_font_title_char_61, // ]
|
||||
texture_font_title_char_62, // ^
|
||||
texture_font_title_char_63, // _
|
||||
texture_font_title_char_64, // `
|
||||
texture_font_title_char_65, // a
|
||||
texture_font_title_char_66, // b
|
||||
texture_font_title_char_67, // c
|
||||
texture_font_title_char_68, // d
|
||||
texture_font_title_char_69, // e
|
||||
texture_font_title_char_70, // f
|
||||
texture_font_title_char_71, // g
|
||||
texture_font_title_char_72, // h
|
||||
texture_font_title_char_73, // i
|
||||
texture_font_title_char_74, // j
|
||||
texture_font_title_char_75, // k
|
||||
texture_font_title_char_76, // l
|
||||
texture_font_title_char_77, // m
|
||||
texture_font_title_char_78, // n
|
||||
texture_font_title_char_79, // o
|
||||
texture_font_title_char_80, // p
|
||||
texture_font_title_char_81, // q
|
||||
texture_font_title_char_82, // r
|
||||
texture_font_title_char_83, // s
|
||||
texture_font_title_char_84, // t
|
||||
texture_font_title_char_85, // u
|
||||
texture_font_title_char_86, // v
|
||||
texture_font_title_char_87, // w
|
||||
texture_font_title_char_88, // x
|
||||
texture_font_title_char_89, // y
|
||||
texture_font_title_char_90, // z
|
||||
texture_font_title_char_91, // {
|
||||
texture_font_title_char_92, // |
|
||||
texture_font_title_char_93, // }
|
||||
texture_font_title_char_94, // ~
|
||||
texture_font_title_char_95, // DEL
|
||||
};
|
||||
|
||||
const f32 font_title_widths[] = {
|
||||
/* ! " # $ % & ' ( ) * + , - . / */
|
||||
0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f,
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
0.45f, 0.35f, 0.45f, 0.45f, 0.45f, 0.45f, 0.45f, 0.45f, 0.45f, 0.45f,
|
||||
/* : ; < = > ? @ */
|
||||
0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f,
|
||||
/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
|
||||
0.55f, 0.50f, 0.50f, 0.50f, 0.45f, 0.45f, 0.50f, 0.55f, 0.28f, 0.60f, 0.50f, 0.45f, 0.55f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.55f, 0.50f, 0.50f, 0.50f, 0.60f, 0.52f, 0.60f, 0.45f,
|
||||
/* [ \ ] ^ _ ` */
|
||||
0.50f, 0.50f, 0.50f, 0.50f, 0.50f, 0.50f,
|
||||
/* a b c d e f g h i j k l m n o p q r s t u v w x y z */
|
||||
0.45f, 0.45f, 0.40f, 0.40f, 0.45f, 0.37f, 0.40f, 0.40f, 0.20f, 0.45f, 0.40f, 0.30f, 0.50f, 0.40f, 0.40f, 0.40f, 0.45f, 0.40f, 0.50f, 0.45f, 0.50f, 0.40f, 0.50f, 0.50f, 0.45f, 0.45f,
|
||||
/* { | } ~ DEL */
|
||||
0.50f, 0.50f, 0.50f, 0.50f, 0.50f,
|
||||
};
|
197
bin/segment2.c
197
bin/segment2.c
|
@ -3372,3 +3372,200 @@ const s16 seg2_painting_mesh_neighbor_tris[] = {
|
|||
3, 240, 242, 244,
|
||||
1, 243,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_03[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_03.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_04[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_04.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_10[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_10.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_11[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_11.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_15[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_15.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_26[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_26.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_27[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_27.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_28[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_28.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_29[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_29.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_30[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_30.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_32[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_32.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_59[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_59.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_60[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_60.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_61[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_61.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_62[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_62.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_63[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_63.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_64[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_64.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_91[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_91.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_92[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_92.ia4.inc.c"
|
||||
};
|
||||
|
||||
ALIGNED8 static const u8 texture_font_normal_char_93[] = {
|
||||
#include "textures/segment2/custom_font_normal_char_93.ia4.inc.c"
|
||||
};
|
||||
|
||||
const u8* const font_normal_chars[] = {
|
||||
texture_font_char_us_exclamation, // !
|
||||
texture_font_char_us_double_quote_open, // "
|
||||
texture_font_normal_char_03, // #
|
||||
texture_font_normal_char_04, // $
|
||||
texture_font_char_us_percent, // %
|
||||
texture_font_char_us_ampersand, // &
|
||||
texture_font_char_us_apostrophe, // '
|
||||
texture_font_char_us_open_parentheses, // (
|
||||
texture_font_char_us_close_parentheses, // )
|
||||
texture_font_normal_char_10, // *
|
||||
texture_font_normal_char_11, // +
|
||||
texture_font_char_us_comma, // ,
|
||||
texture_font_char_us_slash, // -
|
||||
texture_font_char_us_period, // .
|
||||
texture_font_normal_char_15, // /
|
||||
texture_font_char_us_0, // 0
|
||||
texture_font_char_us_1, // 1
|
||||
texture_font_char_us_2, // 2
|
||||
texture_font_char_us_3, // 3
|
||||
texture_font_char_us_4, // 4
|
||||
texture_font_char_us_5, // 5
|
||||
texture_font_char_us_6, // 6
|
||||
texture_font_char_us_7, // 7
|
||||
texture_font_char_us_8, // 8
|
||||
texture_font_char_us_9, // 9
|
||||
texture_font_normal_char_26, // :
|
||||
texture_font_normal_char_27, // ;
|
||||
texture_font_normal_char_28, // <
|
||||
texture_font_normal_char_29, // =
|
||||
texture_font_normal_char_30, // >
|
||||
texture_font_char_us_question, // ?
|
||||
texture_font_normal_char_32, // @
|
||||
texture_font_char_us_A, // A
|
||||
texture_font_char_us_B, // B
|
||||
texture_font_char_us_C, // C
|
||||
texture_font_char_us_D, // D
|
||||
texture_font_char_us_E, // E
|
||||
texture_font_char_us_F, // F
|
||||
texture_font_char_us_G, // G
|
||||
texture_font_char_us_H, // H
|
||||
texture_font_char_us_I, // I
|
||||
texture_font_char_us_J, // J
|
||||
texture_font_char_us_K, // K
|
||||
texture_font_char_us_L, // L
|
||||
texture_font_char_us_M, // M
|
||||
texture_font_char_us_N, // N
|
||||
texture_font_char_us_O, // O
|
||||
texture_font_char_us_P, // P
|
||||
texture_font_char_us_Q, // Q
|
||||
texture_font_char_us_R, // R
|
||||
texture_font_char_us_S, // S
|
||||
texture_font_char_us_T, // T
|
||||
texture_font_char_us_U, // U
|
||||
texture_font_char_us_V, // V
|
||||
texture_font_char_us_W, // W
|
||||
texture_font_char_us_X, // X
|
||||
texture_font_char_us_Y, // Y
|
||||
texture_font_char_us_Z, // Z
|
||||
texture_font_normal_char_59, // [
|
||||
texture_font_normal_char_60, // \ //
|
||||
texture_font_normal_char_61, // ]
|
||||
texture_font_normal_char_62, // ^
|
||||
texture_font_normal_char_63, // _
|
||||
texture_font_normal_char_64, // `
|
||||
texture_font_char_us_a, // a
|
||||
texture_font_char_us_b, // b
|
||||
texture_font_char_us_c, // c
|
||||
texture_font_char_us_d, // d
|
||||
texture_font_char_us_e, // e
|
||||
texture_font_char_us_f, // f
|
||||
texture_font_char_us_g, // g
|
||||
texture_font_char_us_h, // h
|
||||
texture_font_char_us_i, // i
|
||||
texture_font_char_us_j, // j
|
||||
texture_font_char_us_k, // k
|
||||
texture_font_char_us_l, // l
|
||||
texture_font_char_us_m, // m
|
||||
texture_font_char_us_n, // n
|
||||
texture_font_char_us_o, // o
|
||||
texture_font_char_us_p, // p
|
||||
texture_font_char_us_q, // q
|
||||
texture_font_char_us_r, // r
|
||||
texture_font_char_us_s, // s
|
||||
texture_font_char_us_t, // t
|
||||
texture_font_char_us_u, // u
|
||||
texture_font_char_us_v, // v
|
||||
texture_font_char_us_w, // w
|
||||
texture_font_char_us_x, // x
|
||||
texture_font_char_us_y, // y
|
||||
texture_font_char_us_z, // z
|
||||
texture_font_normal_char_91, // {
|
||||
texture_font_normal_char_92, // |
|
||||
texture_font_normal_char_93, // }
|
||||
texture_font_char_us_tilde, // ~
|
||||
texture_font_char_us_star_filled, // DEL
|
||||
};
|
||||
|
||||
const f32 font_normal_widths[] = {
|
||||
/* ! " # $ % & ' ( ) * + , - . / */
|
||||
0.3125f, 0.3750f, 0.4375f, 0.3750f, 0.4375f, 0.5000f, 0.2500f, 0.3125f, 0.3125f, 0.3750f, 0.4375f, 0.2500f, 0.3750f, 0.2500f, 0.3125f,
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f, 0.4375f,
|
||||
/* : ; < = > ? @ */
|
||||
0.2500f, 0.2500f, 0.3125f, 0.3750f, 0.3125f, 0.4375f, 0.5750f,
|
||||
/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
|
||||
0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3125f, 0.3750f, 0.3750f, 0.3125f, 0.5000f, 0.5000f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3750f, 0.3125f, 0.3750f, 0.3750f, 0.5000f, 0.4375f, 0.3750f, 0.3750f,
|
||||
/* [ \ ] ^ _ ` */
|
||||
0.3125f, 0.3125f, 0.3125f, 0.3750f, 0.3750f, 0.2500f,
|
||||
/* a b c d e f g h i j k l m n o p q r s t u v w x y z */
|
||||
0.3750f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.2500f, 0.3125f, 0.3125f, 0.1875f, 0.4375f, 0.3125f, 0.3125f, 0.3125f, 0.3750f, 0.3125f, 0.3125f, 0.3125f, 0.3125f, 0.3125f, 0.4375f, 0.4375f, 0.3125f, 0.3125f,
|
||||
/* { | } ~ DEL */
|
||||
0.3125f, 0.2500f, 0.3125f, 0.5000f, 0.5000f
|
||||
};
|
|
@ -71,7 +71,7 @@
|
|||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>../;../include/;../src/;$(IncludePath)</IncludePath>
|
||||
<IncludePath>../;../include/;../src/;C:/msys64/mingw64/include;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)\..\build\us_pc\</OutDir>
|
||||
<TargetName>sm64.us.f3dex2e</TargetName>
|
||||
</PropertyGroup>
|
||||
|
@ -89,7 +89,7 @@
|
|||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;WINSOCK;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;WINSOCK;DEBUG;CAPI_SDL2;WAPI_SDL2;RAPI_GL;F3DEX_GBI_2;_LANGUAGE_C;BETTERCAMERA;VERSION_US;EXT_OPTIONS_MENU;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -3849,7 +3849,6 @@
|
|||
<ClCompile Include="..\src\game\behaviors\yoshi.inc.c" />
|
||||
<ClCompile Include="..\src\game\camera.c" />
|
||||
<ClCompile Include="..\src\game\characters.c" />
|
||||
<ClCompile Include="..\src\game\chat.c" />
|
||||
<ClCompile Include="..\src\game\debug.c" />
|
||||
<ClCompile Include="..\src\game\debug_course.c" />
|
||||
<ClCompile Include="..\src\game\envfx_bubbles.c" />
|
||||
|
@ -3924,9 +3923,7 @@
|
|||
<ClCompile Include="..\src\goddard\shape_helper.c" />
|
||||
<ClCompile Include="..\src\goddard\skin.c" />
|
||||
<ClCompile Include="..\src\goddard\skin_movement.c" />
|
||||
<ClCompile Include="..\src\menu\custom_menu.c" />
|
||||
<ClCompile Include="..\src\menu\file_select.c" />
|
||||
<ClCompile Include="..\src\menu\custom_menu_system.c" />
|
||||
<ClCompile Include="..\src\menu\intro_geo.c" />
|
||||
<ClCompile Include="..\src\menu\level_select_menu.c" />
|
||||
<ClCompile Include="..\src\menu\star_select.c" />
|
||||
|
@ -3940,8 +3937,47 @@
|
|||
<ClCompile Include="..\src\pc\controller\controller_keyboard.c" />
|
||||
<ClCompile Include="..\src\pc\controller\controller_keyboard_debug.c" />
|
||||
<ClCompile Include="..\src\pc\controller\controller_recorded_tas.c" />
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl.c" />
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl1.c" />
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl2.c" />
|
||||
<ClCompile Include="..\src\pc\discord\discordrpc.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_base.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_bind.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_button.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_chat_box.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_chat_message.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_checkbox.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_inputbox.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_cheats.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_controls.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host_message.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host_save.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_join.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_join_message.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_menu.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_pause.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_popup.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_selectionbox.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_cursor.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_flow_layout.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_font.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_gfx.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_image.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_interactable.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_camera.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_debug.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_display.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_main.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_options.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_confirm.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_sound.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_rect.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_root.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_slider.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_text.c" />
|
||||
<ClCompile Include="..\src\pc\djui\djui_three_panel.c" />
|
||||
<ClCompile Include="..\src\pc\fs\dirtree.c" />
|
||||
<ClCompile Include="..\src\pc\fs\fs.c" />
|
||||
<ClCompile Include="..\src\pc\fs\fs_packtype_dir.c" />
|
||||
|
@ -4008,6 +4044,8 @@
|
|||
<ClCompile Include="..\src\pc\pc_main.c" />
|
||||
<ClCompile Include="..\src\pc\platform.c" />
|
||||
<ClCompile Include="..\src\pc\ultra_reimplementation.c" />
|
||||
<ClCompile Include="..\src\pc\utils\misc.c" />
|
||||
<ClCompile Include="..\src\pc\utils\string_builder.c" />
|
||||
<ClCompile Include="..\src\pc\utils\string_linked_list.c" />
|
||||
<ClCompile Include="..\text\define_courses.inc.c" />
|
||||
<ClCompile Include="..\text\define_text.inc.c" />
|
||||
|
@ -4347,12 +4385,49 @@
|
|||
<ClInclude Include="..\include\behavior_table.h" />
|
||||
<ClInclude Include="..\include\luigi_audio_defines.h" />
|
||||
<ClInclude Include="..\src\game\characters.h" />
|
||||
<ClInclude Include="..\src\game\chat.h" />
|
||||
<ClInclude Include="..\src\game\rng_position.h" />
|
||||
<ClInclude Include="..\src\menu\custom_menu.h" />
|
||||
<ClInclude Include="..\src\menu\custom_menu_system.h" />
|
||||
<ClInclude Include="..\src\pc\controller\controller_keyboard_debug.h" />
|
||||
<ClInclude Include="..\src\pc\debuglog.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_base.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_bind.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_button.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_chat_box.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_chat_message.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_checkbox.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_inputbox.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_cheats.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_controls.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host_message.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host_save.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_join.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_join_message.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_menu.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_pause.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_popup.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_selectionbox.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_cursor.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_flow_layout.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_font.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_gbi.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_gfx.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_image.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_interactable.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_camera.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_debug.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_display.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_main.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_options.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_confirm.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_sound.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_rect.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_root.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_slider.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_text.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_three_panel.h" />
|
||||
<ClInclude Include="..\src\pc\djui\djui_types.h" />
|
||||
<ClInclude Include="..\src\pc\network\branch.h" />
|
||||
<ClInclude Include="..\src\pc\network\discord\activity.h" />
|
||||
<ClInclude Include="..\src\pc\network\discord\discord.h" />
|
||||
|
@ -4367,9 +4442,11 @@
|
|||
<ClInclude Include="..\src\pc\network\socket\socket_linux.h" />
|
||||
<ClInclude Include="..\src\pc\network\socket\socket_windows.h" />
|
||||
<ClInclude Include="..\src\pc\network\version.h" />
|
||||
<ClInclude Include="..\src\pc\utils\misc.h" />
|
||||
<ClInclude Include="..\src\pc\utils\string_builder.h" />
|
||||
<ClInclude Include="..\src\pc\utils\string_linked_list.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -3445,6 +3445,18 @@
|
|||
<Filter Include="Source Files\src\pc\network\packets\reservation-area">
|
||||
<UniqueIdentifier>{9ddfaa87-399e-4f61-aae3-f91af79e14cc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\src\pc\djui">
|
||||
<UniqueIdentifier>{0e1e4798-796e-4801-be6e-69d0c3b05ad7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\src\pc\djui\panel">
|
||||
<UniqueIdentifier>{2401a619-ee3f-4637-9926-a619a5e65bcb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\src\pc\djui\component">
|
||||
<UniqueIdentifier>{471ac819-ed6b-4a33-8952-50a8e0d2d839}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\src\pc\djui\component\compound">
|
||||
<UniqueIdentifier>{a7515004-4574-4bc0-9288-f716100c8a43}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\amp\anims\anim_0800401C.inc.c">
|
||||
|
@ -14805,9 +14817,6 @@
|
|||
<ClCompile Include="..\src\pc\controller\controller_recorded_tas.c">
|
||||
<Filter>Source Files\src\pc\controller</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl.c">
|
||||
<Filter>Source Files\src\pc\controller</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\discord\discordrpc.c">
|
||||
<Filter>Source Files\src\pc\discord</Filter>
|
||||
</ClCompile>
|
||||
|
@ -15033,15 +15042,6 @@
|
|||
<ClCompile Include="..\src\pc\network\discord\discord_network.c">
|
||||
<Filter>Source Files\src\pc\network\discord</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\menu\custom_menu_system.c">
|
||||
<Filter>Source Files\src\menu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\menu\custom_menu.c">
|
||||
<Filter>Source Files\src\menu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\game\chat.c">
|
||||
<Filter>Source Files\src\game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_chat.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
|
@ -15144,6 +15144,132 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_save_set_flag.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui.c">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_gfx.c">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_image.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_rect.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_text.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_base.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_root.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl1.c">
|
||||
<Filter>Source Files\src\pc\controller</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\controller\controller_sdl2.c">
|
||||
<Filter>Source Files\src\pc\controller</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_interactable.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_flow_layout.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_button.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_main.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\utils\misc.c">
|
||||
<Filter>Source Files\src\pc\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_font.c">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_debug.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_options.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_cursor.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_three_panel.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_sound.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_slider.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_camera.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_checkbox.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_display.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_selectionbox.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_controls.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_bind.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_menu.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host_message.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_inputbox.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_join.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_join_message.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\utils\string_builder.c">
|
||||
<Filter>Source Files\src\pc\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_popup.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_host_save.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_confirm.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_pause.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_panel_cheats.c">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_chat_box.c">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\djui\djui_chat_message.c">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
@ -16084,15 +16210,6 @@
|
|||
<ClInclude Include="..\src\pc\network\discord\discord_network.h">
|
||||
<Filter>Header Files\src\pc\network\discord</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\menu\custom_menu_system.h">
|
||||
<Filter>Header Files\src\menu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\menu\custom_menu.h">
|
||||
<Filter>Header Files\src\menu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\game\chat.h">
|
||||
<Filter>Header Files\src\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\network\network_player.h">
|
||||
<Filter>Header Files\src\pc\network</Filter>
|
||||
</ClInclude>
|
||||
|
@ -16117,5 +16234,131 @@
|
|||
<ClInclude Include="..\src\pc\network\reservation_area.h">
|
||||
<Filter>Header Files\src\pc\network</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui.h">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_gfx.h">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_types.h">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_gbi.h">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_image.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_rect.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_text.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_base.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_root.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_interactable.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_flow_layout.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_button.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_main.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\utils\misc.h">
|
||||
<Filter>Source Files\src\pc\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_font.h">
|
||||
<Filter>Source Files\src\pc\djui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_debug.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_options.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_cursor.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_three_panel.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_sound.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_slider.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_camera.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_checkbox.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_display.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_selectionbox.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_controls.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_bind.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_menu.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host_message.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_inputbox.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_join.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_join_message.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\utils\string_builder.h">
|
||||
<Filter>Source Files\src\pc\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_popup.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_host_save.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_confirm.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_pause.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_panel_cheats.h">
|
||||
<Filter>Source Files\src\pc\djui\panel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_chat_box.h">
|
||||
<Filter>Source Files\src\pc\djui\component</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\djui\djui_chat_message.h">
|
||||
<Filter>Source Files\src\pc\djui\component\compound</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,2 +1,5 @@
|
|||
#!/bin/bash
|
||||
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' -ex 'run' -ex 'quit'
|
||||
#make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' -ex 'run' -ex 'quit'
|
||||
#make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_server.txt' -ex 'quit'
|
||||
#make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && ./build/us_pc/sm64.us.f3dex2e.exe --server 27015 --configfile sm64config_server.txt
|
||||
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && ./build/us_pc/sm64.us.f3dex2e.exe
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
#!/bin/bash
|
||||
winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here'
|
||||
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here'
|
||||
#make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_server.txt'
|
||||
|
|
18
developer/flags.sh
Normal file
18
developer/flags.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
function compiler() {
|
||||
make clean
|
||||
make RENDER_API=$1 WINDOW_API=$2 AUDIO_API=$3 CONTROLLER_API=$4
|
||||
mv ./build/us_pc/sm64.us.f3dex2e.exe ./build/us_pc/$5.exe
|
||||
}
|
||||
|
||||
compiler GL_LEGACY SDL1 SDL1 SDL1 legacy_1
|
||||
compiler GL SDL1 SDL1 SDL1 gl_1
|
||||
compiler D3D11 DXGI SDL1 SDL1 d3d11_1
|
||||
compiler D3D12 DXGI SDL1 SDL1 d3d12_1
|
||||
|
||||
compiler GL_LEGACY SDL2 SDL2 SDL2 legacy_2
|
||||
compiler GL SDL1 SDL2 SDL2 gl_2
|
||||
compiler D3D11 DXGI SDL2 SDL2 d3d11_2
|
||||
compiler D3D12 DXGI SDL2 SDL2 d3d12_2
|
|
@ -21,6 +21,7 @@
|
|||
#define _GBI_H_
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include "src/pc/djui/djui_gbi.h"
|
||||
|
||||
/*
|
||||
* To use the F3DEX ucodes, define F3DEX_GBI before include this file.
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
#ifndef TEXT_OPTIONS_STRINGS_H
|
||||
#define TEXT_OPTIONS_STRINGS_H
|
||||
|
||||
/* Extended options menu text */
|
||||
|
||||
// Menu title strings
|
||||
|
||||
#define TEXT_OPT_OPTIONS _("OPTIONS")
|
||||
#define TEXT_OPT_CAMERA _("CAMERA")
|
||||
#define TEXT_OPT_CONTROLS _("CONTROLS")
|
||||
#define TEXT_OPT_VIDEO _("DISPLAY")
|
||||
#define TEXT_OPT_AUDIO _("SOUND")
|
||||
#define TEXT_OPT_CHEATS _("CHEATS")
|
||||
|
||||
// Markers
|
||||
|
||||
#define TEXT_OPT_HIGHLIGHT _("O")
|
||||
#define TEXT_OPT_UNBOUND _("NONE")
|
||||
|
||||
// Language specific strings
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
||||
// TODO: Actually translate this to JP
|
||||
|
||||
// No . in JP
|
||||
|
||||
#define TEXT_OPT_PRESSKEY _("・・・")
|
||||
|
||||
// Option strings
|
||||
|
||||
#define TEXT_OPT_BUTTON1 _("R OPTIONS")
|
||||
#define TEXT_OPT_BUTTON2 _("R RETURN")
|
||||
#define TEXT_OPT_ENABLED _("ENABLED")
|
||||
#define TEXT_OPT_DISABLED _("DISABLED")
|
||||
#define TEXT_OPT_CAMX _("CAMERA X SENSITIVITY")
|
||||
#define TEXT_OPT_CAMY _("CAMERA Y SENSITIVITY")
|
||||
#define TEXT_OPT_INVERTX _("INVERT X AXIS")
|
||||
#define TEXT_OPT_INVERTY _("INVERT Y AXIS")
|
||||
#define TEXT_OPT_CAMC _("CAMERA CENTRE AGGRESSION")
|
||||
#define TEXT_OPT_CAMP _("CAMERA PAN LEVEL")
|
||||
#define TEXT_OPT_CAMD _("CAMERA DECELERATION")
|
||||
#define TEXT_OPT_CAMON _("FREE CAMERA")
|
||||
#define TEXT_OPT_ANALOGUE _("ANALOGUE CAMERA")
|
||||
#define TEXT_OPT_MOUSE _("MOUSE LOOK")
|
||||
#define TEXT_OPT_TEXFILTER _("TEXTURE FILTERING")
|
||||
#define TEXT_OPT_FSCREEN _("FULLSCREEN")
|
||||
#define TEXT_OPT_NEAREST _("NEAREST")
|
||||
#define TEXT_OPT_LINEAR _("LINEAR")
|
||||
#define TEXT_OPT_MVOLUME _("MASTER VOLUME")
|
||||
#define TEXT_OPT_MUSVOLUME _("MUSIC VOLUME")
|
||||
#define TEXT_OPT_SFXVOLUME _("SFX VOLUME")
|
||||
#define TEXT_OPT_ENVVOLUME _("ENV VOLUME")
|
||||
#define TEXT_OPT_VSYNC _("VERTICAL SYNC")
|
||||
#define TEXT_OPT_AUTO _("AUTO")
|
||||
#define TEXT_OPT_HUD _("HUD")
|
||||
#define TEXT_OPT_THREEPT _("THREE POINT")
|
||||
#define TEXT_OPT_APPLY _("APPLY")
|
||||
#define TEXT_OPT_RESETWND _("RESET WINDOW")
|
||||
|
||||
#define TEXT_BIND_A _("A BUTTON")
|
||||
#define TEXT_BIND_B _("B BUTTON")
|
||||
#define TEXT_BIND_START _("START BUTTON")
|
||||
#define TEXT_BIND_L _("L TRIGGER")
|
||||
#define TEXT_BIND_R _("R TRIGGER")
|
||||
#define TEXT_BIND_Z _("Z TRIGGER")
|
||||
#define TEXT_BIND_C_UP _("C-UP")
|
||||
#define TEXT_BIND_C_DOWN _("C-DOWN")
|
||||
#define TEXT_BIND_C_LEFT _("C-LEFT")
|
||||
#define TEXT_BIND_C_RIGHT _("C-RIGHT")
|
||||
#define TEXT_BIND_UP _("STICK UP")
|
||||
#define TEXT_BIND_DOWN _("STICK DOWN")
|
||||
#define TEXT_BIND_LEFT _("STICK LEFT")
|
||||
#define TEXT_BIND_RIGHT _("STICK RIGHT")
|
||||
#define TEXT_OPT_DEADZONE _("STICK DEADZONE")
|
||||
#define TEXT_OPT_RUMBLE _("RUMBLE STRENGTH")
|
||||
|
||||
#define TEXT_OPT_CHEAT1 _("ENABLE CHEATS")
|
||||
#define TEXT_OPT_CHEAT2 _("MOONJUMP (PRESS L)")
|
||||
#define TEXT_OPT_CHEAT3 _("INVINCIBLE MARIO")
|
||||
#define TEXT_OPT_CHEAT4 _("INFINITE LIVES")
|
||||
#define TEXT_OPT_CHEAT5 _("SUPER SPEED")
|
||||
#define TEXT_OPT_CHEAT6 _("SUPER RESPONSIVE CONTROLS")
|
||||
#define TEXT_OPT_CHEAT7 _("EXIT COURSE AT ANY TIME")
|
||||
#define TEXT_OPT_CHEAT8 _("HUGE MARIO")
|
||||
#define TEXT_OPT_CHEAT9 _("TINY MARIO")
|
||||
|
||||
#else // VERSION
|
||||
|
||||
// Markers
|
||||
|
||||
#define TEXT_OPT_PRESSKEY _("...")
|
||||
|
||||
// Option strings
|
||||
|
||||
#define TEXT_OPT_BUTTON1 _("[R] Options")
|
||||
#define TEXT_OPT_BUTTON2 _("[R] Return")
|
||||
#define TEXT_OPT_ENABLED _("Enabled")
|
||||
#define TEXT_OPT_DISABLED _("Disabled")
|
||||
#define TEXT_OPT_CAMX _("Camera X Sensitivity")
|
||||
#define TEXT_OPT_CAMY _("Camera Y Sensitivity")
|
||||
#define TEXT_OPT_INVERTX _("Invert X Axis")
|
||||
#define TEXT_OPT_INVERTY _("Invert Y Axis")
|
||||
#define TEXT_OPT_CAMC _("Camera Centre Aggression")
|
||||
#define TEXT_OPT_CAMP _("Camera Pan Level")
|
||||
#define TEXT_OPT_CAMD _("Camera Deceleration")
|
||||
#define TEXT_OPT_CAMON _("Free Camera")
|
||||
#define TEXT_OPT_ANALOGUE _("Analogue Camera")
|
||||
#define TEXT_OPT_MOUSE _("Mouse Look")
|
||||
#define TEXT_OPT_TEXFILTER _("Texture Filtering")
|
||||
#define TEXT_OPT_FSCREEN _("Fullscreen")
|
||||
#define TEXT_OPT_NEAREST _("Nearest")
|
||||
#define TEXT_OPT_LINEAR _("Linear")
|
||||
#define TEXT_OPT_MVOLUME _("Master Volume")
|
||||
#define TEXT_OPT_MUSVOLUME _("Music Volume")
|
||||
#define TEXT_OPT_SFXVOLUME _("Sfx Volume")
|
||||
#define TEXT_OPT_ENVVOLUME _("Env Volume")
|
||||
#define TEXT_OPT_VSYNC _("Vertical Sync")
|
||||
#define TEXT_OPT_AUTO _("Auto")
|
||||
#define TEXT_OPT_HUD _("HUD")
|
||||
#define TEXT_OPT_THREEPT _("Three-point")
|
||||
#define TEXT_OPT_APPLY _("Apply")
|
||||
#define TEXT_OPT_RESETWND _("Reset Window")
|
||||
|
||||
#define TEXT_BIND_A _("A Button")
|
||||
#define TEXT_BIND_B _("B Button")
|
||||
#define TEXT_BIND_START _("Start Button")
|
||||
#define TEXT_BIND_L _("L Trigger")
|
||||
#define TEXT_BIND_R _("R Trigger")
|
||||
#define TEXT_BIND_Z _("Z Trigger")
|
||||
#define TEXT_BIND_C_UP _("C-Up")
|
||||
#define TEXT_BIND_C_DOWN _("C-Down")
|
||||
#define TEXT_BIND_C_LEFT _("C-Left")
|
||||
#define TEXT_BIND_C_RIGHT _("C-Right")
|
||||
#define TEXT_BIND_UP _("Stick Up")
|
||||
#define TEXT_BIND_DOWN _("Stick Down")
|
||||
#define TEXT_BIND_LEFT _("Stick Left")
|
||||
#define TEXT_BIND_RIGHT _("Stick Right")
|
||||
#define TEXT_OPT_DEADZONE _("Stick Deadzone")
|
||||
#define TEXT_OPT_RUMBLE _("Rumble Strength")
|
||||
|
||||
#define TEXT_OPT_CHEAT1 _("Enable cheats")
|
||||
#define TEXT_OPT_CHEAT2 _("Moonjump (Press L)")
|
||||
#define TEXT_OPT_CHEAT3 _("Invincible Mario")
|
||||
#define TEXT_OPT_CHEAT4 _("Infinite lives")
|
||||
#define TEXT_OPT_CHEAT5 _("Super speed")
|
||||
#define TEXT_OPT_CHEAT6 _("Super responsive controls")
|
||||
#define TEXT_OPT_CHEAT7 _("Exit course at any time")
|
||||
#define TEXT_OPT_CHEAT8 _("Huge Mario")
|
||||
#define TEXT_OPT_CHEAT9 _("Tiny Mario")
|
||||
|
||||
#define TEXT_OPT_LUIGISND _("Luigi Sounds")
|
||||
|
||||
#endif // VERSION
|
||||
|
||||
#endif // TEXT_OPTIONS_STRINGS_H
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
#include "text_menu_strings.h"
|
||||
|
||||
#ifdef EXT_OPTIONS_MENU
|
||||
#include "text_options_strings.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Global Symbols
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#ifdef IMMEDIATELOAD
|
||||
#include "levels/menu/header.h"
|
||||
#include "levels/scripts.h"
|
||||
#else
|
||||
#include "levels/intro/header.h"
|
||||
#endif
|
||||
|
@ -12,15 +13,14 @@
|
|||
#include "make_const_nonconst.h"
|
||||
|
||||
const LevelScript level_script_entry[] = {
|
||||
INIT_LEVEL(),
|
||||
SLEEP(/*frames*/ 2),
|
||||
BLACKOUT(/*active*/ FALSE),
|
||||
SET_REG(/*value*/ 0),
|
||||
#ifdef IMMEDIATELOAD
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_main_menu_entry_1),
|
||||
JUMP(/*target*/ level_main_menu_entry_1),
|
||||
#else
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_1),
|
||||
JUMP(/*target*/ level_script_entry),
|
||||
#endif
|
||||
SET_REG(/*value*/ LEVEL_CASTLE_GROUNDS),
|
||||
JUMP(/*target*/ level_main_scripts_entry),
|
||||
|
||||
// old behavior (intro)
|
||||
//INIT_LEVEL(),
|
||||
//SLEEP(/*frames*/ 2),
|
||||
//BLACKOUT(/*active*/ FALSE),
|
||||
//SET_REG(/*value*/ 0),
|
||||
//EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_1),
|
||||
//JUMP(/*target*/ level_script_entry),
|
||||
};
|
||||
|
|
203
misc/n64-controller.svg
Normal file
203
misc/n64-controller.svg
Normal file
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg3123"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||
sodipodi:docname="n64-controller.svg">
|
||||
<defs
|
||||
id="defs3117">
|
||||
<pattern
|
||||
id="EMFhbasepattern"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
x="0"
|
||||
y="0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98422794"
|
||||
inkscape:cx="366.87429"
|
||||
inkscape:cy="482.24232"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1387"
|
||||
inkscape:window-x="1272"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3120">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="opacity:1;fill:#999999;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 159.02164,179.47574 c 4.22025,-1.90449 6.28702,-7.08236 7.60023,-19.04089 1.49599,-13.62284 0.24084,-34.30392 -1.99705,-47.32577 -0.20446,-1.18966 -0.20446,-1.18966 -0.81578,1.12198 -2.98495,11.28726 -13.59592,24.03716 -29.26288,26.03289 -0.81252,0.1035 -3.77405,0.3089 -3.60094,0.36847 0.53476,0.18404 2.20561,0.19552 2.97591,0.42882 2.64606,0.8014 6.14267,5.68736 7.86503,13.7161 4.7533,22.15739 9.09126,28.37366 17.23548,24.6984 z"
|
||||
id="path3879"
|
||||
sodipodi:nodetypes="sssssssss" />
|
||||
<path
|
||||
style="opacity:1;fill:#999999;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 32.861846,179.99085 c 5.00628,-1.30397 7.90516,-7.49824 11.63722,-24.86622 1.74689,-8.12955 4.040457,-12.01723 6.760691,-13.41247 1.175878,-0.60312 7.936069,-0.81879 7.254723,-1.00324 -0.347508,-0.0941 -7.714416,-0.40085 -8.622923,-0.51096 -13.947408,-1.69042 -24.46162,-12.73569 -27.45118,-23.32573 -0.3377,-1.19622 -0.67694,-2.2379 -0.75388,-2.31484 -0.0769,-0.0769 -0.4002,1.61825 -0.71836,3.76707 -2.15481,14.55314 -2.561091,37.51868 -0.08673,49.90929 1.46209,7.32157 4.05435,11.05512 8.25242,11.88568 1.64494,0.32544 2.03682,0.31192 3.728019,-0.12858 z"
|
||||
id="path3877"
|
||||
sodipodi:nodetypes="ssssssscsss" />
|
||||
<path
|
||||
style="opacity:1;fill:#666666;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 34.669026,91.826028 27.72169,-6.884126 1.818325,-6.455174 c 0,0 -24.936365,1.49832 -32.278785,8.638042 l 0.172599,5.12895 z"
|
||||
id="path3885"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#666666;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 151.88386,91.82585 -27.72169,-6.884125 -1.81832,-6.455175 c 0,0 24.93636,1.49832 32.27878,8.638043 l -0.1726,5.128949 z"
|
||||
id="path3885-3"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#b3b3b3;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 96.641306,210.13404 c 3.380854,-1.51705 6.454544,-6.19977 9.099164,-13.8624 2.68812,-7.78869 3.74969,-12.87923 6.70151,-32.13562 3.19508,-20.84329 4.75644,-22.60184 20.76255,-23.38477 21.1825,-1.03614 31.92894,-10.58468 31.38845,-27.88957 -0.43636,-13.97068 -8.39177,-24.158157 -21.67654,-27.75838 -3.41038,-0.924226 -14.1984,-2.461285 -17.10739,-2.719429 0,0 -2.8761,-5.127414 -4.06555,-6.958522 -0.83939,-1.771386 -15.39779,-6.171957 -28.038814,-6.171957 -11.83651,0 -27.511412,3.714691 -28.56411,6.145662 l -3.466375,6.79723 -7.516145,1.067272 c -19.91914,2.168581 -30.28071,10.635003 -32.25997,26.359574 -2.35782,18.73214 9.00373,30.06503 31.20249,31.12376 15.92894,0.7597 17.70816,2.72014 20.74733,22.86039 2.41524,16.0055 3.44807,21.53411 5.14373,27.53369 4.49992,15.9216 10.38385,22.25339 17.64967,18.99307 z"
|
||||
id="path3819"
|
||||
sodipodi:nodetypes="ssssssccscccsssss" />
|
||||
<ellipse
|
||||
style="opacity:1;fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4050"
|
||||
cx="93.281662"
|
||||
cy="149.23048"
|
||||
rx="15.356243"
|
||||
ry="15.389847" />
|
||||
<path
|
||||
style="opacity:1;fill:#1a1a1a;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 97.472306,157.25386 c 2.869884,-1.16156 2.592834,-0.84172 4.226594,-4.87944 1.31925,-3.26043 1.31925,-3.26043 -0.004,-6.51708 -1.62318,-3.99318 -1.25715,-3.62328 -5.222619,-5.27796 -3.293655,-1.37436 -3.293655,-1.37436 -6.766293,0.0702 -3.472637,1.44446 -3.472637,1.44446 -4.955151,4.95638 -1.482514,3.51191 -1.482514,3.51191 0,7.02456 1.482514,3.51266 1.482514,3.51266 4.934707,4.95635 3.352146,1.40187 3.480201,1.43206 4.418804,1.04148 0.531635,-0.22124 2.047475,-0.83971 3.368526,-1.37439 z"
|
||||
id="path3827" />
|
||||
<path
|
||||
style="fill:#e6e6e6;stroke-width:0.5;opacity:1;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 90.808556,156.06467 c -3.19709,-0.95777 -5.44345,-4.93001 -4.69055,-8.29433 1.46124,-6.52952 10.04671,-7.88776 13.29527,-2.10334 3.226694,5.74546 -2.20892,12.31367 -8.60472,10.39767 z"
|
||||
id="path3829" />
|
||||
<path
|
||||
style="opacity:1;fill:#cccccc;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 65.017829,75.401478 -3.343628,6.794806 c 0,0 6.248151,22.468596 5.826195,20.433286 -0.827522,-9.076031 -2.462914,-28.250425 -2.482567,-27.228092 z"
|
||||
id="path3881"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:0.264369"
|
||||
id="path3138"
|
||||
d="" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ff0000;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892"
|
||||
cx="93.14756"
|
||||
cy="119.22792"
|
||||
r="6.7085466" />
|
||||
<path
|
||||
id="rect3924"
|
||||
style="opacity:1;fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 123.98074,122.64871 1.54028,-1.51666 3.96468,3.71008 -1.77651,1.15706 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<circle
|
||||
style="opacity:1;fill:#00ff00;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0"
|
||||
cx="121.27341"
|
||||
cy="118.1497"
|
||||
r="5.2315807" />
|
||||
<circle
|
||||
style="opacity:1;fill:#0000ff;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0-9"
|
||||
cx="131.88081"
|
||||
cy="129.24153"
|
||||
r="5.2315807" />
|
||||
<rect
|
||||
style="opacity:0.645161;fill:#999999;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3948"
|
||||
width="29.365215"
|
||||
height="6.4055333"
|
||||
x="78.46347"
|
||||
y="84.188957"
|
||||
ry="3.1025405"
|
||||
rx="3.1738269" />
|
||||
<path
|
||||
style="opacity:1;fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 121.7435,75.425349 3.34362,6.794806 c 0,0 -6.24815,22.468595 -5.82619,20.433285 0.82752,-9.07603 2.46291,-28.250424 2.48257,-27.228091 z"
|
||||
id="path3881-7"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<ellipse
|
||||
style="opacity:1;fill:#999999;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
|
||||
id="path3982"
|
||||
cx="46.353729"
|
||||
cy="114.51382"
|
||||
rx="16.790049"
|
||||
ry="16.844238" />
|
||||
<path
|
||||
id="rect3984"
|
||||
style="opacity:1;fill:#333333;fill-opacity:1;stroke:#000000;stroke-width:3.77953;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 174.89453 390.91992 C 168.15317 390.91992 162.72656 393.73545 162.72656 397.23242 L 162.72656 419.83789 L 140.12109 419.83789 C 136.62412 419.83789 133.80859 425.26451 133.80859 432.00586 L 133.80859 432.81445 C 133.80859 439.55581 136.62412 444.98242 140.12109 444.98242 L 162.72656 444.98242 L 162.72656 467.58789 C 162.72656 471.08486 168.15317 473.90039 174.89453 473.90039 L 175.70312 473.90039 C 182.44449 473.90039 187.87109 471.08486 187.87109 467.58789 L 187.87109 444.98242 L 210.47656 444.98242 C 213.97353 444.98242 216.78906 439.55581 216.78906 432.81445 L 216.78906 432.00586 C 216.78906 425.26451 213.97353 419.83789 210.47656 419.83789 L 187.87109 419.83789 L 187.87109 397.23242 C 187.87109 393.73545 182.44449 390.91992 175.70312 390.91992 L 174.89453 390.91992 z "
|
||||
transform="scale(0.26458333)" />
|
||||
<circle
|
||||
style="opacity:1;fill:#999999;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4048"
|
||||
cy="109.39449"
|
||||
cx="143.2998"
|
||||
r="11.098639" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffff00;stroke:#000000;stroke-width:0.82998;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0-5"
|
||||
cx="134.47882"
|
||||
cy="108.94062"
|
||||
r="4.3421068" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffff00;stroke:#000000;stroke-width:0.829979;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0-5-2"
|
||||
cx="152.28836"
|
||||
cy="108.94061"
|
||||
r="4.3421068" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffff00;stroke:#000000;stroke-width:0.829979;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0-5-5"
|
||||
cx="142.94675"
|
||||
cy="100.47269"
|
||||
r="4.3421068" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffff00;stroke:#000000;stroke-width:0.829979;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3892-0-5-7"
|
||||
cx="143.04756"
|
||||
cy="118.31582"
|
||||
r="4.3421068" />
|
||||
<path
|
||||
style="opacity:1;fill:#e6e6e6;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 91.310516,154.60644 c -2.517257,-0.75411 -4.28595,-3.88169 -3.693146,-6.53061 1.15052,-5.14108 7.910368,-6.2105 10.468147,-1.65608 2.540573,4.52373 -1.739209,9.69528 -6.775001,8.18669 z"
|
||||
id="path3829-4" />
|
||||
<path
|
||||
style="opacity:1;fill:#e6e6e6;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 91.933837,152.79309 c -1.6719,-0.50086 -2.846622,-2.57812 -2.452896,-4.33746 0.764147,-3.41458 5.253869,-4.12486 6.952682,-1.09993 1.687385,3.00455 -1.15514,6.43936 -4.499786,5.43739 z"
|
||||
id="path3829-4-2" />
|
||||
<path
|
||||
style="opacity:1;fill:#e6e6e6;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 92.606431,150.83354 c -0.758421,-0.2272 -1.291308,-1.1695 -1.112703,-1.96759 0.346639,-1.54895 2.383302,-1.87115 3.153935,-0.49896 0.765443,1.36295 -0.524004,2.92108 -2.041232,2.46655 z"
|
||||
id="path3829-4-2-1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
|
@ -115,5 +115,5 @@ struct Character gCharacters[CT_MAX] = {
|
|||
|
||||
struct Character* get_character_sound(struct MarioState* m) {
|
||||
if (m == NULL || m->character == NULL) { return &gCharacters[CT_MARIO]; }
|
||||
return configLuigiSounds ? m->character : &gCharacters[CT_MARIO];
|
||||
return m->character;
|
||||
}
|
166
src/game/chat.c
166
src/game/chat.c
|
@ -1,166 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <ultra64.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "chat.h"
|
||||
#include "game_init.h"
|
||||
#include "ingame_menu.h"
|
||||
#include "mario_misc.h"
|
||||
#include "segment2.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "config.h"
|
||||
#include "PR/gbi.h"
|
||||
#include "pc/controller/controller_keyboard.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
#include "menu/file_select.h"
|
||||
|
||||
#define CHAT_DIALOG_MAX 96
|
||||
#define CHAT_MESSAGES_MAX 16
|
||||
#define CHAT_LIFE_MAX 400
|
||||
|
||||
struct ChatMessage {
|
||||
u8 dialog[CHAT_DIALOG_MAX];
|
||||
enum ChatMessageType type;
|
||||
u16 life;
|
||||
u8 color[3];
|
||||
};
|
||||
|
||||
static char inputMessage[CHAT_DIALOG_MAX] = { 0 };
|
||||
static struct ChatMessage message[CHAT_MESSAGES_MAX] = { 0 };
|
||||
static u8 onMessageIndex = 0;
|
||||
static u8 sInChatInput = FALSE;
|
||||
|
||||
#define CHAT_SCALE 0.5f
|
||||
#define CHAT_SPACE 10.0f
|
||||
#define CHATBOX_PAD_X 0.0215f
|
||||
#define CHATBOX_SCALE_X 0.00385f
|
||||
#define CHATBOX_SCALE_Y 0.115f
|
||||
#define CHATBOX_X 2.0f
|
||||
#define CHATBOX_Y 11.0f
|
||||
#define CHAT_X 4.0f
|
||||
#define CHAT_Y -18.0f
|
||||
|
||||
static void render_chat_message(struct ChatMessage* chatMessage, u8 index) {
|
||||
f32 textWidth = get_generic_dialog_width(chatMessage->dialog);
|
||||
f32 alphaScale = ((f32)chatMessage->life / (f32)(CHAT_LIFE_MAX / 20.0f));
|
||||
alphaScale *= alphaScale;
|
||||
if (alphaScale > 1) { alphaScale = 1; }
|
||||
|
||||
f32 chatBoxWidth = CHATBOX_SCALE_X * textWidth + CHATBOX_PAD_X;
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(CHATBOX_X), CHATBOX_Y + index * CHAT_SPACE, 0);
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, chatBoxWidth, CHATBOX_SCALE_Y, 1.0f);
|
||||
|
||||
u8 boxR, boxG, boxB;
|
||||
if (chatMessage->type == CMT_INPUT) {
|
||||
boxR = 150;
|
||||
boxG = 150;
|
||||
boxB = 255;
|
||||
} else {
|
||||
f32 rgbScale = (((f32)chatMessage->life - ((f32)CHAT_LIFE_MAX * 0.98f)) / ((f32)CHAT_LIFE_MAX * 0.02f));
|
||||
if (chatMessage->type == CMT_LOCAL || rgbScale < 0) { rgbScale = 0; }
|
||||
boxR = 255 * rgbScale;
|
||||
boxG = 255 * rgbScale;
|
||||
boxB = 255 * rgbScale;
|
||||
}
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, boxR, boxG, boxB, 110 * alphaScale);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
||||
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, CHAT_SCALE / chatBoxWidth, CHAT_SCALE / CHATBOX_SCALE_Y, 1.0f);
|
||||
|
||||
u8 textR, textG, textB;
|
||||
switch (chatMessage->type) {
|
||||
case CMT_LOCAL: textR = 200; textG = 200; textB = 255; break;
|
||||
case CMT_INPUT: textR = 0; textG = 0; textB = 0; break;
|
||||
case CMT_SYSTEM: textR = 255; textG = 255; textB = 190; break;
|
||||
default: textR = 255; textG = 255; textB = 255; break;
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, textR, textG, textB, 255 * alphaScale);
|
||||
print_generic_string(CHAT_X, CHAT_Y, chatMessage->dialog);
|
||||
|
||||
if (chatMessage->type == CMT_REMOTE || chatMessage->type == CMT_SYSTEM) {
|
||||
// if it's someone else's message, highlight the icon with their color
|
||||
u8 starR = chatMessage->color[0];
|
||||
u8 starG = chatMessage->color[1];
|
||||
u8 starB = chatMessage->color[2];
|
||||
gDPSetEnvColor(gDisplayListHead++, starR, starG, starB, 255 * alphaScale);
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, CHAT_X, CHAT_Y, 0.0f);
|
||||
render_generic_char(chatMessage->dialog[0]);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]) {
|
||||
u8 character = '?';
|
||||
switch (chatMessageType) {
|
||||
case CMT_INPUT:
|
||||
case CMT_LOCAL: character = 0xFD; break;
|
||||
case CMT_REMOTE: character = 0xFA; break;
|
||||
case CMT_SYSTEM: character = 0xF9; break;
|
||||
}
|
||||
struct ChatMessage* msg = &message[onMessageIndex];
|
||||
msg->dialog[0] = character;
|
||||
msg->dialog[1] = 0x9E;
|
||||
str_ascii_to_dialog(ascii, &msg->dialog[2], MIN(strlen(ascii), CHAT_DIALOG_MAX - 3));
|
||||
msg->life = (sSelectedFileNum != 0) ? CHAT_LIFE_MAX : CHAT_LIFE_MAX / 3;
|
||||
msg->type = chatMessageType;
|
||||
msg->color[0] = color[0];
|
||||
msg->color[1] = color[1];
|
||||
msg->color[2] = color[2];
|
||||
onMessageIndex = (onMessageIndex + 1) % CHAT_MESSAGES_MAX;
|
||||
play_sound((msg->type == CMT_LOCAL) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
|
||||
}
|
||||
|
||||
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
|
||||
const u8 defaultColor[3] = { 255, 255, 255 };
|
||||
chat_add_message_ext(ascii, chatMessageType, defaultColor);
|
||||
}
|
||||
|
||||
static void chat_stop_input(void) {
|
||||
sInChatInput = FALSE;
|
||||
keyboard_stop_text_input();
|
||||
}
|
||||
|
||||
static void chat_send_input(void) {
|
||||
sInChatInput = FALSE;
|
||||
keyboard_stop_text_input();
|
||||
if (strlen(gTextInput) == 0) { return; }
|
||||
chat_add_message(gTextInput, CMT_LOCAL);
|
||||
// our message has the same color as our shirt
|
||||
network_send_chat(gTextInput, get_player_color(gNetworkPlayerLocal->globalIndex, 0));
|
||||
}
|
||||
|
||||
void chat_start_input(void) {
|
||||
sInChatInput = TRUE;
|
||||
keyboard_start_text_input(TIM_SINGLE_LINE, CHAT_DIALOG_MAX - 3, chat_stop_input, chat_send_input);
|
||||
}
|
||||
|
||||
void render_chat(void) {
|
||||
u8 count = 0;
|
||||
if (sInChatInput) {
|
||||
struct ChatMessage inputMessage = { 0 };
|
||||
inputMessage.type = CMT_INPUT;
|
||||
inputMessage.dialog[0] = 0xFD;
|
||||
inputMessage.dialog[1] = 0x9E;
|
||||
str_ascii_to_dialog(gTextInput, &inputMessage.dialog[2], MIN(strlen(gTextInput), CHAT_DIALOG_MAX - 3));
|
||||
inputMessage.life = CHAT_LIFE_MAX;
|
||||
render_chat_message(&inputMessage, count++);
|
||||
}
|
||||
|
||||
u8 index = onMessageIndex;
|
||||
for (int i = 0; i < CHAT_MESSAGES_MAX; i++) {
|
||||
if (--index >= CHAT_MESSAGES_MAX) { index = CHAT_MESSAGES_MAX - 1; }
|
||||
if (message[index].life == 0) { continue; }
|
||||
render_chat_message(&message[index], count++);
|
||||
message[index].life--;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef CHAT_H
|
||||
#define CHAT_H
|
||||
|
||||
enum ChatMessageType {
|
||||
CMT_LOCAL,
|
||||
CMT_REMOTE,
|
||||
CMT_SYSTEM,
|
||||
CMT_INPUT,
|
||||
};
|
||||
|
||||
void render_chat(void);
|
||||
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType);
|
||||
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]);
|
||||
void chat_start_input(void);
|
||||
|
||||
#endif
|
|
@ -21,6 +21,7 @@
|
|||
#include "segment_symbols.h"
|
||||
#include "thread6.h"
|
||||
#include "rng_position.h"
|
||||
#include "src/pc/djui/djui.h"
|
||||
#include <prevent_bss_reordering.h>
|
||||
#ifdef BETTERCAMERA
|
||||
#include "bettercamera.h"
|
||||
|
@ -259,6 +260,9 @@ void end_master_display_list(void) {
|
|||
draw_profiler();
|
||||
}
|
||||
|
||||
extern void djui_render(void);
|
||||
djui_render();
|
||||
|
||||
gDPFullSync(gDisplayListHead++);
|
||||
gSPEndDisplayList(gDisplayListHead++);
|
||||
|
||||
|
@ -460,7 +464,7 @@ void read_controller_inputs(void) {
|
|||
// controller information.
|
||||
if (gControllerBits) {
|
||||
osRecvMesg(&gSIEventMesgQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||
osContGetReadData(&gControllerPads[0]);
|
||||
osContGetReadData(gInteractableOverridePad ? &gInteractablePad : &gControllerPads[0]);
|
||||
}
|
||||
run_demo_inputs();
|
||||
|
||||
|
|
|
@ -26,13 +26,10 @@
|
|||
#include "macros.h"
|
||||
#include "pc/cheats.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#ifdef BETTERCAMERA
|
||||
#include "bettercamera.h"
|
||||
#endif
|
||||
#ifdef EXT_OPTIONS_MENU
|
||||
#include "options_menu.h"
|
||||
#endif
|
||||
#include "chat.h"
|
||||
|
||||
u16 gDialogColorFadeTimer;
|
||||
s8 gLastDialogLineNum;
|
||||
|
@ -414,26 +411,31 @@ void render_multi_text_string(s16 *xPos, s16 *yPos, s8 multiTextID)
|
|||
}
|
||||
#endif
|
||||
|
||||
u8 str_ascii_char_to_dialog(char c) {
|
||||
switch (c) {
|
||||
case '\'': return 0x3E;
|
||||
case '.': return 0x3F;
|
||||
case ',': return DIALOG_CHAR_COMMA;
|
||||
case '-': return 0x9F;
|
||||
case '(': return 0xE1;
|
||||
case ')': return 0xE3;
|
||||
case '&': return 0xE5;
|
||||
case '!': return 0xF2;
|
||||
case '%': return 0xF3;
|
||||
case '?': return 0xF4;
|
||||
case '"': return 0xF6; // 0xF5 is opening quote
|
||||
case '~': return 0xF7;
|
||||
case '*': return 0xFB;
|
||||
case ' ': return DIALOG_CHAR_SPACE;
|
||||
case '\n': return DIALOG_CHAR_NEWLINE;
|
||||
case '\0': return DIALOG_CHAR_TERMINATOR;
|
||||
default: return ((u8)c < 0xF0) ? ASCII_TO_DIALOG(c) : c;
|
||||
}
|
||||
}
|
||||
|
||||
void str_ascii_to_dialog(const char* string, u8* dialog, u16 length) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
switch (string[i]) {
|
||||
case '\'': dialog[i] = 0x3E; break;
|
||||
case '.': dialog[i] = 0x3F; break;
|
||||
case ',': dialog[i] = DIALOG_CHAR_COMMA; break;
|
||||
case '-': dialog[i] = 0x9F; break;
|
||||
case '(': dialog[i] = 0xE1; break;
|
||||
case ')': dialog[i] = 0xE3; break;
|
||||
case '&': dialog[i] = 0xE5; break;
|
||||
case '!': dialog[i] = 0xF2; break;
|
||||
case '%': dialog[i] = 0xF3; break;
|
||||
case '?': dialog[i] = 0xF4; break;
|
||||
case '"': dialog[i] = 0xF6; break; // 0xF5 is opening quote
|
||||
case '~': dialog[i] = 0xF7; break;
|
||||
case '*': dialog[i] = 0xFB; break;
|
||||
case ' ': dialog[i] = DIALOG_CHAR_SPACE; break;
|
||||
case '\n': dialog[i] = DIALOG_CHAR_NEWLINE; break;
|
||||
default: dialog[i] = ((u8)string[i] < 0xF0) ? ASCII_TO_DIALOG(string[i]) : string[i];
|
||||
}
|
||||
dialog[i] = str_ascii_char_to_dialog(string[i]);
|
||||
}
|
||||
dialog[length] = DIALOG_CHAR_TERMINATOR;
|
||||
}
|
||||
|
@ -2731,9 +2733,6 @@ s16 render_pause_courses_and_castle(void) {
|
|||
|
||||
#ifdef VERSION_EU
|
||||
gInGameLanguage = eu_get_language();
|
||||
#endif
|
||||
#ifdef EXT_OPTIONS_MENU
|
||||
if (optmenu_open == 0) {
|
||||
#endif
|
||||
switch (gDialogBoxState) {
|
||||
case DIALOG_STATE_OPENING:
|
||||
|
@ -2811,14 +2810,10 @@ s16 render_pause_courses_and_castle(void) {
|
|||
if (gDialogTextAlpha < 250) {
|
||||
gDialogTextAlpha += 25;
|
||||
}
|
||||
#ifdef EXT_OPTIONS_MENU
|
||||
} else {
|
||||
shade_screen();
|
||||
optmenu_draw();
|
||||
}
|
||||
optmenu_check_buttons();
|
||||
optmenu_draw_prompt();
|
||||
#endif
|
||||
|
||||
if (gDjuiPanelPauseCreated) { shade_screen(); }
|
||||
if (gPlayer1Controller->buttonPressed & R_TRIG)
|
||||
djui_panel_pause_create(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3109,8 +3104,8 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 sp6e)
|
|||
s16 xOffset = get_str_x_pos_from_center(160, textContinueWithoutSaveArr[gInGameLanguage], 12.0f);
|
||||
#else
|
||||
u8 textSaveAndContinue[] = { TEXT_SAVE_AND_CONTINUE };
|
||||
u8 textSaveAndQuit[] = { TEXT_SAVE_AND_QUIT };
|
||||
u8 textSaveExitGame[] = { TEXT_SAVE_EXIT_GAME };
|
||||
//u8 textSaveAndQuit[] = { TEXT_SAVE_AND_QUIT };
|
||||
//u8 textSaveExitGame[] = { TEXT_SAVE_EXIT_GAME };
|
||||
u8 textContinueWithoutSave[] = { TEXT_CONTINUE_WITHOUT_SAVING };
|
||||
#endif
|
||||
|
||||
|
@ -3195,8 +3190,6 @@ s16 render_menus_and_dialogs() {
|
|||
|
||||
create_dl_ortho_matrix();
|
||||
|
||||
render_chat();
|
||||
|
||||
if (gMenuMode != -1) {
|
||||
switch (gMenuMode) {
|
||||
case 0:
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#define RENDER_COURSE_DONE_SCREEN 2
|
||||
|
||||
|
||||
#if !defined(VERSION_JP) && !defined(VERSION_SH)
|
||||
extern u8 gDialogCharWidths[];
|
||||
#endif
|
||||
|
||||
extern s8 gDialogCourseActNum;
|
||||
extern s8 gHudFlash;
|
||||
|
||||
|
@ -117,6 +121,7 @@ void create_dl_identity_matrix(void);
|
|||
void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z);
|
||||
void create_dl_ortho_matrix(void);
|
||||
void render_generic_char(u8 c);
|
||||
u8 str_ascii_char_to_dialog(char c);
|
||||
void str_ascii_to_dialog(const char* string, u8* dialog, u16 length);
|
||||
f32 get_generic_dialog_width(u8* dialog);
|
||||
f32 get_generic_ascii_string_width(const char* ascii);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "pc/cliopts.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/djui/djui.h"
|
||||
|
||||
#include "game/screen_transition.h"
|
||||
|
||||
|
@ -218,6 +219,13 @@ u32 pressed_pause(void) {
|
|||
}
|
||||
|
||||
void set_play_mode(s16 playMode) {
|
||||
if (sCurrPlayMode == PLAY_MODE_PAUSED && playMode != PLAY_MODE_PAUSED) {
|
||||
djui_base_set_visible(&gDjuiPauseOptions->base, false);
|
||||
}
|
||||
if (playMode == PLAY_MODE_PAUSED && sCurrPlayMode != PLAY_MODE_PAUSED) {
|
||||
djui_base_set_visible(&gDjuiPauseOptions->base, true);
|
||||
}
|
||||
|
||||
sCurrPlayMode = playMode;
|
||||
D_80339ECA = 0;
|
||||
}
|
||||
|
@ -1306,7 +1314,8 @@ s32 init_level(void) {
|
|||
set_mario_action(gMarioState, ACT_IDLE, 0);
|
||||
} else if (gDebugLevelSelect == 0) {
|
||||
if (gMarioState->action != ACT_UNINITIALIZED) {
|
||||
if (save_file_exists(gCurrSaveFileNum - 1)) {
|
||||
bool skipIntro = (gNetworkType == NT_NONE);
|
||||
if (save_file_exists(gCurrSaveFileNum - 1) || skipIntro) {
|
||||
set_mario_action(gMarioState, ACT_IDLE, 0);
|
||||
} else if (gCLIOpts.SkipIntro == 0 && configSkipIntro == 0 && gServerSettings.skipIntro == 0) {
|
||||
set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 0);
|
||||
|
@ -1377,6 +1386,7 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
|
|||
sWarpDest.type = WARP_TYPE_NOT_WARPING;
|
||||
sDelayedWarpOp = WARP_OP_NONE;
|
||||
gShouldNotPlayCastleMusic = !save_file_exists(gCurrSaveFileNum - 1) && gCLIOpts.SkipIntro == 0 && configSkipIntro == 0;
|
||||
if (gNetworkType == NT_NONE) { gShouldNotPlayCastleMusic = true; }
|
||||
|
||||
gCurrLevelNum = levelNum;
|
||||
gCurrCourseNum = COURSE_NONE;
|
||||
|
|
|
@ -1867,7 +1867,7 @@ s32 execute_mario_action(UNUSED struct Object *o) {
|
|||
s32 inLoop = TRUE;
|
||||
// hide inactive players
|
||||
struct NetworkPlayer* np = &gNetworkPlayers[gMarioState->playerIndex];
|
||||
if (np->type != NPT_LOCAL) {
|
||||
if (gMarioState->playerIndex != 0 && gNetworkPlayerLocal != NULL) {
|
||||
bool levelAreaMismatch =
|
||||
(np->currCourseNum != gNetworkPlayerLocal->currCourseNum
|
||||
|| np->currActNum != gNetworkPlayerLocal->currActNum
|
||||
|
|
|
@ -514,10 +514,13 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) {
|
|||
}
|
||||
|
||||
u8 is_player_active(struct MarioState* m) {
|
||||
if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; }
|
||||
|
||||
if (m->action == ACT_BUBBLED) { return FALSE; }
|
||||
struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex];
|
||||
if (np->type != NPT_LOCAL) {
|
||||
if (!np->connected) { return FALSE; }
|
||||
if (gNetworkPlayerLocal == NULL) { return FALSE; }
|
||||
bool levelAreaMismatch =
|
||||
(np->currCourseNum != gNetworkPlayerLocal->currCourseNum
|
||||
|| np->currActNum != gNetworkPlayerLocal->currActNum
|
||||
|
|
|
@ -1,634 +0,0 @@
|
|||
#ifdef EXT_OPTIONS_MENU
|
||||
|
||||
#include "sm64.h"
|
||||
#include "include/text_strings.h"
|
||||
#include "engine/math_util.h"
|
||||
#include "audio/external.h"
|
||||
#include "game/camera.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/print.h"
|
||||
#include "game/segment2.h"
|
||||
#include "game/save_file.h"
|
||||
#ifdef BETTERCAMERA
|
||||
#include "game/bettercamera.h"
|
||||
#endif
|
||||
#include "game/mario_misc.h"
|
||||
#include "game/game_init.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/options_menu.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "pc/cliopts.h"
|
||||
#include "pc/cheats.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/controller/controller_api.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../../include/libc/stdlib.h"
|
||||
|
||||
u8 optmenu_open = 0;
|
||||
|
||||
static u8 optmenu_binding = 0;
|
||||
static u8 optmenu_bind_idx = 0;
|
||||
|
||||
/* Keeps track of how many times the user has pressed L while in the options menu, so cheats can be unlocked */
|
||||
static s32 l_counter = 0;
|
||||
|
||||
// How to add stuff:
|
||||
// strings: add them to include/text_strings.h.in
|
||||
// and to menuStr[] / opts*Str[]
|
||||
// options: add them to the relevant options list
|
||||
// menus: add a new submenu definition and a new
|
||||
// option to the optsMain list
|
||||
|
||||
static const u8 toggleStr[][16] = {
|
||||
{ TEXT_OPT_DISABLED },
|
||||
{ TEXT_OPT_ENABLED },
|
||||
};
|
||||
|
||||
static const u8 menuStr[][32] = {
|
||||
{ TEXT_OPT_HIGHLIGHT },
|
||||
{ TEXT_OPT_BUTTON1 },
|
||||
{ TEXT_OPT_BUTTON2 },
|
||||
{ TEXT_OPT_OPTIONS },
|
||||
{ TEXT_OPT_CAMERA },
|
||||
{ TEXT_OPT_CONTROLS },
|
||||
{ TEXT_OPT_VIDEO },
|
||||
{ TEXT_OPT_AUDIO },
|
||||
{ TEXT_EXIT_GAME },
|
||||
{ TEXT_OPT_CHEATS },
|
||||
|
||||
};
|
||||
|
||||
static const u8 optsCameraStr[][32] = {
|
||||
{ TEXT_OPT_CAMX },
|
||||
{ TEXT_OPT_CAMY },
|
||||
{ TEXT_OPT_INVERTX },
|
||||
{ TEXT_OPT_INVERTY },
|
||||
{ TEXT_OPT_CAMC },
|
||||
{ TEXT_OPT_CAMP },
|
||||
{ TEXT_OPT_ANALOGUE },
|
||||
{ TEXT_OPT_MOUSE },
|
||||
{ TEXT_OPT_CAMD },
|
||||
{ TEXT_OPT_CAMON },
|
||||
};
|
||||
|
||||
static const u8 optsVideoStr[][32] = {
|
||||
{ TEXT_OPT_FSCREEN },
|
||||
{ TEXT_OPT_TEXFILTER },
|
||||
{ TEXT_OPT_NEAREST },
|
||||
{ TEXT_OPT_LINEAR },
|
||||
{ TEXT_OPT_RESETWND },
|
||||
{ TEXT_OPT_VSYNC },
|
||||
{ TEXT_OPT_AUTO },
|
||||
{ TEXT_OPT_HUD },
|
||||
{ TEXT_OPT_THREEPT },
|
||||
{ TEXT_OPT_APPLY },
|
||||
};
|
||||
|
||||
static const u8 optsAudioStr[][32] = {
|
||||
{ TEXT_OPT_MVOLUME },
|
||||
{ TEXT_OPT_MUSVOLUME },
|
||||
{ TEXT_OPT_SFXVOLUME },
|
||||
{ TEXT_OPT_ENVVOLUME },
|
||||
{ TEXT_OPT_LUIGISND },
|
||||
};
|
||||
|
||||
static const u8 optsCheatsStr[][64] = {
|
||||
{ TEXT_OPT_CHEAT1 },
|
||||
{ TEXT_OPT_CHEAT2 },
|
||||
{ TEXT_OPT_CHEAT3 },
|
||||
{ TEXT_OPT_CHEAT4 },
|
||||
{ TEXT_OPT_CHEAT5 },
|
||||
{ TEXT_OPT_CHEAT6 },
|
||||
{ TEXT_OPT_CHEAT7 },
|
||||
{ TEXT_OPT_CHEAT8 },
|
||||
{ TEXT_OPT_CHEAT9 },
|
||||
};
|
||||
|
||||
#define TEXT_BIND_CHAT 0x0C,0x2B,0x24,0x37,0xFF
|
||||
|
||||
static const u8 bindStr[][32] = {
|
||||
{ TEXT_OPT_UNBOUND },
|
||||
{ TEXT_OPT_PRESSKEY },
|
||||
{ TEXT_BIND_A },
|
||||
{ TEXT_BIND_B },
|
||||
{ TEXT_BIND_START },
|
||||
{ TEXT_BIND_L },
|
||||
{ TEXT_BIND_R },
|
||||
{ TEXT_BIND_Z },
|
||||
{ TEXT_BIND_C_UP },
|
||||
{ TEXT_BIND_C_DOWN },
|
||||
{ TEXT_BIND_C_LEFT },
|
||||
{ TEXT_BIND_C_RIGHT },
|
||||
{ TEXT_BIND_UP },
|
||||
{ TEXT_BIND_DOWN },
|
||||
{ TEXT_BIND_LEFT },
|
||||
{ TEXT_BIND_RIGHT },
|
||||
{ TEXT_BIND_CHAT },
|
||||
{ TEXT_OPT_DEADZONE },
|
||||
{ TEXT_OPT_RUMBLE }
|
||||
};
|
||||
|
||||
static const u8 *filterChoices[] = {
|
||||
optsVideoStr[2],
|
||||
optsVideoStr[3],
|
||||
optsVideoStr[8],
|
||||
};
|
||||
|
||||
static const u8 *vsyncChoices[] = {
|
||||
toggleStr[0],
|
||||
toggleStr[1],
|
||||
optsVideoStr[6],
|
||||
};
|
||||
|
||||
enum OptType {
|
||||
OPT_INVALID = 0,
|
||||
OPT_TOGGLE,
|
||||
OPT_CHOICE,
|
||||
OPT_SCROLL,
|
||||
OPT_SUBMENU,
|
||||
OPT_BIND,
|
||||
OPT_BUTTON,
|
||||
};
|
||||
|
||||
struct SubMenu;
|
||||
|
||||
struct Option {
|
||||
enum OptType type;
|
||||
const u8 *label;
|
||||
union {
|
||||
u32 *uval;
|
||||
bool *bval;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
const u8 **choices;
|
||||
u32 numChoices;
|
||||
};
|
||||
struct {
|
||||
u32 scrMin;
|
||||
u32 scrMax;
|
||||
u32 scrStep;
|
||||
};
|
||||
struct SubMenu *nextMenu;
|
||||
void (*actionFn)(struct Option *, s32);
|
||||
};
|
||||
};
|
||||
|
||||
struct SubMenu {
|
||||
struct SubMenu *prev; // this is set at runtime to avoid needless complication
|
||||
const u8 *label;
|
||||
struct Option *opts;
|
||||
s32 numOpts;
|
||||
s32 select;
|
||||
s32 scroll;
|
||||
};
|
||||
|
||||
/* helper macros */
|
||||
|
||||
#define DEF_OPT_TOGGLE(lbl, bv) \
|
||||
{ .type = OPT_TOGGLE, .label = lbl, .bval = bv }
|
||||
#define DEF_OPT_SCROLL(lbl, uv, min, max, st) \
|
||||
{ .type = OPT_SCROLL, .label = lbl, .uval = uv, .scrMin = min, .scrMax = max, .scrStep = st }
|
||||
#define DEF_OPT_CHOICE(lbl, uv, ch) \
|
||||
{ .type = OPT_CHOICE, .label = lbl, .uval = uv, .choices = ch, .numChoices = sizeof(ch) / sizeof(ch[0]) }
|
||||
#define DEF_OPT_SUBMENU(lbl, nm) \
|
||||
{ .type = OPT_SUBMENU, .label = lbl, .nextMenu = nm }
|
||||
#define DEF_OPT_BIND(lbl, uv) \
|
||||
{ .type = OPT_BIND, .label = lbl, .uval = uv }
|
||||
#define DEF_OPT_BUTTON(lbl, act) \
|
||||
{ .type = OPT_BUTTON, .label = lbl, .actionFn = act }
|
||||
#define DEF_SUBMENU(lbl, opt) \
|
||||
{ .label = lbl, .opts = opt, .numOpts = sizeof(opt) / sizeof(opt[0]) }
|
||||
|
||||
/* button action functions */
|
||||
|
||||
static void optmenu_act_exit(UNUSED struct Option *self, s32 arg) {
|
||||
if (!arg) game_exit(); // only exit on A press and not directions
|
||||
}
|
||||
|
||||
static void optvideo_reset_window(UNUSED struct Option *self, s32 arg) {
|
||||
if (!arg) {
|
||||
// Restrict reset to A press and not directions
|
||||
configWindow.reset = true;
|
||||
configWindow.settings_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void optvideo_apply(UNUSED struct Option *self, s32 arg) {
|
||||
if (!arg) configWindow.settings_changed = true;
|
||||
}
|
||||
|
||||
/* submenu option lists */
|
||||
|
||||
#ifdef BETTERCAMERA
|
||||
static struct Option optsCamera[] = {
|
||||
DEF_OPT_TOGGLE( optsCameraStr[9], &configEnableCamera ),
|
||||
DEF_OPT_TOGGLE( optsCameraStr[6], &configCameraAnalog ),
|
||||
DEF_OPT_TOGGLE( optsCameraStr[7], &configCameraMouse ),
|
||||
DEF_OPT_TOGGLE( optsCameraStr[2], &configCameraInvertX ),
|
||||
DEF_OPT_TOGGLE( optsCameraStr[3], &configCameraInvertY ),
|
||||
DEF_OPT_SCROLL( optsCameraStr[0], &configCameraXSens, 1, 100, 1 ),
|
||||
DEF_OPT_SCROLL( optsCameraStr[1], &configCameraYSens, 1, 100, 1 ),
|
||||
DEF_OPT_SCROLL( optsCameraStr[4], &configCameraAggr, 0, 100, 1 ),
|
||||
DEF_OPT_SCROLL( optsCameraStr[5], &configCameraPan, 0, 100, 1 ),
|
||||
DEF_OPT_SCROLL( optsCameraStr[8], &configCameraDegrade, 0, 100, 1 ),
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct Option optsControls[] = {
|
||||
DEF_OPT_BIND( bindStr[ 2], configKeyA ),
|
||||
DEF_OPT_BIND( bindStr[ 3], configKeyB ),
|
||||
DEF_OPT_BIND( bindStr[ 4], configKeyStart ),
|
||||
DEF_OPT_BIND( bindStr[ 5], configKeyL ),
|
||||
DEF_OPT_BIND( bindStr[ 6], configKeyR ),
|
||||
DEF_OPT_BIND( bindStr[ 7], configKeyZ ),
|
||||
DEF_OPT_BIND( bindStr[ 8], configKeyCUp ),
|
||||
DEF_OPT_BIND( bindStr[ 9], configKeyCDown ),
|
||||
DEF_OPT_BIND( bindStr[10], configKeyCLeft ),
|
||||
DEF_OPT_BIND( bindStr[11], configKeyCRight ),
|
||||
DEF_OPT_BIND( bindStr[12], configKeyStickUp ),
|
||||
DEF_OPT_BIND( bindStr[13], configKeyStickDown ),
|
||||
DEF_OPT_BIND( bindStr[14], configKeyStickLeft ),
|
||||
DEF_OPT_BIND( bindStr[15], configKeyStickRight ),
|
||||
DEF_OPT_BIND( bindStr[16], configKeyChat ),
|
||||
// max deadzone is 31000; this is less than the max range of ~32768, but this
|
||||
// way, the player can't accidentally lock themselves out of using the stick
|
||||
DEF_OPT_SCROLL( bindStr[17], &configStickDeadzone, 0, 100, 1 ),
|
||||
DEF_OPT_SCROLL( bindStr[18], &configRumbleStrength, 0, 100, 1)
|
||||
};
|
||||
|
||||
static struct Option optsVideo[] = {
|
||||
DEF_OPT_TOGGLE( optsVideoStr[0], &configWindow.fullscreen ),
|
||||
DEF_OPT_TOGGLE( optsVideoStr[5], &configWindow.vsync ),
|
||||
DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
|
||||
DEF_OPT_TOGGLE( optsVideoStr[7], &configHUD ),
|
||||
DEF_OPT_BUTTON( optsVideoStr[4], optvideo_reset_window ),
|
||||
DEF_OPT_BUTTON( optsVideoStr[9], optvideo_apply ),
|
||||
};
|
||||
|
||||
static struct Option optsAudio[] = {
|
||||
DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ),
|
||||
DEF_OPT_SCROLL( optsAudioStr[1], &configMusicVolume, 0, MAX_VOLUME, 1),
|
||||
DEF_OPT_SCROLL( optsAudioStr[2], &configSfxVolume, 0, MAX_VOLUME, 1),
|
||||
DEF_OPT_SCROLL( optsAudioStr[3], &configEnvVolume, 0, MAX_VOLUME, 1),
|
||||
DEF_OPT_TOGGLE( optsAudioStr[4], &configLuigiSounds ),
|
||||
};
|
||||
|
||||
static struct Option optsCheats[] = {
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[0], &Cheats.EnableCheats ),
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[1], &Cheats.MoonJump ),
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[2], &Cheats.GodMode ),
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[3], &Cheats.InfiniteLives ),
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed ),
|
||||
DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive ),
|
||||
|
||||
};
|
||||
|
||||
/* submenu definitions */
|
||||
|
||||
#ifdef BETTERCAMERA
|
||||
static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera );
|
||||
#endif
|
||||
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls );
|
||||
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo );
|
||||
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio );
|
||||
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[9], optsCheats );
|
||||
|
||||
/* main options menu definition */
|
||||
|
||||
static struct Option optsMain[] = {
|
||||
#ifdef BETTERCAMERA
|
||||
DEF_OPT_SUBMENU( menuStr[4], &menuCamera ),
|
||||
#endif
|
||||
DEF_OPT_SUBMENU( menuStr[5], &menuControls ),
|
||||
DEF_OPT_SUBMENU( menuStr[6], &menuVideo ),
|
||||
DEF_OPT_SUBMENU( menuStr[7], &menuAudio ),
|
||||
DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ),
|
||||
// NOTE: always keep cheats the last option here because of the half-assed way I toggle them
|
||||
DEF_OPT_SUBMENU( menuStr[9], &menuCheats )
|
||||
};
|
||||
|
||||
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain );
|
||||
|
||||
/* implementation */
|
||||
|
||||
static s32 optmenu_option_timer = 0;
|
||||
static u8 optmenu_hold_count = 0;
|
||||
|
||||
static struct SubMenu *currentMenu = &menuMain;
|
||||
|
||||
static inline s32 wrap_add(s32 a, const s32 b, const s32 min, const s32 max) {
|
||||
a += b;
|
||||
if (a < min) a = max - (min - a) + 1;
|
||||
else if (a > max) a = min + (a - max) - 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
static void uint_to_hex(u32 num, u8 *dst) {
|
||||
u8 places = 4;
|
||||
while (places--) {
|
||||
const u32 digit = num & 0xF;
|
||||
dst[places] = digit;
|
||||
num >>= 4;
|
||||
}
|
||||
dst[4] = DIALOG_CHAR_TERMINATOR;
|
||||
}
|
||||
|
||||
//Displays a box.
|
||||
static void optmenu_draw_box(s16 x1, s16 y1, s16 x2, s16 y2, u8 r, u8 g, u8 b) {
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||
gDPSetCycleType(gDisplayListHead++, G_CYC_FILL);
|
||||
gDPSetFillColor(gDisplayListHead++, GPACK_RGBA5551(r, g, b, 255));
|
||||
gDPFillRectangle(gDisplayListHead++, x1, y1, x2 - 1, y2 - 1);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
|
||||
}
|
||||
|
||||
static void optmenu_draw_text(s16 x, s16 y, const u8 *str, u8 col) {
|
||||
const u8 textX = get_str_x_pos_from_center(x, (u8*)str, 10.0f);
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
|
||||
print_generic_string(textX+1, y-1, str);
|
||||
if (col == 0) {
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
} else {
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 32, 32, 255);
|
||||
}
|
||||
print_generic_string(textX, y, str);
|
||||
}
|
||||
|
||||
static void optmenu_draw_opt(const struct Option *opt, s16 x, s16 y, u8 sel) {
|
||||
u8 buf[32] = { 0 };
|
||||
|
||||
if (opt->type == OPT_SUBMENU || opt->type == OPT_BUTTON)
|
||||
y -= 6;
|
||||
|
||||
optmenu_draw_text(x, y, opt->label, sel);
|
||||
|
||||
switch (opt->type) {
|
||||
case OPT_TOGGLE:
|
||||
optmenu_draw_text(x, y-13, toggleStr[(int)*opt->bval], sel);
|
||||
break;
|
||||
|
||||
case OPT_CHOICE:
|
||||
optmenu_draw_text(x, y-13, opt->choices[*opt->uval], sel);
|
||||
break;
|
||||
|
||||
case OPT_SCROLL:
|
||||
int_to_str(*opt->uval, buf);
|
||||
optmenu_draw_text(x, y-13, buf, sel);
|
||||
break;
|
||||
|
||||
case OPT_BIND:
|
||||
x = 112;
|
||||
for (u8 i = 0; i < MAX_BINDS; ++i, x += 48) {
|
||||
const u8 white = (sel && (optmenu_bind_idx == i));
|
||||
// TODO: button names
|
||||
if (opt->uval[i] == VK_INVALID) {
|
||||
if (optmenu_binding && white)
|
||||
optmenu_draw_text(x, y-13, bindStr[1], 1);
|
||||
else
|
||||
optmenu_draw_text(x, y-13, bindStr[0], white);
|
||||
} else {
|
||||
uint_to_hex(opt->uval[i], buf);
|
||||
optmenu_draw_text(x, y-13, buf, white);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
};
|
||||
}
|
||||
|
||||
static void optmenu_opt_change(struct Option *opt, s32 val) {
|
||||
switch (opt->type) {
|
||||
case OPT_TOGGLE:
|
||||
*opt->bval = !*opt->bval;
|
||||
break;
|
||||
|
||||
case OPT_CHOICE:
|
||||
*opt->uval = wrap_add(*opt->uval, val, 0, opt->numChoices - 1);
|
||||
break;
|
||||
|
||||
case OPT_SCROLL:
|
||||
*opt->uval = wrap_add(*opt->uval, opt->scrStep * val, opt->scrMin, opt->scrMax);
|
||||
break;
|
||||
|
||||
case OPT_SUBMENU:
|
||||
opt->nextMenu->prev = currentMenu;
|
||||
currentMenu = opt->nextMenu;
|
||||
break;
|
||||
|
||||
case OPT_BUTTON:
|
||||
if (opt->actionFn)
|
||||
opt->actionFn(opt, val);
|
||||
break;
|
||||
|
||||
case OPT_BIND:
|
||||
if (val == 0xFF) {
|
||||
// clear the bind
|
||||
opt->uval[optmenu_bind_idx] = VK_INVALID;
|
||||
} else if (val == 0) {
|
||||
opt->uval[optmenu_bind_idx] = VK_INVALID;
|
||||
optmenu_binding = 1;
|
||||
controller_get_raw_key(); // clear the last key, which is probably A
|
||||
} else {
|
||||
optmenu_bind_idx = wrap_add(optmenu_bind_idx, val, 0, MAX_BINDS - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline s16 get_hudstr_centered_x(const s16 sx, const u8 *str) {
|
||||
const u8 *chr = str;
|
||||
s16 len = 0;
|
||||
while (*chr != GLOBAR_CHAR_TERMINATOR) ++chr, ++len;
|
||||
return sx - len * 6; // stride is 12
|
||||
}
|
||||
|
||||
//Options menu
|
||||
void optmenu_draw(void) {
|
||||
s16 scroll;
|
||||
s16 scrollpos;
|
||||
|
||||
const s16 labelX = get_hudstr_centered_x(160, currentMenu->label);
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, labelX, 40, currentMenu->label);
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
||||
|
||||
if (currentMenu->numOpts > 4) {
|
||||
optmenu_draw_box(272, 90, 280, 208, 0x80, 0x80, 0x80);
|
||||
scrollpos = 54 * ((f32)currentMenu->scroll / (currentMenu->numOpts-4));
|
||||
optmenu_draw_box(272, 90+scrollpos, 280, 154+scrollpos, 0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 80, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
for (u8 i = 0; i < currentMenu->numOpts; i++) {
|
||||
scroll = 140 - 32 * i + currentMenu->scroll * 32;
|
||||
// FIXME: just start from the first visible option bruh
|
||||
if (scroll <= 140 && scroll > 32)
|
||||
optmenu_draw_opt(¤tMenu->opts[i], 160, scroll, (currentMenu->select == i));
|
||||
}
|
||||
|
||||
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, 80, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, 224, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
||||
}
|
||||
|
||||
//This has been separated for interesting reasons. Don't question it.
|
||||
void optmenu_draw_prompt(void) {
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
optmenu_draw_text(264, 212, menuStr[1 + optmenu_open], 0);
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
}
|
||||
|
||||
void optmenu_toggle(void) {
|
||||
if (optmenu_open == 0) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
|
||||
// HACK: hide the last option in main if cheats are disabled
|
||||
menuMain.numOpts = sizeof(optsMain) / sizeof(optsMain[0]);
|
||||
if (!Cheats.EnableCheats) {
|
||||
menuMain.numOpts--;
|
||||
if (menuMain.select >= menuMain.numOpts) {
|
||||
menuMain.select = 0; // don't bother
|
||||
menuMain.scroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
currentMenu = &menuMain;
|
||||
optmenu_open = 1;
|
||||
|
||||
/* Resets l_counter to 0 every time the options menu is open */
|
||||
l_counter = 0;
|
||||
} else {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gDefaultSoundArgs);
|
||||
#endif
|
||||
optmenu_open = 0;
|
||||
#ifdef BETTERCAMERA
|
||||
newcam_init_settings(); // load bettercam settings from config vars
|
||||
#endif
|
||||
controller_reconfigure(); // rebind using new config values
|
||||
configfile_save(configfile_name());
|
||||
}
|
||||
}
|
||||
|
||||
void optmenu_check_buttons(void) {
|
||||
if (optmenu_binding) {
|
||||
u32 key = controller_get_raw_key();
|
||||
if (key != VK_INVALID) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
currentMenu->opts[currentMenu->select].uval[optmenu_bind_idx] = key;
|
||||
optmenu_binding = 0;
|
||||
optmenu_option_timer = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (gPlayer1Controller->buttonPressed & R_TRIG)
|
||||
optmenu_toggle();
|
||||
|
||||
/* Enables cheats if the user press the L trigger 3 times while in the options menu. Also plays a sound. */
|
||||
|
||||
if ((gPlayer1Controller->buttonPressed & L_TRIG) && !Cheats.EnableCheats) {
|
||||
if (l_counter == 2) {
|
||||
Cheats.EnableCheats = true;
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
||||
l_counter = 0;
|
||||
} else {
|
||||
l_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!optmenu_open) return;
|
||||
|
||||
u8 allowInput = 0;
|
||||
|
||||
optmenu_option_timer--;
|
||||
if (optmenu_option_timer <= 0) {
|
||||
if (optmenu_hold_count == 0) {
|
||||
optmenu_hold_count++;
|
||||
optmenu_option_timer = 10;
|
||||
} else {
|
||||
optmenu_option_timer = 3;
|
||||
}
|
||||
allowInput = 1;
|
||||
}
|
||||
|
||||
if (ABS(gPlayer1Controller->stickY) > 60) {
|
||||
if (allowInput) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
|
||||
if (gPlayer1Controller->stickY >= 60) {
|
||||
currentMenu->select--;
|
||||
if (currentMenu->select < 0)
|
||||
currentMenu->select = currentMenu->numOpts-1;
|
||||
} else {
|
||||
currentMenu->select++;
|
||||
if (currentMenu->select >= currentMenu->numOpts)
|
||||
currentMenu->select = 0;
|
||||
}
|
||||
|
||||
if (currentMenu->select < currentMenu->scroll)
|
||||
currentMenu->scroll = currentMenu->select;
|
||||
else if (currentMenu->select > currentMenu->scroll + 3)
|
||||
currentMenu->scroll = currentMenu->select - 3;
|
||||
}
|
||||
} else if (ABS(gPlayer1Controller->stickX) > 60) {
|
||||
if (allowInput) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
if (gPlayer1Controller->stickX >= 60)
|
||||
optmenu_opt_change(¤tMenu->opts[currentMenu->select], 1);
|
||||
else
|
||||
optmenu_opt_change(¤tMenu->opts[currentMenu->select], -1);
|
||||
}
|
||||
} else if (gPlayer1Controller->buttonPressed & A_BUTTON) {
|
||||
if (allowInput) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
optmenu_opt_change(¤tMenu->opts[currentMenu->select], 0);
|
||||
}
|
||||
} else if (gPlayer1Controller->buttonPressed & B_BUTTON) {
|
||||
if (allowInput) {
|
||||
if (currentMenu->prev) {
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
#endif
|
||||
currentMenu = currentMenu->prev;
|
||||
} else {
|
||||
// can't go back, exit the menu altogether
|
||||
optmenu_toggle();
|
||||
}
|
||||
}
|
||||
} else if (gPlayer1Controller->buttonPressed & Z_TRIG) {
|
||||
// HACK: clear binds with Z
|
||||
if (allowInput && currentMenu->opts[currentMenu->select].type == OPT_BIND)
|
||||
optmenu_opt_change(¤tMenu->opts[currentMenu->select], 0xFF);
|
||||
} else if (gPlayer1Controller->buttonPressed & START_BUTTON) {
|
||||
if (allowInput) optmenu_toggle();
|
||||
} else {
|
||||
optmenu_hold_count = 0;
|
||||
optmenu_option_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EXT_OPTIONS_MENU
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef OPTIONS_MENU_H
|
||||
#define OPTIONS_MENU_H
|
||||
|
||||
void optmenu_toggle(void);
|
||||
void optmenu_draw(void);
|
||||
void optmenu_draw_prompt(void);
|
||||
void optmenu_check_buttons(void);
|
||||
|
||||
extern u8 optmenu_open;
|
||||
|
||||
#endif // OPTIONS_MENU_H
|
|
@ -199,7 +199,7 @@ void unload_object(struct Object *obj) {
|
|||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_CYLBOARD;
|
||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
|
||||
|
||||
if (obj->oSyncID != 0) {
|
||||
if (obj->oSyncID != 0 && gNetworkType != NT_NONE) {
|
||||
if (gSyncObjects[obj->oSyncID].syncDeathEvent) {
|
||||
network_send_object(obj);
|
||||
} else {
|
||||
|
|
|
@ -227,7 +227,7 @@ static Gfx gd_texture1_dummy_aligner1[] = { // @ 801A8728
|
|||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
ALIGNED8 static u8 gd_texture_hand_open[] = {
|
||||
ALIGNED8 u8 gd_texture_hand_open[] = {
|
||||
#include "textures/intro_raw/hand_open.rgba16.inc.c"
|
||||
};
|
||||
|
||||
|
@ -235,7 +235,7 @@ static Gfx gd_texture2_dummy_aligner1[] = {
|
|||
gsSPEndDisplayList()
|
||||
};
|
||||
|
||||
ALIGNED8 static u8 gd_texture_hand_closed[] = {
|
||||
ALIGNED8 u8 gd_texture_hand_closed[] = {
|
||||
#include "textures/intro_raw/hand_closed.rgba16.inc.c"
|
||||
};
|
||||
|
||||
|
|
|
@ -1,326 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "custom_menu.h"
|
||||
#include "custom_menu_system.h"
|
||||
#include "pc/network/network.h"
|
||||
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/controller/controller_keyboard.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/game_init.h"
|
||||
#include "game/segment2.h"
|
||||
#include "object_fields.h"
|
||||
#include "model_ids.h"
|
||||
#include "behavior_data.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
#include "config.h"
|
||||
#include "pc/network/version.h"
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
#include "pc/network/discord/discord.h"
|
||||
#endif
|
||||
|
||||
#define MAIN_MENU_HEADER_TEXT "SM64 COOP"
|
||||
|
||||
char sConnectionJoinError[128] = { 0 };
|
||||
char gConnectionText[128] = { 0 };
|
||||
struct CustomMenu* sConnectMenu = NULL;
|
||||
|
||||
u8 gOpenConnectMenu = FALSE;
|
||||
s8 sGotoGame = 0;
|
||||
|
||||
static void menu_main_draw_strings(void) {
|
||||
char* subtitle = "Still in development.";
|
||||
s16 subtitleX = (SCREEN_WIDTH - get_generic_ascii_string_width(subtitle)) / 2;
|
||||
print_generic_ascii_string(subtitleX, 150, subtitle);
|
||||
|
||||
char* versionString = get_version();
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 120);
|
||||
print_generic_ascii_string(25, 25, versionString);
|
||||
|
||||
}
|
||||
|
||||
static void host_menu_draw_strings(void) {
|
||||
#ifdef DISCORD_SDK
|
||||
#define HOST_MENU_MAX_ITEMS 6
|
||||
#else
|
||||
#define HOST_MENU_MAX_ITEMS 5
|
||||
#endif
|
||||
|
||||
// set up server setting strings
|
||||
char* buttonText[HOST_MENU_MAX_ITEMS];
|
||||
|
||||
switch (configPlayerInteraction) {
|
||||
case 0: buttonText[0] = "Non-solid players."; break;
|
||||
case 1: buttonText[0] = "Solid players."; break;
|
||||
case 2: buttonText[0] = "Friendly fire."; break;
|
||||
default: buttonText[0] = "UNKNOWN"; break;
|
||||
}
|
||||
if (configPlayerKnockbackStrength <= 20) {
|
||||
buttonText[1] = "Weak knockback.";
|
||||
} else if (configPlayerKnockbackStrength <= 40) {
|
||||
buttonText[1] = "Normal knockback.";
|
||||
} else {
|
||||
buttonText[1] = "Too much knockback.";
|
||||
}
|
||||
|
||||
buttonText[2] = configStayInLevelAfterStar ? "Stay in level after star." : "Leave level after star.";
|
||||
|
||||
buttonText[3] = configSkipIntro ? "Skip intro cutscene." : "Play intro cutscene.";
|
||||
|
||||
buttonText[4] = configShareLives ? "Share lives." : "Lives are not shared.";
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
buttonText[5] = (configNetworkSystem == 0) ? "Host through Discord." : "Host direct connection.";
|
||||
#endif
|
||||
|
||||
// display server setting strings
|
||||
for (int i = 0; i < HOST_MENU_MAX_ITEMS; i++) {
|
||||
print_generic_ascii_string(95, 173 + -29 * i, buttonText[i]);
|
||||
}
|
||||
|
||||
// display direct connection warning
|
||||
if (configNetworkSystem != 0) {
|
||||
f32 red = (f32)fabs(sin(gGlobalTimer / 20.0f));
|
||||
gDPSetEnvColor(gDisplayListHead++, 222, 222 * red, 222 * red, gMenuStringAlpha);
|
||||
char warning[128];
|
||||
snprintf(warning, 127, "Port forward '%d' in network router settings or use Hamachi.", configHostPort);
|
||||
print_generic_ascii_string(0, 5, warning);
|
||||
}
|
||||
#ifdef DISCORD_SDK
|
||||
else if ((configNetworkSystem == 0) && gDiscordFailed) {
|
||||
f32 red = (f32)fabs(sin(gGlobalTimer / 20.0f));
|
||||
gDPSetEnvColor(gDisplayListHead++, 222, 222 * red, 222 * red, gMenuStringAlpha);
|
||||
char warning[128];
|
||||
snprintf(warning, 127, "Discord failed to initialize.");
|
||||
print_generic_ascii_string(0, 15, warning);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void host_menu_do_host(void) {
|
||||
#ifndef DISCORD_SDK
|
||||
configNetworkSystem = 1;
|
||||
#endif
|
||||
if (configNetworkSystem == 0) {
|
||||
network_set_system(NS_DISCORD);
|
||||
} else {
|
||||
network_set_system(NS_SOCKET);
|
||||
}
|
||||
custom_menu_close_system();
|
||||
}
|
||||
|
||||
static void host_menu_setting_network_system(void) {
|
||||
#ifdef DISCORD_SDK
|
||||
configNetworkSystem = (configNetworkSystem == 0) ? 1 : 0;
|
||||
#else
|
||||
configNetworkSystem = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void host_menu_setting_interaction(void) {
|
||||
switch (configPlayerInteraction) {
|
||||
case 0: configPlayerInteraction = 1; break;
|
||||
case 1: configPlayerInteraction = 2; break;
|
||||
default: configPlayerInteraction = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
static void host_menu_setting_knockback(void) {
|
||||
if (configPlayerKnockbackStrength <= 20) {
|
||||
configPlayerKnockbackStrength = 25;
|
||||
} else if (configPlayerKnockbackStrength <= 40) {
|
||||
configPlayerKnockbackStrength = 75;
|
||||
} else {
|
||||
configPlayerKnockbackStrength = 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void host_menu_setting_stay_in_level(void) {
|
||||
configStayInLevelAfterStar = (configStayInLevelAfterStar == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void host_menu_setting_skip_intro(void) {
|
||||
configSkipIntro = (configSkipIntro == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void host_menu_setting_share_lives(void) {
|
||||
configShareLives = (configShareLives == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
static void join_menu_draw_strings(void) {
|
||||
print_generic_ascii_string(30, 155, "Accept a Discord game invite in order to join.");
|
||||
print_generic_ascii_string(30, 130, "For direct connections, click connect to type in an IP.");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void connect_menu_draw_strings(void) {
|
||||
if (gNetworkType == NT_CLIENT) {
|
||||
f32 alpha = (f32)fabs(sin(gGlobalTimer / 20.0f));
|
||||
gDPSetEnvColor(gDisplayListHead++, 222, 222, 222, gMenuStringAlpha * alpha);
|
||||
print_generic_ascii_string(130, 130, "Connecting...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*sConnectionJoinError) {
|
||||
f32 red = (f32)fabs(sin(gGlobalTimer / 20.0f));
|
||||
gDPSetEnvColor(gDisplayListHead++, 222, 222 * red, 222 * red, gMenuStringAlpha);
|
||||
f32 messageX = (SCREEN_WIDTH - get_generic_ascii_string_width(sConnectionJoinError)) / 2.0;
|
||||
f32 messageY = (SCREEN_HEIGHT + get_generic_ascii_string_height(sConnectionJoinError)) / 2.0;
|
||||
print_generic_ascii_string(messageX, messageY, sConnectionJoinError);
|
||||
return;
|
||||
}
|
||||
|
||||
print_generic_ascii_string(30, 175, "Type in or paste the host's IP.");
|
||||
print_generic_ascii_string(30, 160, "Note - the host must forward a port on their router.");
|
||||
|
||||
if (keyboard_in_text_input()) {
|
||||
if (strlen(gTextInput) >= 7) {
|
||||
print_generic_ascii_string(30, 100, "Press (ENTER) to connect.");
|
||||
} else {
|
||||
print_generic_ascii_string(30, 100, "Press (ESC) to cancel.");
|
||||
}
|
||||
}
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, 130, 222, 140, gMenuStringAlpha);
|
||||
print_generic_ascii_string(30, 130, gTextInput);
|
||||
}
|
||||
|
||||
static void connect_menu_on_connection_attempt(void) {
|
||||
play_sound(SOUND_GENERAL_COIN, gDefaultSoundArgs);
|
||||
|
||||
keyboard_stop_text_input();
|
||||
if (gNetworkType != NT_NONE) { return; }
|
||||
|
||||
char delims[2] = " ";
|
||||
|
||||
// copy input
|
||||
char buffer[MAX_TEXT_INPUT] = { 0 };
|
||||
strncpy(buffer, gTextInput, MAX_TEXT_INPUT);
|
||||
char* text = buffer;
|
||||
|
||||
// trim whitespace
|
||||
while (*text == ' ') { text++; }
|
||||
|
||||
// grab IP
|
||||
char* ip = strtok(text, delims);
|
||||
if (ip == NULL) { custom_menu_close(); return; }
|
||||
strncpy(configJoinIp, ip, MAX_CONFIG_STRING);
|
||||
|
||||
// grab port
|
||||
char* port = strtok(NULL, delims);
|
||||
if (port != NULL) {
|
||||
unsigned int intPort = atoi(port);
|
||||
if (intPort == 0 || intPort > 65535) { configJoinPort = DEFAULT_PORT; custom_menu_close(); return; }
|
||||
configJoinPort = intPort;
|
||||
}
|
||||
else {
|
||||
configJoinPort = DEFAULT_PORT;
|
||||
}
|
||||
|
||||
network_set_system(NS_SOCKET);
|
||||
network_init(NT_CLIENT);
|
||||
|
||||
}
|
||||
|
||||
static void connect_menu_on_click(void) {
|
||||
sConnectionJoinError[0] = '\0';
|
||||
|
||||
keyboard_start_text_input(TIM_IP, MAX_TEXT_INPUT, custom_menu_close, connect_menu_on_connection_attempt);
|
||||
|
||||
// fill in our last attempt
|
||||
if (configJoinPort == 0 || configJoinPort > 65535) { configJoinPort = DEFAULT_PORT; }
|
||||
|
||||
// only print custom port
|
||||
if (configJoinPort == DEFAULT_PORT) {
|
||||
sprintf(gTextInput, "%s", configJoinIp);
|
||||
}
|
||||
else {
|
||||
sprintf(gTextInput, "%s %d", configJoinIp, configJoinPort);
|
||||
}
|
||||
}
|
||||
|
||||
static void connect_menu_on_close(void) {
|
||||
keyboard_stop_text_input();
|
||||
network_shutdown();
|
||||
}
|
||||
|
||||
void custom_menu_init(struct CustomMenu* head) {
|
||||
|
||||
// set the header text
|
||||
head->me->label = calloc(strlen(MAIN_MENU_HEADER_TEXT) + 1, sizeof(char));
|
||||
strcpy(head->me->label, MAIN_MENU_HEADER_TEXT);
|
||||
|
||||
// set main menu settings
|
||||
head->headerY = 55;
|
||||
head->draw_strings = menu_main_draw_strings;
|
||||
|
||||
// create sub menus and buttons
|
||||
struct CustomMenu* hostMenu = custom_menu_create(head, "HOST", -266, 0, gButtonScale.large);
|
||||
hostMenu->headerY = 30;
|
||||
hostMenu->draw_strings = host_menu_draw_strings;
|
||||
custom_menu_create_button(hostMenu, "CANCEL", 700, -196 + (210 * 3), gButtonScale.large, SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close);
|
||||
custom_menu_create_button(hostMenu, "HOST", 700, -220, gButtonScale.large, SOUND_MENU_CAMERA_ZOOM_IN, host_menu_do_host);
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * 3), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_interaction);
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * 2), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_knockback);
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * 1), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_stay_in_level);
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * 0), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_skip_intro);
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * -1), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_share_lives);
|
||||
#ifdef DISCORD_SDK
|
||||
custom_menu_create_button(hostMenu, "", -700, -180 + (210 * -2), gButtonScale.medium, SOUND_ACTION_BONK, host_menu_setting_network_system);
|
||||
#endif
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
struct CustomMenu* joinMenu = custom_menu_create(head, "JOIN", 266, 0, gButtonScale.large);
|
||||
custom_menu_create_button(joinMenu, "CANCEL", -266, -320, gButtonScale.large, SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close);
|
||||
joinMenu->draw_strings = join_menu_draw_strings;
|
||||
struct CustomMenu* connectMenu = custom_menu_create(joinMenu, "CONNECT", 266, -320, gButtonScale.large);
|
||||
#else
|
||||
struct CustomMenu* connectMenu = custom_menu_create(head, "CONNECT", 266, 0, gButtonScale.large);
|
||||
#endif
|
||||
connectMenu->me->on_click = connect_menu_on_click;
|
||||
connectMenu->on_close = connect_menu_on_close;
|
||||
connectMenu->draw_strings = connect_menu_draw_strings;
|
||||
custom_menu_create_button(connectMenu, "CANCEL", 0, -400, gButtonScale.large, SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close);
|
||||
sConnectMenu = connectMenu;
|
||||
}
|
||||
|
||||
void custom_menu_loop(void) {
|
||||
// we've received an event that makes us exit the menus
|
||||
if (sGotoGame) {
|
||||
sSelectedFileNum = sGotoGame;
|
||||
custom_menu_close_system();
|
||||
}
|
||||
|
||||
// force-start the load when command-line server hosting
|
||||
if (gNetworkType == NT_SERVER && sSelectedFileNum == 0) {
|
||||
sSelectedFileNum = 1;
|
||||
}
|
||||
|
||||
if (gOpenConnectMenu && sConnectMenu != NULL) {
|
||||
gOpenConnectMenu = FALSE;
|
||||
custom_menu_open(sConnectMenu);
|
||||
}
|
||||
}
|
||||
|
||||
void custom_menu_on_load_save_file(s8 saveFileNum) {
|
||||
if (gNetworkType != NT_CLIENT && saveFileNum != 0) {
|
||||
configHostSaveSlot = saveFileNum;
|
||||
network_init(NT_SERVER);
|
||||
}
|
||||
}
|
||||
|
||||
void custom_menu_goto_game(s16 saveFileNum) {
|
||||
sGotoGame = saveFileNum;
|
||||
}
|
||||
|
||||
void custom_menu_connection_error(char* message) {
|
||||
play_sound(SOUND_MARIO_MAMA_MIA, gDefaultSoundArgs);
|
||||
strcpy(sConnectionJoinError, message);
|
||||
network_shutdown();
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef CUSTOM_MENU_H
|
||||
#define CUSTOM_MENU_H
|
||||
#include "custom_menu_system.h"
|
||||
|
||||
extern u8 gOpenConnectMenu;
|
||||
|
||||
void custom_menu_init(struct CustomMenu* head);
|
||||
void custom_menu_loop(void);
|
||||
void custom_menu_on_load_save_file(s8 saveFileNum);
|
||||
void custom_menu_goto_game(s16 saveFileNum);
|
||||
void custom_menu_connection_error(char* message);
|
||||
|
||||
#endif // CUSTOM_MENU_H
|
|
@ -1,409 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "custom_menu_system.h"
|
||||
#include "custom_menu.h"
|
||||
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/object_helpers.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/game_init.h"
|
||||
#include "game/segment2.h"
|
||||
#include "object_fields.h"
|
||||
#include "model_ids.h"
|
||||
#include "behavior_data.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "config.h"
|
||||
|
||||
static struct CustomMenu* sHead = NULL;
|
||||
static struct CustomMenu* sCurrentMenu = NULL;
|
||||
static struct CustomMenu* sLastMenu = NULL;
|
||||
struct CustomMenuButtonScale gButtonScale = {
|
||||
.small = 0.08111111f,
|
||||
.medium = 0.09511111f,
|
||||
.large = 0.11111111f,
|
||||
};
|
||||
|
||||
u8 gMenuStringAlpha = 255;
|
||||
|
||||
struct ErrorDialog {
|
||||
u8* dialog;
|
||||
struct ErrorDialog* next;
|
||||
};
|
||||
static struct ErrorDialog* sErrorDialog = NULL;
|
||||
|
||||
struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, f32 scale, s32 clickSound, void (*on_click)(void)) {
|
||||
struct CustomMenuButton* button = calloc(1, sizeof(struct CustomMenuButton));
|
||||
if (parent->buttons == NULL) {
|
||||
parent->buttons = button;
|
||||
} else {
|
||||
struct CustomMenuButton* parentButton = parent->buttons;
|
||||
while (parentButton->next != NULL) { parentButton = parentButton->next; }
|
||||
parentButton->next = button;
|
||||
}
|
||||
button->label = calloc(strlen(label), sizeof(char) + 1);
|
||||
strcpy(button->label, label);
|
||||
|
||||
button->on_click = on_click;
|
||||
button->clickSound = clickSound;
|
||||
|
||||
struct Object* obj = spawn_object_rel_with_rot(parent->me->object, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, x * -1, y, -1, 0, 0x8000, 0);
|
||||
|
||||
obj->oMenuButtonScale = scale;
|
||||
obj->oFaceAngleRoll = 0;
|
||||
obj->oMenuButtonTimer = 0;
|
||||
obj->oMenuButtonOrigPosX = obj->oParentRelativePosX;
|
||||
obj->oMenuButtonOrigPosY = obj->oParentRelativePosY;
|
||||
obj->oMenuButtonOrigPosZ = obj->oParentRelativePosZ;
|
||||
obj->oMenuButtonIsCustom = 1;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT;
|
||||
button->object = obj;
|
||||
return button;
|
||||
}
|
||||
|
||||
struct CustomMenu* custom_menu_create(struct CustomMenu* parent, char* label, u16 x, u16 y, f32 scale) {
|
||||
struct CustomMenuButton* button = custom_menu_create_button(parent, label, x, y, scale, SOUND_MENU_CAMERA_ZOOM_IN, NULL);
|
||||
struct CustomMenu* menu = calloc(1, sizeof(struct CustomMenu));
|
||||
menu->parent = parent;
|
||||
menu->depth = parent->depth + 1;
|
||||
menu->headerY = 25;
|
||||
menu->me = button;
|
||||
button->menu = menu;
|
||||
return menu;
|
||||
}
|
||||
|
||||
void custom_menu_system_init(void) {
|
||||
// allocate the main menu and set it to current
|
||||
sHead = calloc(1, sizeof(struct CustomMenu));
|
||||
sHead->me = calloc(1, sizeof(struct CustomMenuButton));
|
||||
sCurrentMenu = sHead;
|
||||
|
||||
// spawn the main menu game object
|
||||
struct Object* obj = spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, 0, 0, 0, 0, 0, 0);
|
||||
obj->oParentRelativePosZ += 1000;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_FULLSCREEN;
|
||||
obj->oFaceAngleYaw = 0x8000;
|
||||
obj->oFaceAngleRoll = 0;
|
||||
obj->oMenuButtonScale = 9.0f;
|
||||
obj->oMenuButtonOrigPosZ = obj->oPosZ;
|
||||
obj->oMenuButtonOrigPosX = 99999;
|
||||
obj->oMenuButtonIsCustom = 1;
|
||||
sHead->me->object = obj;
|
||||
|
||||
custom_menu_init(sHead);
|
||||
}
|
||||
|
||||
void custom_menu_destroy(void) {
|
||||
// TODO: clean up all of the calloc()'d memory
|
||||
}
|
||||
|
||||
void custom_menu_system_loop(void) {
|
||||
custom_menu_loop();
|
||||
}
|
||||
|
||||
static void button_force_instant_close(struct Object* obj) {
|
||||
obj->oFaceAngleYaw = 0x8000;
|
||||
obj->oFaceAnglePitch = 0;
|
||||
obj->oParentRelativePosX = obj->oMenuButtonOrigPosX;
|
||||
obj->oParentRelativePosY = obj->oMenuButtonOrigPosY;
|
||||
obj->oParentRelativePosZ = obj->oMenuButtonOrigPosZ;
|
||||
obj->oMenuButtonScale = 0.11111111f;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT;
|
||||
obj->oMenuButtonTimer = 0;
|
||||
}
|
||||
|
||||
static void button_force_instant_open(struct Object* obj) {
|
||||
obj->oFaceAngleYaw = 0;
|
||||
obj->oFaceAnglePitch = 0;
|
||||
obj->oParentRelativePosX = 0.0f;
|
||||
obj->oParentRelativePosY = 0.0f;
|
||||
obj->oParentRelativePosZ = -801;
|
||||
obj->oMenuButtonScale = 0.623111;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_FULLSCREEN;
|
||||
obj->oMenuButtonTimer = 0;
|
||||
}
|
||||
|
||||
void custom_menu_open(struct CustomMenu* menu) {
|
||||
if (sCurrentMenu == menu) { return; }
|
||||
if (menu == NULL) { return; }
|
||||
// force instant-close all parents if not a direct route
|
||||
{
|
||||
// check all buttons of current menu to see if the desired menu is directly beneath it
|
||||
struct CustomMenuButton* onButton = sCurrentMenu->buttons;
|
||||
u8 foundMenu = FALSE;
|
||||
while (onButton != NULL) {
|
||||
if (onButton == menu->me) { foundMenu = TRUE; break; }
|
||||
onButton = onButton->next;
|
||||
}
|
||||
|
||||
// if not direct route, force close all the way to the main menu
|
||||
if (!foundMenu) {
|
||||
struct CustomMenu* onMenu = sCurrentMenu;
|
||||
while (onMenu != NULL && onMenu != sHead) {
|
||||
struct Object* obj = onMenu->me->object;
|
||||
if (obj->oMenuButtonState != MENU_BUTTON_STATE_FULLSCREEN) { break; }
|
||||
button_force_instant_close(obj);
|
||||
if (onMenu->on_close != NULL) { onMenu->on_close(); }
|
||||
onMenu = onMenu->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// force instant-open all parents
|
||||
{
|
||||
struct CustomMenu* onMenu = menu->parent;
|
||||
while (onMenu != NULL) {
|
||||
struct Object* obj = onMenu->me->object;
|
||||
if (obj->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { break; }
|
||||
button_force_instant_open(obj);
|
||||
onMenu = onMenu->parent;
|
||||
}
|
||||
}
|
||||
struct Object* obj = menu->me->object;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
|
||||
obj->oMenuButtonTimer = 0;
|
||||
gMenuStringAlpha = 0;
|
||||
sLastMenu = sCurrentMenu;
|
||||
sCurrentMenu = menu;
|
||||
}
|
||||
|
||||
void custom_menu_close(void) {
|
||||
struct Object* obj = sCurrentMenu->me->object;
|
||||
obj->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING;
|
||||
obj->oMenuButtonTimer = 0;
|
||||
gMenuStringAlpha = 0;
|
||||
if (sCurrentMenu->on_close != NULL) { sCurrentMenu->on_close(); }
|
||||
sLastMenu = sCurrentMenu;
|
||||
if (sCurrentMenu->parent != NULL) {
|
||||
sCurrentMenu = sCurrentMenu->parent;
|
||||
}
|
||||
}
|
||||
|
||||
void custom_menu_close_system(void) {
|
||||
sHead->me->object->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING;
|
||||
gInCustomMenu = FALSE;
|
||||
}
|
||||
|
||||
static s32 cursor_inside_button(struct CustomMenuButton* button, f32 cursorX, f32 cursorY) {
|
||||
f32 x = button->object->oParentRelativePosX;
|
||||
f32 y = button->object->oParentRelativePosY;
|
||||
f32 scale = button->object->oMenuButtonScale;
|
||||
|
||||
x *= -0.137f;
|
||||
y *= 0.137f;
|
||||
|
||||
s16 maxX = x + scale * 185.0f;
|
||||
s16 minX = x - scale * 185.0f;
|
||||
s16 maxY = y + scale * 185.0f;
|
||||
s16 minY = y - scale * 101.0f;
|
||||
|
||||
return (cursorX < maxX && minX < cursorX && cursorY < maxY && minY < cursorY);
|
||||
}
|
||||
|
||||
void custom_menu_cursor_click(f32 cursorX, f32 cursorY) {
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u16 cursorClickButtons = (A_BUTTON | B_BUTTON | START_BUTTON | Z_TRIG);
|
||||
#else
|
||||
u16 cursorClickButtons = (A_BUTTON | B_BUTTON | START_BUTTON);
|
||||
#endif
|
||||
if (!(gPlayer3Controller->buttonPressed & cursorClickButtons)) { return; }
|
||||
if (sCurrentMenu->me->object->oMenuButtonState != MENU_BUTTON_STATE_FULLSCREEN) { return; }
|
||||
|
||||
if (sErrorDialog != NULL) {
|
||||
struct ErrorDialog* current = sErrorDialog;
|
||||
sErrorDialog = sErrorDialog->next;
|
||||
free(current->dialog);
|
||||
free(current);
|
||||
play_sound(SOUND_ACTION_BONK, gDefaultSoundArgs);
|
||||
if (sErrorDialog != NULL) {
|
||||
play_sound(SOUND_MARIO_OOOF2, gDefaultSoundArgs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct CustomMenuButton* button = sCurrentMenu->buttons;
|
||||
while (button != NULL) {
|
||||
if (cursor_inside_button(button, cursorX, cursorY)) {
|
||||
u8 didSomething = FALSE;
|
||||
|
||||
if (button->menu != NULL) {
|
||||
custom_menu_open(button->menu);
|
||||
didSomething = TRUE;
|
||||
}
|
||||
|
||||
if (button->on_click != NULL) {
|
||||
button->on_click();
|
||||
didSomething = TRUE;
|
||||
}
|
||||
|
||||
if (button->clickSound != 0) {
|
||||
play_sound(button->clickSound, gDefaultSoundArgs);
|
||||
}
|
||||
|
||||
if (didSomething) { break; }
|
||||
}
|
||||
button = button->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void button_label_pos(struct CustomMenuButton* button, s16* outX, s16* outY) {
|
||||
f32 x = button->object->oParentRelativePosX;
|
||||
f32 y = button->object->oParentRelativePosY;
|
||||
x -= strlen(button->label) * -27.0f;
|
||||
y += -163.0f;
|
||||
*outX = 165.0f + x * -0.137f;
|
||||
*outY = 110.0f + y * 0.137f;
|
||||
}
|
||||
|
||||
void custom_menu_print_strings(void) {
|
||||
// figure out alpha
|
||||
struct Object* curObj = sCurrentMenu->me->object;
|
||||
struct Object* lastObj = (sLastMenu != NULL) ? sLastMenu->me->object : NULL;
|
||||
|
||||
if (curObj != NULL && lastObj != NULL) {
|
||||
if (curObj->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN && lastObj->oMenuButtonState != MENU_BUTTON_STATE_SHRINKING) {
|
||||
if (gMenuStringAlpha < 250) {
|
||||
gMenuStringAlpha += 10;
|
||||
} else {
|
||||
gMenuStringAlpha = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print header
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuStringAlpha);
|
||||
char* headerLabel = sCurrentMenu->me->label;
|
||||
u16 headerLabelLen = strlen(headerLabel);
|
||||
u16 headerX = (u16)(159.66f - (headerLabelLen * 5.66f));
|
||||
|
||||
unsigned char header[64];
|
||||
str_ascii_to_dialog(headerLabel, header, headerLabelLen);
|
||||
|
||||
print_hud_lut_string(HUD_LUT_DIFF, headerX, sCurrentMenu->headerY, header);
|
||||
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
|
||||
|
||||
// print text
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
struct CustomMenuButton* button = sCurrentMenu->buttons;
|
||||
while (button != NULL) {
|
||||
gDPSetEnvColor(gDisplayListHead++, 222, 222, 222, gMenuStringAlpha);
|
||||
s16 x, y;
|
||||
button_label_pos(button, &x, &y);
|
||||
print_generic_ascii_string(x, y, button->label);
|
||||
button = button->next;
|
||||
}
|
||||
if (sCurrentMenu->draw_strings != NULL) { sCurrentMenu->draw_strings(); }
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
}
|
||||
|
||||
void custom_menu_render_top(void) {
|
||||
// print error message
|
||||
if (sErrorDialog != NULL) {
|
||||
// black screen
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 240.0f, 0);
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT / 130.0f, 3.0f, 1.0f);
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 240);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
|
||||
// print text
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
f32 textWidth = get_generic_dialog_width(sErrorDialog->dialog);
|
||||
f32 textHeight = get_generic_dialog_height(sErrorDialog->dialog);
|
||||
|
||||
f32 xPos = (SCREEN_WIDTH - textWidth) / 2.0f;
|
||||
f32 yPos = (SCREEN_HEIGHT + textHeight) / 2.0f;
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, 30, 30, 30, 255);
|
||||
print_generic_string(xPos, yPos, sErrorDialog->dialog);
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
print_generic_string((xPos - 1), (yPos + 1), sErrorDialog->dialog);
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grow from submenu, used by selecting a file in the score menu.
|
||||
*/
|
||||
void bhv_menu_button_growing_from_custom(struct Object* button) {
|
||||
if (button->oMenuButtonTimer < 16) {
|
||||
button->oFaceAngleYaw += 0x800;
|
||||
}
|
||||
if (button->oMenuButtonTimer < 8) {
|
||||
button->oFaceAnglePitch += 0x800;
|
||||
}
|
||||
if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) {
|
||||
button->oFaceAnglePitch -= 0x800;
|
||||
}
|
||||
|
||||
button->oParentRelativePosX -= button->oMenuButtonOrigPosX / 16.0;
|
||||
button->oParentRelativePosY -= button->oMenuButtonOrigPosY / 16.0;
|
||||
button->oParentRelativePosZ -= 50;
|
||||
|
||||
button->oMenuButtonScale += 0.032f;
|
||||
|
||||
button->oMenuButtonTimer++;
|
||||
if (button->oMenuButtonTimer == 16) {
|
||||
button->oParentRelativePosX = 0.0f;
|
||||
button->oParentRelativePosY = 0.0f;
|
||||
button->oMenuButtonState = MENU_BUTTON_STATE_FULLSCREEN;
|
||||
button->oMenuButtonTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shrink back to submenu, used to return back while inside a score save menu.
|
||||
*/
|
||||
void bhv_menu_button_shrinking_to_custom(struct Object* button) {
|
||||
if (button->oMenuButtonTimer < 16) {
|
||||
button->oFaceAngleYaw -= 0x800;
|
||||
}
|
||||
if (button->oMenuButtonTimer < 8) {
|
||||
button->oFaceAnglePitch -= 0x800;
|
||||
}
|
||||
if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) {
|
||||
button->oFaceAnglePitch += 0x800;
|
||||
}
|
||||
|
||||
button->oParentRelativePosX += button->oMenuButtonOrigPosX / 16.0;
|
||||
button->oParentRelativePosY += button->oMenuButtonOrigPosY / 16.0;
|
||||
button->oParentRelativePosZ += 50;
|
||||
|
||||
button->oMenuButtonScale -= 0.032f;
|
||||
|
||||
button->oMenuButtonTimer++;
|
||||
if (button->oMenuButtonTimer == 16) {
|
||||
button->oParentRelativePosX = button->oMenuButtonOrigPosX;
|
||||
button->oParentRelativePosY = button->oMenuButtonOrigPosY;
|
||||
button->oMenuButtonScale = 0.11111111f;
|
||||
button->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT;
|
||||
button->oMenuButtonTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void custom_menu_error(char* message) {
|
||||
struct ErrorDialog* errorDialog = malloc(sizeof(struct ErrorDialog));
|
||||
memset(errorDialog, 0, sizeof(struct ErrorDialog));
|
||||
errorDialog->dialog = malloc(sizeof(u8) * (strlen(message) + 1));
|
||||
str_ascii_to_dialog(message, errorDialog->dialog, strlen(message));
|
||||
|
||||
if (sErrorDialog == NULL) {
|
||||
sErrorDialog = errorDialog;
|
||||
play_sound(SOUND_MARIO_OOOF2, gDefaultSoundArgs);
|
||||
} else {
|
||||
struct ErrorDialog* item = sErrorDialog;
|
||||
while (item != NULL) {
|
||||
if (item->next == NULL) {
|
||||
item->next = errorDialog;
|
||||
break;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef CUSTOM_MENU_SYSTEM_H
|
||||
#define CUSTOM_MENU_SYSTEM_H
|
||||
#include "file_select.h"
|
||||
|
||||
struct CustomMenuButton {
|
||||
struct Object* object;
|
||||
char* label;
|
||||
void (*on_click)(void);
|
||||
u32 clickSound;
|
||||
struct CustomMenu* menu;
|
||||
struct CustomMenuButton* next;
|
||||
};
|
||||
|
||||
struct CustomMenu {
|
||||
struct CustomMenu* parent;
|
||||
struct CustomMenuButton* me;
|
||||
struct CustomMenuButton* buttons;
|
||||
u16 headerY;
|
||||
u16 depth;
|
||||
void (*draw_strings)(void);
|
||||
void (*on_close)(void);
|
||||
};
|
||||
|
||||
struct CustomMenuButtonScale {
|
||||
f32 small;
|
||||
f32 medium;
|
||||
f32 large;
|
||||
};
|
||||
extern struct CustomMenuButtonScale gButtonScale;
|
||||
|
||||
extern u8 gMenuStringAlpha;
|
||||
|
||||
void custom_menu_system_init(void);
|
||||
struct CustomMenu* custom_menu_create(struct CustomMenu* parent, char* label, u16 x, u16 y, f32 scale);
|
||||
struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, f32 scale, s32 clickSound, void (*on_click)(void));
|
||||
|
||||
void custom_menu_system_loop(void);
|
||||
void custom_menu_print_strings(void);
|
||||
void custom_menu_render_top(void);
|
||||
void custom_menu_cursor_click(f32 x, f32 y);
|
||||
|
||||
void custom_menu_open(struct CustomMenu* menu);
|
||||
void custom_menu_close(void);
|
||||
void custom_menu_close_system(void);
|
||||
|
||||
void bhv_menu_button_growing_from_custom(struct Object* button);
|
||||
void bhv_menu_button_shrinking_to_custom(struct Object* button);
|
||||
|
||||
void custom_menu_error(char* message);
|
||||
|
||||
#endif // CUSTOM_MENU_SYSTEM_H
|
|
@ -23,9 +23,6 @@
|
|||
|
||||
#include "eu_translation.h"
|
||||
|
||||
#include "custom_menu_system.h"
|
||||
#include "custom_menu.h"
|
||||
|
||||
#ifdef VERSION_EU
|
||||
#undef LANGUAGE_FUNCTION
|
||||
#define LANGUAGE_FUNCTION sLanguageMode
|
||||
|
@ -38,9 +35,6 @@
|
|||
* special menu messages and phases, button states and button clicked checks.
|
||||
*/
|
||||
|
||||
u8 gInCustomMenu = 1;
|
||||
u8 sIgnoreMenuTimer = 5;
|
||||
|
||||
#ifdef VERSION_US
|
||||
// The current sound mode is automatically centered on US due to
|
||||
// the large length difference between options.
|
||||
|
@ -530,9 +524,7 @@ void bhv_menu_button_loop(void) {
|
|||
gCurrentObject->oMenuButtonOrigPosZ = gCurrentObject->oPosZ;
|
||||
break;
|
||||
case MENU_BUTTON_STATE_GROWING: // Switching from button to menu state
|
||||
if (gInCustomMenu) {
|
||||
bhv_menu_button_growing_from_custom(gCurrentObject);
|
||||
} else if (sCurrentMenuLevel == MENU_LAYER_MAIN) {
|
||||
if (sCurrentMenuLevel == MENU_LAYER_MAIN) {
|
||||
bhv_menu_button_growing_from_main_menu(gCurrentObject);
|
||||
} else if (sCurrentMenuLevel == MENU_LAYER_SUBMENU) {
|
||||
bhv_menu_button_growing_from_submenu(gCurrentObject); // Only used for score files
|
||||
|
@ -543,9 +535,7 @@ void bhv_menu_button_loop(void) {
|
|||
case MENU_BUTTON_STATE_FULLSCREEN: // Menu state
|
||||
break;
|
||||
case MENU_BUTTON_STATE_SHRINKING: // Switching from menu to button state
|
||||
if (gInCustomMenu) {
|
||||
bhv_menu_button_shrinking_to_custom(gCurrentObject);
|
||||
} else if (sCurrentMenuLevel == MENU_LAYER_MAIN) {
|
||||
if (sCurrentMenuLevel == MENU_LAYER_MAIN) {
|
||||
bhv_menu_button_shrinking_to_main_menu(gCurrentObject);
|
||||
} else if (sCurrentMenuLevel == MENU_LAYER_SUBMENU) {
|
||||
bhv_menu_button_shrinking_to_submenu(gCurrentObject); // Only used for score files
|
||||
|
@ -1127,7 +1117,6 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) {
|
|||
void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) {
|
||||
if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) {
|
||||
sSelectedFileNum = fileNum;
|
||||
custom_menu_on_load_save_file(sSelectedFileNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1362,9 +1351,6 @@ void bhv_menu_button_manager_init(void) {
|
|||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonScale = 1.0f;
|
||||
|
||||
sTextBaseAlpha = 0;
|
||||
|
||||
// custom menus
|
||||
custom_menu_system_init();
|
||||
}
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
@ -1378,10 +1364,6 @@ void bhv_menu_button_manager_init(void) {
|
|||
* Also play a sound and/or render buttons depending of the button ID selected.
|
||||
*/
|
||||
void check_main_menu_clicked_buttons(void) {
|
||||
if (sIgnoreMenuTimer > 0) {
|
||||
sIgnoreMenuTimer--;
|
||||
return;
|
||||
}
|
||||
#ifdef VERSION_EU
|
||||
if (sMainMenuTimer >= 5) {
|
||||
#endif
|
||||
|
@ -1461,10 +1443,6 @@ void check_main_menu_clicked_buttons(void) {
|
|||
* is loaded, and that checks what buttonID is clicked in the main menu.
|
||||
*/
|
||||
void bhv_menu_button_manager_loop(void) {
|
||||
if (gInCustomMenu) {
|
||||
custom_menu_system_loop();
|
||||
return;
|
||||
}
|
||||
switch (sSelectedButtonID) {
|
||||
case MENU_BUTTON_NONE:
|
||||
check_main_menu_clicked_buttons();
|
||||
|
@ -1651,13 +1629,6 @@ void handle_controller_cursor_input(void) {
|
|||
if (sCursorPos[1] < -90.0f) {
|
||||
sCursorPos[1] = -90.0f;
|
||||
}
|
||||
|
||||
if (sCursorClickingTimer == 0) {
|
||||
handle_cursor_button_input();
|
||||
if (gInCustomMenu) {
|
||||
custom_menu_cursor_click(sCursorPos[0], sCursorPos[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2741,11 +2712,6 @@ static void print_file_select_strings(void) {
|
|||
|
||||
create_dl_ortho_matrix();
|
||||
|
||||
if (gInCustomMenu) {
|
||||
custom_menu_print_strings();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sSelectedButtonID) {
|
||||
case MENU_BUTTON_NONE:
|
||||
#ifdef VERSION_EU
|
||||
|
@ -2804,7 +2770,6 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap
|
|||
if (callContext == GEO_CONTEXT_RENDER) {
|
||||
print_file_select_strings();
|
||||
print_menu_cursor();
|
||||
custom_menu_render_top();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -129,7 +129,6 @@ enum SoundModeMenuActionPhase {
|
|||
|
||||
extern f32 sCursorPos[2];
|
||||
extern s8 sSelectedFileNum;
|
||||
extern u8 gInCustomMenu;
|
||||
|
||||
void beh_yellow_background_menu_init(void);
|
||||
void beh_yellow_background_menu_loop(void);
|
||||
|
|
|
@ -92,7 +92,8 @@ bool configCameraAnalog = true;
|
|||
bool configCameraMouse = false;
|
||||
#endif
|
||||
bool configSkipIntro = 0;
|
||||
bool configShareLives = 0;
|
||||
bool configShareLives = 0;
|
||||
bool configEnableCheats = 0;
|
||||
bool configHUD = true;
|
||||
#ifdef DISCORDRPC
|
||||
bool configDiscordRPC = true;
|
||||
|
@ -104,9 +105,8 @@ unsigned int configHostPort = DEFAULT_PORT;
|
|||
unsigned int configHostSaveSlot = 1;
|
||||
unsigned int configPlayerInteraction = 1;
|
||||
unsigned int configPlayerKnockbackStrength = 25;
|
||||
unsigned int configStayInLevelAfterStar = 0;
|
||||
bool configStayInLevelAfterStar = 0;
|
||||
unsigned int configNetworkSystem = 0;
|
||||
bool configLuigiSounds = true;
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||
|
@ -154,6 +154,7 @@ static const struct ConfigOption options[] = {
|
|||
#endif
|
||||
{.name = "skip_intro", .type = CONFIG_TYPE_BOOL, .boolValue = &configSkipIntro},
|
||||
{.name = "share_lives", .type = CONFIG_TYPE_BOOL, .boolValue = &configShareLives},
|
||||
{.name = "enable_cheats", .type = CONFIG_TYPE_BOOL, .boolValue = &configEnableCheats},
|
||||
#ifdef DISCORDRPC
|
||||
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
|
||||
#endif
|
||||
|
@ -164,9 +165,8 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "coop_host_save_slot", .type = CONFIG_TYPE_UINT , .uintValue = &configHostSaveSlot},
|
||||
{.name = "coop_player_interaction", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerInteraction},
|
||||
{.name = "coop_player_knockback_strength", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerKnockbackStrength},
|
||||
{.name = "coop_stay_in_level_after_star", .type = CONFIG_TYPE_UINT , .uintValue = &configStayInLevelAfterStar},
|
||||
{.name = "coop_stay_in_level_after_star", .type = CONFIG_TYPE_UINT , .boolValue = &configStayInLevelAfterStar},
|
||||
{.name = "coop_network_system", .type = CONFIG_TYPE_UINT , .uintValue = &configNetworkSystem},
|
||||
{.name = "coop_luigi_sounds", .type = CONFIG_TYPE_BOOL , .boolValue = &configLuigiSounds},
|
||||
};
|
||||
|
||||
// Reads an entire line from a file (excluding the newline character) and returns an allocated string
|
||||
|
|
|
@ -61,6 +61,7 @@ extern bool configCameraAnalog;
|
|||
extern bool configHUD;
|
||||
extern bool configSkipIntro;
|
||||
extern bool configShareLives;
|
||||
extern bool configEnableCheats;
|
||||
#ifdef DISCORDRPC
|
||||
extern bool configDiscordRPC;
|
||||
#endif
|
||||
|
@ -70,9 +71,8 @@ extern unsigned int configHostPort;
|
|||
extern unsigned int configHostSaveSlot;
|
||||
extern unsigned int configPlayerInteraction;
|
||||
extern unsigned int configPlayerKnockbackStrength;
|
||||
extern unsigned int configStayInLevelAfterStar;
|
||||
extern bool configStayInLevelAfterStar;
|
||||
extern unsigned int configNetworkSystem;
|
||||
extern bool configLuigiSounds;
|
||||
|
||||
void configfile_load(const char *filename);
|
||||
void configfile_save(const char *filename);
|
||||
|
|
|
@ -17,20 +17,7 @@
|
|||
#include "pc/pc_main.h"
|
||||
#include "engine/math_util.h"
|
||||
#include "menu/file_select.h"
|
||||
#include "game/chat.h"
|
||||
|
||||
// TODO: use some common lookup header
|
||||
#define SCANCODE_BACKSPACE 0x0E
|
||||
#define SCANCODE_ESCAPE 0x01
|
||||
#define SCANCODE_ENTER 0x1C
|
||||
#define SCANCODE_V 0x2F
|
||||
#define SCANCODE_INSERT 0x152
|
||||
#define SCANCODE_CTRL1 0x1D
|
||||
#define SCANCODE_CTRL2 0x11D
|
||||
#define SCANCODE_SHIFT1 0x2A
|
||||
#define SCANCODE_SHIFT2 0x36
|
||||
#define SCANCODE_ALT1 0x38
|
||||
#define SCANCODE_ALT2 0x138
|
||||
#include "src/pc/djui/djui.h"
|
||||
|
||||
static int keyboard_buttons_down;
|
||||
|
||||
|
@ -40,16 +27,6 @@ static int num_keybinds = 0;
|
|||
|
||||
static u32 keyboard_lastkey = VK_INVALID;
|
||||
|
||||
char gTextInput[MAX_TEXT_INPUT];
|
||||
static u8 sInTextInput = false;
|
||||
static u8 sMaxTextInput = 0;
|
||||
static clock_t sIgnoreTextInput = 0;
|
||||
|
||||
u8 held_ctrl, held_shift, held_alt;
|
||||
static enum TextInputMode sTextInputMode;
|
||||
void (*textInputOnEscape)(void) = NULL;
|
||||
void (*textInputOnEnter)(void) = NULL;
|
||||
|
||||
static int keyboard_map_scancode(int scancode) {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < num_keybinds; i++) {
|
||||
|
@ -60,68 +37,16 @@ static int keyboard_map_scancode(int scancode) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void keyboard_alter_modifier(int scancode, bool down) {
|
||||
if (down) {
|
||||
switch (scancode) {
|
||||
case SCANCODE_CTRL1: held_ctrl |= (1 << 0); break;
|
||||
case SCANCODE_CTRL2: held_ctrl |= (1 << 1); break;
|
||||
case SCANCODE_SHIFT1: held_shift |= (1 << 0); break;
|
||||
case SCANCODE_SHIFT2: held_shift |= (1 << 1); break;
|
||||
case SCANCODE_ALT1: held_alt |= (1 << 0); break;
|
||||
case SCANCODE_ALT2: held_alt |= (1 << 1); break;
|
||||
}
|
||||
} else {
|
||||
switch (scancode) {
|
||||
case SCANCODE_CTRL1: held_ctrl &= ~(1 << 0); break;
|
||||
case SCANCODE_CTRL2: held_ctrl &= ~(1 << 1); break;
|
||||
case SCANCODE_SHIFT1: held_shift &= ~(1 << 0); break;
|
||||
case SCANCODE_SHIFT2: held_shift &= ~(1 << 1); break;
|
||||
case SCANCODE_ALT1: held_alt &= ~(1 << 0); break;
|
||||
case SCANCODE_ALT2: held_alt &= ~(1 << 1); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool keyboard_on_key_down(int scancode) {
|
||||
// alter the held value of modifier keys
|
||||
keyboard_alter_modifier(scancode, true);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!sInTextInput) {
|
||||
debug_keyboard_on_key_down(scancode);
|
||||
}
|
||||
debug_keyboard_on_key_down(scancode);
|
||||
#endif
|
||||
if (sInTextInput) {
|
||||
// perform text-input-specific actions
|
||||
switch (scancode & 0xFF) {
|
||||
case SCANCODE_BACKSPACE:
|
||||
gTextInput[max(strlen(gTextInput) - 1, 0)] = '\0';
|
||||
break;
|
||||
case SCANCODE_ESCAPE:
|
||||
if (textInputOnEscape != NULL) { textInputOnEscape(); }
|
||||
break;
|
||||
case SCANCODE_ENTER:
|
||||
if (textInputOnEnter != NULL) { textInputOnEnter(); }
|
||||
break;
|
||||
case SCANCODE_V:
|
||||
if (held_ctrl) { keyboard_on_text_input(wm_api->get_clipboard_text()); }
|
||||
break;
|
||||
case SCANCODE_INSERT:
|
||||
if (held_shift) { keyboard_on_text_input(wm_api->get_clipboard_text()); }
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore any normal key down event if we're in text-input mode
|
||||
// see if interactable captures this scancode
|
||||
if (djui_interactable_on_key_down(scancode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!held_alt && (scancode == (int)configKeyChat[0])) {
|
||||
if (sSelectedFileNum != 0) {
|
||||
sIgnoreTextInput = clock() + CLOCKS_PER_SEC * 0.01f;
|
||||
chat_start_input();
|
||||
}
|
||||
}
|
||||
|
||||
int mapped = keyboard_map_scancode(scancode);
|
||||
keyboard_buttons_down |= mapped;
|
||||
keyboard_lastkey = scancode;
|
||||
|
@ -129,13 +54,7 @@ bool keyboard_on_key_down(int scancode) {
|
|||
}
|
||||
|
||||
bool keyboard_on_key_up(int scancode) {
|
||||
// alter the held value of modifier keys
|
||||
keyboard_alter_modifier(scancode, false);
|
||||
|
||||
if (sInTextInput) {
|
||||
// ignore any key up event if we're in text-input mode
|
||||
return FALSE;
|
||||
}
|
||||
djui_interactable_on_key_up(scancode);
|
||||
|
||||
int mapped = keyboard_map_scancode(scancode);
|
||||
keyboard_buttons_down &= ~mapped;
|
||||
|
@ -148,87 +67,8 @@ void keyboard_on_all_keys_up(void) {
|
|||
keyboard_buttons_down = 0;
|
||||
}
|
||||
|
||||
char* keyboard_start_text_input(enum TextInputMode inInputMode, u8 inMaxTextInput, void (*onEscape)(void), void (*onEnter)(void)) {
|
||||
// set text-input events
|
||||
textInputOnEscape = onEscape;
|
||||
textInputOnEnter = onEnter;
|
||||
sMaxTextInput = inMaxTextInput;
|
||||
|
||||
// clear buffer
|
||||
for (int i = 0; i < MAX_TEXT_INPUT; i++) { gTextInput[i] = '\0'; }
|
||||
|
||||
// clear held-value for modifiers
|
||||
held_ctrl = 0;
|
||||
held_shift = 0;
|
||||
held_alt = 0;
|
||||
|
||||
// start allowing text input
|
||||
wm_api->start_text_input();
|
||||
sTextInputMode = inInputMode;
|
||||
sInTextInput = true;
|
||||
}
|
||||
|
||||
void keyboard_stop_text_input(void) {
|
||||
// stop allowing text input
|
||||
sInTextInput = false;
|
||||
wm_api->stop_text_input();
|
||||
}
|
||||
|
||||
bool keyboard_in_text_input(void) { return sInTextInput; }
|
||||
|
||||
static bool keyboard_allow_character_input(char c) {
|
||||
switch (sTextInputMode) {
|
||||
case TIM_IP:
|
||||
// IP only allows numbers, periods, and spaces
|
||||
return (c >= '0' && c <= '9')
|
||||
|| (c == '.')
|
||||
|| (c == ' ');
|
||||
|
||||
case TIM_MULTI_LINE:
|
||||
// multi-line allows new-line character
|
||||
if (c == '\n') { return true; }
|
||||
// intentional fall-through
|
||||
|
||||
case TIM_SINGLE_LINE:
|
||||
// allow all characters that we can display in-game
|
||||
return (c >= '0' && c <= '9')
|
||||
|| (c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c == '\'') || (c == '.')
|
||||
|| (c == ',') || (c == '-')
|
||||
|| (c == '(') || (c == ')')
|
||||
|| (c == '&') || (c == '!')
|
||||
|| (c == '%') || (c == '?')
|
||||
|| (c == '"') || (c == '~')
|
||||
|| (c == '*') || (c == ' ');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void keyboard_on_text_input(char* text) {
|
||||
if (sIgnoreTextInput != 0 && clock() <= sIgnoreTextInput) {
|
||||
sIgnoreTextInput = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sInTextInput) { return; }
|
||||
// sanity check input
|
||||
if (text == NULL) { return; }
|
||||
|
||||
int i = strlen(gTextInput);
|
||||
while (*text != '\0') {
|
||||
// make sure we don't overrun the buffer
|
||||
if (i >= MAX_TEXT_INPUT) { break; }
|
||||
if (i >= sMaxTextInput) { break; }
|
||||
|
||||
// copy over character if we're allowed to input it
|
||||
if (keyboard_allow_character_input(*text)) {
|
||||
gTextInput[i++] = *text;
|
||||
}
|
||||
|
||||
text++;
|
||||
}
|
||||
djui_interactable_on_text_input(text);
|
||||
}
|
||||
|
||||
static void keyboard_add_binds(int mask, unsigned int *scancode) {
|
||||
|
|
|
@ -6,26 +6,32 @@
|
|||
|
||||
# define VK_BASE_KEYBOARD 0x0000
|
||||
|
||||
#define SCANCODE_ESCAPE 1
|
||||
#define SCANCODE_BACKSPACE 14
|
||||
#define SCANCODE_ENTER 28
|
||||
#define SCANCODE_CONTROL_LEFT 29
|
||||
#define SCANCODE_SHIFT_LEFT 42
|
||||
#define SCANCODE_A 30
|
||||
#define SCANCODE_X 45
|
||||
#define SCANCODE_C 46
|
||||
#define SCANCODE_V 47
|
||||
#define SCANCODE_SHIFT_RIGHT 54
|
||||
#define SCANCODE_CONTROL_RIGHT 285
|
||||
#define SCANCODE_HOME 327
|
||||
#define SCANCODE_LEFT 331
|
||||
#define SCANCODE_RIGHT 333
|
||||
#define SCANCODE_END 335
|
||||
#define SCANCODE_INSERT 338
|
||||
#define SCANCODE_DELETE 339
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_TEXT_INPUT 255
|
||||
extern char gTextInput[];
|
||||
|
||||
enum TextInputMode {
|
||||
TIM_IP,
|
||||
TIM_MULTI_LINE,
|
||||
TIM_SINGLE_LINE,
|
||||
};
|
||||
|
||||
bool keyboard_on_key_down(int scancode);
|
||||
bool keyboard_on_key_up(int scancode);
|
||||
void keyboard_on_all_keys_up(void);
|
||||
void keyboard_on_text_input(char* text);
|
||||
char* keyboard_start_text_input(enum TextInputMode, u8 inMaxTextInput, void (*onEscape)(void), void (*onEnter)(void));
|
||||
void keyboard_stop_text_input(void);
|
||||
bool keyboard_in_text_input(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
extern int mouse_x;
|
||||
extern int mouse_y;
|
||||
|
||||
extern int mouse_window_buttons;
|
||||
extern int mouse_window_x;
|
||||
extern int mouse_window_y;
|
||||
|
||||
|
||||
#define VK_BASE_MOUSE 0x2000
|
||||
|
||||
extern struct ControllerAPI controller_mouse;
|
||||
|
|
|
@ -7,4 +7,6 @@
|
|||
|
||||
extern struct ControllerAPI controller_sdl;
|
||||
|
||||
void controller_sdl_read_mouse_window(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,10 @@ enum {
|
|||
int mouse_x;
|
||||
int mouse_y;
|
||||
|
||||
int mouse_window_buttons;
|
||||
int mouse_window_x;
|
||||
int mouse_window_y;
|
||||
|
||||
#ifdef BETTERCAMERA
|
||||
extern u8 newcam_mouse;
|
||||
#endif
|
||||
|
@ -155,9 +159,11 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
|
||||
u32 mouse = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
|
||||
|
||||
for (u32 i = 0; i < num_mouse_binds; ++i)
|
||||
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
|
||||
pad->button |= mouse_binds[i][1];
|
||||
if (!gInteractableOverridePad) {
|
||||
for (u32 i = 0; i < num_mouse_binds; ++i)
|
||||
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
|
||||
pad->button |= mouse_binds[i][1];
|
||||
}
|
||||
|
||||
// remember buttons that changed from 0 to 1
|
||||
last_mouse = (mouse_buttons ^ mouse) & mouse;
|
||||
|
@ -238,6 +244,11 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
}
|
||||
}
|
||||
|
||||
void controller_sdl_read_mouse_window(void) {
|
||||
if (!init_ok) { return; }
|
||||
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);
|
||||
}
|
||||
|
||||
static void controller_sdl_rumble_play(f32 strength, f32 length) { }
|
||||
|
||||
static void controller_sdl_rumble_stop(void) { }
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "game/level_update.h"
|
||||
|
||||
#include "pc/djui/djui.h"
|
||||
|
||||
// mouse buttons are also in the controller namespace (why), just offset 0x100
|
||||
#define VK_OFS_SDL_MOUSE 0x0100
|
||||
#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE)
|
||||
|
@ -31,6 +33,10 @@
|
|||
int mouse_x;
|
||||
int mouse_y;
|
||||
|
||||
int mouse_window_buttons;
|
||||
int mouse_window_x;
|
||||
int mouse_window_y;
|
||||
|
||||
#ifdef BETTERCAMERA
|
||||
extern u8 newcam_mouse;
|
||||
#endif
|
||||
|
@ -156,13 +162,14 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
else
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
|
||||
|
||||
u32 mouse = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
|
||||
|
||||
for (u32 i = 0; i < num_mouse_binds; ++i)
|
||||
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
|
||||
pad->button |= mouse_binds[i][1];
|
||||
|
||||
if (!gInteractableOverridePad) {
|
||||
for (u32 i = 0; i < num_mouse_binds; ++i)
|
||||
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
|
||||
pad->button |= mouse_binds[i][1];
|
||||
}
|
||||
// remember buttons that changed from 0 to 1
|
||||
last_mouse = (mouse_buttons ^ mouse) & mouse;
|
||||
mouse_buttons = mouse;
|
||||
|
@ -262,6 +269,11 @@ static void controller_sdl_read(OSContPad *pad) {
|
|||
}
|
||||
}
|
||||
|
||||
void controller_sdl_read_mouse_window(void) {
|
||||
if (!init_ok) { return; }
|
||||
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);
|
||||
}
|
||||
|
||||
static void controller_sdl_rumble_play(f32 strength, f32 length) {
|
||||
if (sdl_haptic)
|
||||
SDL_HapticRumblePlay(sdl_haptic, strength, (u32)(length * 1000.0f));
|
||||
|
|
55
src/pc/djui/djui.c
Normal file
55
src/pc/djui/djui.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "djui.h"
|
||||
#include "../debuglog.h"
|
||||
#include "pc/cliopts.h"
|
||||
|
||||
static Gfx* sSavedDisplayListHead = NULL;
|
||||
|
||||
struct DjuiRoot* gDjuiRoot = NULL;
|
||||
struct DjuiText* gDjuiPauseOptions = NULL;
|
||||
|
||||
void djui_init(void) {
|
||||
gDjuiRoot = djui_root_create();
|
||||
|
||||
gDjuiPauseOptions = djui_text_create(&gDjuiRoot->base, "R Button - Options");
|
||||
djui_base_set_size_type(&gDjuiPauseOptions->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&gDjuiPauseOptions->base, 1.0f, 32);
|
||||
djui_base_set_location(&gDjuiPauseOptions->base, 0, 16);
|
||||
djui_text_set_drop_shadow(gDjuiPauseOptions, 0, 0, 0, 255);
|
||||
djui_text_set_alignment(gDjuiPauseOptions, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_visible(&gDjuiPauseOptions->base, false);
|
||||
|
||||
if (gCLIOpts.Network != NT_SERVER) {
|
||||
djui_panel_main_create(NULL);
|
||||
//djui_panel_debug_create();
|
||||
}
|
||||
djui_cursor_create();
|
||||
}
|
||||
|
||||
void djui_connect_menu_open(void) {
|
||||
djui_panel_shutdown();
|
||||
djui_panel_main_create(NULL);
|
||||
djui_panel_join_create(NULL);
|
||||
djui_panel_join_message_create(NULL);
|
||||
}
|
||||
|
||||
void djui_render_patch(void) {
|
||||
// reset the head and re-render DJUI
|
||||
if (sSavedDisplayListHead == NULL) { return; }
|
||||
gDisplayListHead = sSavedDisplayListHead;
|
||||
djui_render();
|
||||
gDPFullSync(gDisplayListHead++);
|
||||
gSPEndDisplayList(gDisplayListHead++);
|
||||
}
|
||||
|
||||
void djui_render(void) {
|
||||
sSavedDisplayListHead = gDisplayListHead;
|
||||
create_dl_ortho_matrix();
|
||||
|
||||
djui_panel_update();
|
||||
djui_popup_update();
|
||||
|
||||
djui_base_render(&gDjuiRoot->base);
|
||||
|
||||
djui_cursor_update();
|
||||
djui_interactable_update();
|
||||
}
|
58
src/pc/djui/djui.h
Normal file
58
src/pc/djui/djui.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
#include <PR/gbi.h>
|
||||
#include <PR/ultratypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "game/game_init.h"
|
||||
#include "game/ingame_menu.h"
|
||||
|
||||
#include "djui_types.h"
|
||||
#include "djui_font.h"
|
||||
#include "djui_gfx.h"
|
||||
#include "djui_base.h"
|
||||
#include "djui_interactable.h"
|
||||
|
||||
#include "djui_root.h"
|
||||
#include "djui_cursor.h"
|
||||
#include "djui_rect.h"
|
||||
#include "djui_text.h"
|
||||
#include "djui_image.h"
|
||||
#include "djui_three_panel.h"
|
||||
|
||||
#include "djui_button.h"
|
||||
#include "djui_inputbox.h"
|
||||
#include "djui_slider.h"
|
||||
#include "djui_checkbox.h"
|
||||
#include "djui_flow_layout.h"
|
||||
#include "djui_selectionbox.h"
|
||||
#include "djui_bind.h"
|
||||
#include "djui_popup.h"
|
||||
#include "djui_chat_box.h"
|
||||
#include "djui_chat_message.h"
|
||||
|
||||
#include "djui_panel.h"
|
||||
#include "djui_panel_menu.h"
|
||||
#include "djui_panel_debug.h"
|
||||
#include "djui_panel_main.h"
|
||||
#include "djui_panel_host.h"
|
||||
#include "djui_panel_host_save.h"
|
||||
#include "djui_panel_host_message.h"
|
||||
#include "djui_panel_join.h"
|
||||
#include "djui_panel_join_message.h"
|
||||
#include "djui_panel_pause.h"
|
||||
#include "djui_panel_options.h"
|
||||
#include "djui_panel_camera.h"
|
||||
#include "djui_panel_controls.h"
|
||||
#include "djui_panel_display.h"
|
||||
#include "djui_panel_sound.h"
|
||||
#include "djui_panel_confirm.h"
|
||||
#include "djui_panel_cheats.h"
|
||||
|
||||
extern struct DjuiRoot* gDjuiRoot;
|
||||
extern struct DjuiText* gDjuiPauseOptions;
|
||||
|
||||
void djui_init(void);
|
||||
void djui_connect_menu_open(void);
|
||||
void djui_render_patch(void);
|
||||
void djui_render(void);
|
380
src/pc/djui/djui_base.c
Normal file
380
src/pc/djui/djui_base.c
Normal file
|
@ -0,0 +1,380 @@
|
|||
#include <string.h>
|
||||
#include "djui.h"
|
||||
|
||||
////////////////
|
||||
// properties //
|
||||
////////////////
|
||||
|
||||
void djui_base_set_visible(struct DjuiBase* base, bool visible) {
|
||||
base->visible = visible;
|
||||
}
|
||||
|
||||
void djui_base_set_enabled(struct DjuiBase* base, bool enabled) {
|
||||
base->enabled = enabled;
|
||||
if (base->interactable != NULL && base->interactable->on_enabled_change != NULL) {
|
||||
base->interactable->on_enabled_change(base);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_base_set_location(struct DjuiBase* base, f32 x, f32 y) {
|
||||
base->x.value = x;
|
||||
base->y.value = y;
|
||||
}
|
||||
|
||||
void djui_base_set_location_type(struct DjuiBase* base, enum DjuiScreenValueType xType, enum DjuiScreenValueType yType) {
|
||||
base->x.type = xType;
|
||||
base->y.type = yType;
|
||||
}
|
||||
|
||||
void djui_base_set_size(struct DjuiBase* base, f32 width, f32 height) {
|
||||
base->width.value = width;
|
||||
base->height.value = height;
|
||||
}
|
||||
|
||||
void djui_base_set_size_type(struct DjuiBase* base, enum DjuiScreenValueType widthType, enum DjuiScreenValueType heightType) {
|
||||
base->width.type = widthType;
|
||||
base->height.type = heightType;
|
||||
}
|
||||
|
||||
void djui_base_set_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a) {
|
||||
base->color.r = r;
|
||||
base->color.g = g;
|
||||
base->color.b = b;
|
||||
base->color.a = a;
|
||||
}
|
||||
|
||||
void djui_base_set_border_width(struct DjuiBase* base, f32 width) {
|
||||
base->borderWidth.value = width;
|
||||
}
|
||||
|
||||
void djui_base_set_border_width_type(struct DjuiBase* base, enum DjuiScreenValueType widthType) {
|
||||
base->borderWidth.type = widthType;
|
||||
}
|
||||
|
||||
void djui_base_set_border_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a) {
|
||||
base->borderColor.r = r;
|
||||
base->borderColor.g = g;
|
||||
base->borderColor.b = b;
|
||||
base->borderColor.a = a;
|
||||
}
|
||||
|
||||
void djui_base_set_padding(struct DjuiBase* base, f32 top, f32 right, f32 bottom, f32 left) {
|
||||
base->padding.top.value = top;
|
||||
base->padding.right.value = right;
|
||||
base->padding.bottom.value = bottom;
|
||||
base->padding.left.value = left;
|
||||
}
|
||||
|
||||
void djui_base_set_padding_type(struct DjuiBase* base, enum DjuiScreenValueType topType, enum DjuiScreenValueType rightType, enum DjuiScreenValueType bottomType, enum DjuiScreenValueType leftType) {
|
||||
base->padding.top.type = topType;
|
||||
base->padding.right.type = rightType;
|
||||
base->padding.bottom.type = bottomType;
|
||||
base->padding.left.type = leftType;
|
||||
}
|
||||
|
||||
void djui_base_set_alignment(struct DjuiBase* base, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign) {
|
||||
base->hAlign = hAlign;
|
||||
base->vAlign = vAlign;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// utility //
|
||||
/////////////
|
||||
|
||||
static void djui_base_get_cursor_hover_location(struct DjuiBase* base, f32* x, f32* y) {
|
||||
*x = (base->elem.x + base->elem.width * 3.0f / 4.0f);
|
||||
*y = (base->elem.y + base->elem.height * 3.0f / 4.0f);
|
||||
}
|
||||
|
||||
static void djui_base_clip(struct DjuiBase* base) {
|
||||
struct DjuiBase* parent = base->parent;
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
|
||||
clip->x = comp->x;
|
||||
clip->y = comp->y;
|
||||
clip->width = comp->width;
|
||||
clip->height = comp->height;
|
||||
|
||||
if (parent == NULL) { return; }
|
||||
|
||||
clip->x = fmax(clip->x, parent->clip.x);
|
||||
clip->y = fmax(clip->y, parent->clip.y);
|
||||
|
||||
clip->width = (comp->x + comp->width) - clip->x;
|
||||
clip->height = (comp->y + comp->height) - clip->y;
|
||||
|
||||
clip->width = fmin(clip->width, (parent->clip.x + parent->clip.width) - clip->x);
|
||||
clip->height = fmin(clip->height, (parent->clip.y + parent->clip.height) - clip->y);
|
||||
}
|
||||
|
||||
static void djui_base_add_padding(struct DjuiBase* base) {
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiBaseRect* parentComp = &base->comp;
|
||||
|
||||
f32 tPad = (base->padding.top.type == DJUI_SVT_RELATIVE) ? parentComp->height * base->padding.top.value : base->padding.top.value;
|
||||
f32 rPad = (base->padding.right.type == DJUI_SVT_RELATIVE) ? parentComp->width * base->padding.right.value : base->padding.right.value;
|
||||
f32 bPad = (base->padding.bottom.type == DJUI_SVT_RELATIVE) ? parentComp->height * base->padding.bottom.value : base->padding.bottom.value;
|
||||
f32 lPad = (base->padding.left.type == DJUI_SVT_RELATIVE) ? parentComp->width * base->padding.left.value : base->padding.left.value;
|
||||
|
||||
comp->x += lPad;
|
||||
comp->y += tPad;
|
||||
comp->height -= tPad + bPad;
|
||||
comp->width -= lPad + rPad;
|
||||
}
|
||||
|
||||
void djui_base_compute(struct DjuiBase* base) {
|
||||
struct DjuiBase* parent = base->parent;
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
|
||||
f32 x = (base->x.type == DJUI_SVT_RELATIVE) ? parent->comp.width * base->x.value : base->x.value;
|
||||
f32 y = (base->y.type == DJUI_SVT_RELATIVE) ? parent->comp.height * base->y.value : base->y.value;
|
||||
|
||||
f32 width = (base->width.type == DJUI_SVT_RELATIVE) ? parent->comp.width * base->width.value : base->width.value;
|
||||
f32 height = (base->height.type == DJUI_SVT_RELATIVE) ? parent->comp.height * base->height.value : base->height.value;
|
||||
|
||||
width = (base->width.type == DJUI_SVT_ASPECT_RATIO) ? height * base->width.value : width;
|
||||
height = (base->height.type == DJUI_SVT_ASPECT_RATIO) ? width * base->height.value : height;
|
||||
|
||||
// horizontal alignment
|
||||
if (base->hAlign == DJUI_HALIGN_CENTER) {
|
||||
x += (parent->comp.width - width) / 2.0f;
|
||||
} else if (base->hAlign == DJUI_HALIGN_RIGHT) {
|
||||
x = parent->comp.width - width - x;
|
||||
}
|
||||
|
||||
// vertical alignment
|
||||
if (base->vAlign == DJUI_VALIGN_CENTER) {
|
||||
y += (parent->comp.height - height) / 2.0f;
|
||||
} else if (base->vAlign == DJUI_VALIGN_BOTTOM) {
|
||||
y = parent->comp.height - height - y;
|
||||
}
|
||||
|
||||
// offset comp on parent's location
|
||||
if (base->parent != NULL) {
|
||||
x += parent->comp.x;
|
||||
y += parent->comp.y;
|
||||
}
|
||||
|
||||
// set computed values
|
||||
comp->x = x;
|
||||
comp->y = y;
|
||||
comp->width = width;
|
||||
comp->height = height;
|
||||
|
||||
struct DjuiBaseRect* elem = &base->elem;
|
||||
elem->x = x;
|
||||
elem->y = y;
|
||||
elem->width = width;
|
||||
elem->height = height;
|
||||
|
||||
djui_base_clip(base);
|
||||
}
|
||||
|
||||
static void djui_base_add_child(struct DjuiBase* parent, struct DjuiBase* base) {
|
||||
if (parent == NULL) { return; }
|
||||
|
||||
// allocate linked list node
|
||||
struct DjuiBaseChild* baseChild = malloc(sizeof(struct DjuiBaseChild));
|
||||
baseChild->base = base;
|
||||
baseChild->next = NULL;
|
||||
|
||||
// add it to the head
|
||||
if (parent->child == NULL || parent->addChildrenToHead) {
|
||||
baseChild->next = parent->child;
|
||||
parent->child = baseChild;
|
||||
return;
|
||||
}
|
||||
|
||||
// add it to the tail
|
||||
struct DjuiBaseChild* parentChild = parent->child;
|
||||
while (parentChild != NULL) {
|
||||
if (parentChild->next == NULL) {
|
||||
parentChild->next = baseChild;
|
||||
break;
|
||||
}
|
||||
parentChild = parentChild->next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////
|
||||
// render //
|
||||
////////////
|
||||
|
||||
static f32 djui_base_render_border_piece(struct DjuiBase* base, f32 x1, f32 y1, f32 x2, f32 y2, bool isXBorder) {
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
|
||||
x1 = fmax(x1, clip->x);
|
||||
y1 = fmax(y1, clip->y);
|
||||
x2 = fmin(x2, clip->x + clip->width);
|
||||
y2 = fmin(y2, clip->y + clip->height);
|
||||
|
||||
if (x2 <= x1) { return 0; }
|
||||
if (y2 <= y1) { return 0; }
|
||||
|
||||
// translate position
|
||||
f32 translatedX = x1;
|
||||
f32 translatedY = y1;
|
||||
djui_gfx_position_translate(&translatedX, &translatedY);
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
|
||||
|
||||
// translate size
|
||||
f32 translatedWidth = x2 - x1;
|
||||
f32 translatedHeight = y2 - y1;
|
||||
djui_gfx_scale_translate(&translatedWidth, &translatedHeight);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedWidth, translatedHeight, 1.0f);
|
||||
|
||||
// render
|
||||
gDPSetEnvColor(gDisplayListHead++, base->borderColor.r, base->borderColor.g, base->borderColor.b, base->borderColor.a);
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
|
||||
return isXBorder ? fmax(x2 - x1, 0) : fmax(y2 - y1, 0);
|
||||
}
|
||||
|
||||
static void djui_base_render_border(struct DjuiBase* base) {
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
struct DjuiBaseRect savedComp = base->comp;
|
||||
|
||||
f32 xBorderWidth = (base->borderWidth.type == DJUI_SVT_RELATIVE) ? (savedComp.width * base->borderWidth.value) : base->borderWidth.value;
|
||||
f32 yBorderWidth = (base->borderWidth.type == DJUI_SVT_RELATIVE) ? (savedComp.height * base->borderWidth.value) : base->borderWidth.value;
|
||||
|
||||
xBorderWidth = fmin(xBorderWidth, savedComp.width / 2.0f);
|
||||
yBorderWidth = fmin(yBorderWidth, savedComp.height / 2.0f);
|
||||
|
||||
comp->x += base->borderWidth.value;
|
||||
comp->y += base->borderWidth.value;
|
||||
comp->width -= base->borderWidth.value * 2.0f;
|
||||
comp->height -= base->borderWidth.value * 2.0f;
|
||||
|
||||
f32 addClip = 0;
|
||||
|
||||
addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y, savedComp.x + savedComp.width, savedComp.y + yBorderWidth, false);
|
||||
clip->y += addClip;
|
||||
clip->height -= addClip;
|
||||
|
||||
addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y + savedComp.height - yBorderWidth, savedComp.x + savedComp.width, savedComp.y + savedComp.height, false);
|
||||
clip->height -= addClip;
|
||||
|
||||
addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y, savedComp.x + xBorderWidth, savedComp.y + savedComp.height, true);
|
||||
clip->x += addClip;
|
||||
clip->width -= addClip;
|
||||
|
||||
addClip = djui_base_render_border_piece(base, savedComp.x + savedComp.width - xBorderWidth, savedComp.y, savedComp.x + savedComp.width, savedComp.y + savedComp.height, true);
|
||||
clip->width -= addClip;
|
||||
}
|
||||
|
||||
////////////
|
||||
// events //
|
||||
////////////
|
||||
|
||||
bool djui_base_render(struct DjuiBase* base) {
|
||||
if (!base->visible) { return false; }
|
||||
|
||||
if (base->on_render_pre != NULL) {
|
||||
bool skipRender = false;
|
||||
base->on_render_pre(base, &skipRender);
|
||||
if (skipRender) { return false; }
|
||||
}
|
||||
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
|
||||
djui_base_compute(base);
|
||||
if (comp->width <= 0) { return false; }
|
||||
if (comp->height <= 0) { return false; }
|
||||
if (clip->width <= 0) { return false; }
|
||||
if (clip->height <= 0) { return false; }
|
||||
|
||||
if (base->borderWidth.value > 0 && base->borderColor.a > 0) {
|
||||
djui_base_render_border(base);
|
||||
}
|
||||
|
||||
if (clip->width < 0 || clip->height <= 0) { return false; }
|
||||
|
||||
if (base->render != NULL) {
|
||||
base->render(base);
|
||||
}
|
||||
|
||||
djui_base_add_padding(base);
|
||||
|
||||
// render all children
|
||||
struct DjuiBaseChild* child = base->child;
|
||||
bool hasChildRendered = false;
|
||||
while (child != NULL) {
|
||||
struct DjuiBaseChild* nextChild = child->next;
|
||||
bool childRendered = djui_base_render(child->base);
|
||||
if (base->abandonAfterChildRenderFail && !childRendered && hasChildRendered) { break; }
|
||||
hasChildRendered = hasChildRendered || childRendered;
|
||||
if (base->on_child_render != NULL) {
|
||||
base->on_child_render(base, child->base);
|
||||
}
|
||||
|
||||
child = nextChild;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void djui_base_destroy(struct DjuiBase* base) {
|
||||
// remove myself from parent's linked list
|
||||
if (base->parent != NULL) {
|
||||
struct DjuiBaseChild* child = base->parent->child;
|
||||
struct DjuiBaseChild* lastChild = NULL;
|
||||
struct DjuiBaseChild* nextChild = NULL;
|
||||
while (child != NULL) {
|
||||
nextChild = child->next;
|
||||
|
||||
if (child->base == base) {
|
||||
// adjust linked list
|
||||
if (lastChild == NULL) {
|
||||
base->parent->child = nextChild;
|
||||
} else {
|
||||
lastChild->next = nextChild;
|
||||
}
|
||||
// deallocate child node
|
||||
free(child);
|
||||
base->parent = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// iterate
|
||||
lastChild = child;
|
||||
child = nextChild;
|
||||
}
|
||||
}
|
||||
|
||||
// destroy all children and our linked list
|
||||
struct DjuiBaseChild* child = base->child;
|
||||
while (child != NULL) {
|
||||
struct DjuiBaseChild* nextChild = child->next;
|
||||
child->base->parent = NULL;
|
||||
djui_base_destroy(child->base);
|
||||
free(child);
|
||||
child = nextChild;
|
||||
}
|
||||
|
||||
// deallocate interactable
|
||||
if (base->interactable != NULL) {
|
||||
free(base->interactable);
|
||||
base->interactable = NULL;
|
||||
}
|
||||
|
||||
// destroy this
|
||||
base->destroy(base);
|
||||
}
|
||||
|
||||
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, void(*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*)) {
|
||||
memset(base, 0, sizeof(struct DjuiBase));
|
||||
base->parent = parent;
|
||||
djui_base_set_visible(base, true);
|
||||
djui_base_set_enabled(base, true);
|
||||
djui_base_set_size(base, 64, 64);
|
||||
djui_base_set_color(base, 255, 255, 255, 255);
|
||||
base->get_cursor_hover_location = djui_base_get_cursor_hover_location;
|
||||
base->render = render;
|
||||
base->destroy = destroy;
|
||||
djui_base_add_child(parent, base);
|
||||
}
|
74
src/pc/djui/djui_base.h
Normal file
74
src/pc/djui/djui_base.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiBaseRect {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 width;
|
||||
f32 height;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiBaseChild {
|
||||
struct DjuiBase* base;
|
||||
struct DjuiBaseChild* next;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiBasePadding {
|
||||
struct DjuiScreenValue top;
|
||||
struct DjuiScreenValue right;
|
||||
struct DjuiScreenValue bottom;
|
||||
struct DjuiScreenValue left;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiBase {
|
||||
struct DjuiBase* parent;
|
||||
struct DjuiBaseChild* child;
|
||||
bool visible;
|
||||
bool enabled;
|
||||
struct DjuiScreenValue x;
|
||||
struct DjuiScreenValue y;
|
||||
struct DjuiScreenValue width;
|
||||
struct DjuiScreenValue height;
|
||||
struct DjuiColor color;
|
||||
struct DjuiScreenValue borderWidth;
|
||||
struct DjuiColor borderColor;
|
||||
struct DjuiBasePadding padding;
|
||||
enum DjuiHAlign hAlign;
|
||||
enum DjuiVAlign vAlign;
|
||||
struct DjuiBaseRect elem;
|
||||
struct DjuiBaseRect comp;
|
||||
struct DjuiBaseRect clip;
|
||||
struct DjuiInteractable* interactable;
|
||||
bool addChildrenToHead;
|
||||
bool abandonAfterChildRenderFail;
|
||||
s32 tag;
|
||||
void (*get_cursor_hover_location)(struct DjuiBase*, f32* x, f32* y);
|
||||
void (*on_child_render)(struct DjuiBase*, struct DjuiBase*);
|
||||
void (*on_render_pre)(struct DjuiBase*, bool*);
|
||||
void (*render)(struct DjuiBase*);
|
||||
void (*destroy)(struct DjuiBase*);
|
||||
};
|
||||
|
||||
void djui_base_set_visible(struct DjuiBase* base, bool visible);
|
||||
void djui_base_set_enabled(struct DjuiBase* base, bool enabled);
|
||||
void djui_base_set_location(struct DjuiBase* base, f32 x, f32 y);
|
||||
void djui_base_set_location_type(struct DjuiBase* base, enum DjuiScreenValueType xType, enum DjuiScreenValueType yType);
|
||||
void djui_base_set_size(struct DjuiBase* base, f32 width, f32 height);
|
||||
void djui_base_set_size_type(struct DjuiBase* base, enum DjuiScreenValueType widthType, enum DjuiScreenValueType heightType);
|
||||
void djui_base_set_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a);
|
||||
void djui_base_set_border_width(struct DjuiBase* base, f32 width);
|
||||
void djui_base_set_border_width_type(struct DjuiBase* base, enum DjuiScreenValueType widthType);
|
||||
void djui_base_set_border_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a);
|
||||
void djui_base_set_padding(struct DjuiBase* base, f32 top, f32 right, f32 bottom, f32 left);
|
||||
void djui_base_set_padding_type(struct DjuiBase* base, enum DjuiScreenValueType topType, enum DjuiScreenValueType rightType, enum DjuiScreenValueType bottomType, enum DjuiScreenValueType leftType);
|
||||
void djui_base_set_alignment(struct DjuiBase* base, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign);
|
||||
|
||||
void djui_base_compute(struct DjuiBase* base);
|
||||
|
||||
bool djui_base_render(struct DjuiBase* base);
|
||||
void djui_base_destroy(struct DjuiBase* base);
|
||||
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, void (*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*));
|
98
src/pc/djui/djui_bind.c
Normal file
98
src/pc/djui/djui_bind.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "djui.h"
|
||||
#include "src/pc/controller/controller_api.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
#define VK_ESCAPE 1
|
||||
|
||||
static void djui_bind_button_on_click(struct DjuiBase* caller) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)caller;
|
||||
djui_text_set_text(button->text, "...");
|
||||
controller_get_raw_key(); // consume lingering controller button press
|
||||
djui_interactable_set_binding(caller);
|
||||
}
|
||||
|
||||
static void djui_bind_button_on_bind(struct DjuiBase* caller) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)caller;
|
||||
struct DjuiBind* bind = (struct DjuiBind*) caller->parent->parent;
|
||||
|
||||
// get key
|
||||
u32 key = controller_get_raw_key();
|
||||
if (key == VK_INVALID) { return; }
|
||||
|
||||
// invalidate key
|
||||
if (key == VK_ESCAPE) { key = VK_INVALID; }
|
||||
for (int i = 0; i < MAX_BINDS; i++) {
|
||||
if (i == button->base.tag) { continue; }
|
||||
if (bind->configKey[i] == key) {
|
||||
key = VK_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
// set key
|
||||
bind->configKey[button->base.tag] = key;
|
||||
char keyStr[5] = { 0 };
|
||||
if (key != VK_INVALID) {
|
||||
sprintf(keyStr, "%04x", key);
|
||||
}
|
||||
djui_text_set_text(button->text, keyStr);
|
||||
djui_interactable_set_binding(NULL);
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
}
|
||||
|
||||
static void djui_bind_destroy(struct DjuiBase* base) {
|
||||
struct DjuiBind* bind = (struct DjuiBind*)base;
|
||||
free(bind);
|
||||
}
|
||||
|
||||
struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message, unsigned int configKey[]) {
|
||||
struct DjuiBind* bind = malloc(sizeof(struct DjuiBind));
|
||||
struct DjuiBase* base = &bind->base;
|
||||
|
||||
bind->configKey = configKey;
|
||||
|
||||
djui_base_init(parent, base, NULL, djui_bind_destroy);
|
||||
djui_base_set_size_type(&bind->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&bind->base, 1.0f, 32);
|
||||
djui_base_set_color(&bind->base, 0, 0, 0, 0);
|
||||
|
||||
struct DjuiText* text = djui_text_create(&bind->base, message);
|
||||
djui_base_set_alignment(&text->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&text->base, 0.3f, 1.0f);
|
||||
djui_text_set_alignment(text, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
djui_text_set_drop_shadow(text, 120, 120, 120, 64);
|
||||
djui_base_set_color(&text->base, 200, 200, 200, 255);
|
||||
bind->text = text;
|
||||
|
||||
struct DjuiRect* rect = djui_rect_create(&bind->base);
|
||||
djui_base_set_alignment(&rect->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&rect->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&rect->base, 0.7f, 1.0f);
|
||||
djui_base_set_color(&rect->base, 0, 0, 0, 0);
|
||||
bind->rect = rect;
|
||||
|
||||
for (int i = 0; i < MAX_BINDS; i++) {
|
||||
unsigned int key = configKey[i];
|
||||
char keyStr[5] = { 0 };
|
||||
if (key != VK_INVALID) {
|
||||
sprintf(keyStr, "%04x", key);
|
||||
}
|
||||
struct DjuiButton* button = djui_button_create(&rect->base, keyStr);
|
||||
djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&button->base, 0.33f, 1.0f);
|
||||
button->base.tag = i;
|
||||
djui_interactable_hook_click(&button->base, djui_bind_button_on_click);
|
||||
djui_interactable_hook_bind(&button->base, djui_bind_button_on_bind);
|
||||
|
||||
enum DjuiHAlign hAlign = DJUI_HALIGN_LEFT;
|
||||
if (i > 0) { hAlign = (i == 1) ? DJUI_HALIGN_CENTER : DJUI_HALIGN_RIGHT; }
|
||||
djui_base_set_alignment(&button->base, hAlign, DJUI_VALIGN_CENTER);
|
||||
|
||||
bind->buttons[i] = button;
|
||||
}
|
||||
|
||||
return bind;
|
||||
}
|
14
src/pc/djui/djui_bind.h
Normal file
14
src/pc/djui/djui_bind.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiBind {
|
||||
struct DjuiBase base;
|
||||
struct DjuiText* text;
|
||||
struct DjuiRect* rect;
|
||||
struct DjuiButton* buttons[MAX_BINDS];
|
||||
unsigned int* configKey;
|
||||
};
|
||||
|
||||
struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message, unsigned int configKey[]);
|
72
src/pc/djui/djui_button.c
Normal file
72
src/pc/djui/djui_button.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "djui.h"
|
||||
|
||||
static void djui_button_set_default_style(struct DjuiBase* base) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)base;
|
||||
u8 borderBrightness = button->style ? 100 : 150;
|
||||
u8 rectBrightness = button->style ? 150 : 222;
|
||||
djui_base_set_border_color(base, borderBrightness, borderBrightness, borderBrightness, 255);
|
||||
djui_base_set_color(&button->rect->base, rectBrightness, rectBrightness, rectBrightness, 255);
|
||||
djui_base_set_location(&button->text->base, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void djui_button_set_style(struct DjuiButton* button, u8 style) {
|
||||
button->style = style;
|
||||
djui_button_set_default_style(&button->base);
|
||||
}
|
||||
|
||||
static void djui_button_on_hover(struct DjuiBase* base) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)base;
|
||||
djui_base_set_border_color(base, 0, 120, 215, 255);
|
||||
djui_base_set_color(&button->rect->base, 229, 241, 251, 255);
|
||||
djui_base_set_location(&button->text->base, -0.5f, -1.0f);
|
||||
}
|
||||
|
||||
static void djui_button_on_hover_end(struct DjuiBase* base) {
|
||||
djui_button_set_default_style(base);
|
||||
}
|
||||
|
||||
static void djui_button_on_cursor_down_begin(struct DjuiBase* base, bool inputCursor) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)base;
|
||||
djui_base_set_border_color(base, 0, 84, 153, 255);
|
||||
djui_base_set_color(&button->rect->base, 204, 228, 247, 255);
|
||||
djui_base_set_location(&button->text->base, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
static void djui_button_on_cursor_down_end(struct DjuiBase* base) {
|
||||
djui_button_set_default_style(base);
|
||||
}
|
||||
|
||||
static void djui_button_destroy(struct DjuiBase* base) {
|
||||
struct DjuiButton* button = (struct DjuiButton*)base;
|
||||
free(button);
|
||||
}
|
||||
|
||||
struct DjuiButton* djui_button_create(struct DjuiBase* parent, const char* message) {
|
||||
struct DjuiButton* button = malloc(sizeof(struct DjuiButton));
|
||||
struct DjuiBase* base = &button->base;
|
||||
|
||||
djui_base_init(parent, base, NULL, djui_button_destroy);
|
||||
djui_base_set_size(base, 200, 64);
|
||||
djui_base_set_border_width(base, 2);
|
||||
djui_interactable_create(base);
|
||||
djui_interactable_hook_hover(base, djui_button_on_hover, djui_button_on_hover_end);
|
||||
djui_interactable_hook_cursor_down(base, djui_button_on_cursor_down_begin, NULL, djui_button_on_cursor_down_end);
|
||||
button->style = 0;
|
||||
|
||||
struct DjuiRect* rect = djui_rect_create(&button->base);
|
||||
djui_base_set_size_type(&rect->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&rect->base, 1.0f, 1.0f);
|
||||
button->rect = rect;
|
||||
|
||||
struct DjuiText* text = djui_text_create(&rect->base, message);
|
||||
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&text->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&text->base, 11, 11, 11, 255);
|
||||
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_text_set_drop_shadow(text, 0, 0, 0, 64);
|
||||
button->text = text;
|
||||
|
||||
djui_button_set_default_style(base);
|
||||
|
||||
return button;
|
||||
}
|
14
src/pc/djui/djui_button.h
Normal file
14
src/pc/djui/djui_button.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiButton {
|
||||
struct DjuiBase base;
|
||||
struct DjuiRect* rect;
|
||||
struct DjuiText* text;
|
||||
u8 style;
|
||||
};
|
||||
|
||||
void djui_button_set_style(struct DjuiButton* button, u8 style);
|
||||
|
||||
struct DjuiButton* djui_button_create(struct DjuiBase* parent, const char* message);
|
135
src/pc/djui/djui_chat_box.c
Normal file
135
src/pc/djui/djui_chat_box.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pc/network/network.h"
|
||||
#include "djui.h"
|
||||
|
||||
struct DjuiChatBox* gDjuiChatBox = NULL;
|
||||
bool gDjuiChatBoxFocus = false;
|
||||
|
||||
void djui_chat_box_render(struct DjuiBase* base) {
|
||||
struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base;
|
||||
struct DjuiBase* ccBase = &chatBox->chatContainer->base;
|
||||
djui_base_set_size(ccBase, 1.0f, chatBox->base.comp.height - 32 - 8);
|
||||
}
|
||||
|
||||
static void djui_chat_box_destroy(struct DjuiBase* base) {
|
||||
struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base;
|
||||
free(chatBox);
|
||||
}
|
||||
|
||||
static void djui_chat_box_set_focus_style(void) {
|
||||
djui_base_set_visible(&gDjuiChatBox->chatInput->base, gDjuiChatBoxFocus);
|
||||
if (gDjuiChatBoxFocus) {
|
||||
djui_interactable_set_input_focus(&gDjuiChatBox->chatInput->base);
|
||||
}
|
||||
|
||||
djui_base_set_color(&gDjuiChatBox->chatFlow->base, 0, 0, 0, gDjuiChatBoxFocus ? 128 : 0);
|
||||
}
|
||||
|
||||
static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) {
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
|
||||
if (strlen(chatInput->buffer) != 0) {
|
||||
djui_chat_message_create_from(gNetworkPlayerLocal->globalIndex, chatInput->buffer);
|
||||
network_send_chat(chatInput->buffer, gNetworkPlayerLocal->globalIndex);
|
||||
}
|
||||
|
||||
djui_inputbox_set_text(chatInput, "");
|
||||
djui_inputbox_select_all(chatInput);
|
||||
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
|
||||
}
|
||||
|
||||
static void djui_chat_box_input_escape(struct DjuiInputbox* chatInput) {
|
||||
djui_inputbox_set_text(chatInput, "");
|
||||
djui_inputbox_select_all(chatInput);
|
||||
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
|
||||
}
|
||||
|
||||
static bool djui_chat_box_input_on_key_down(struct DjuiBase* base, int scancode) {
|
||||
if (gDjuiChatBox == NULL) { return false; }
|
||||
f32 yMax = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
|
||||
|
||||
f32* yValue = &gDjuiChatBox->chatFlow->base.y.value;
|
||||
bool canScrollUp = (*yValue > yMax);
|
||||
bool canScrollDown = (*yValue < 0);
|
||||
f32 pageAmount = gDjuiChatBox->chatFlow->base.elem.height / 3.0f;
|
||||
|
||||
switch (scancode) {
|
||||
case SCANCODE_UP:
|
||||
gDjuiChatBox->scrolling = true;
|
||||
if (canScrollUp) { *yValue = fmax(*yValue - 15, yMax); }
|
||||
return true;
|
||||
case SCANCODE_DOWN:
|
||||
gDjuiChatBox->scrolling = true;
|
||||
if (canScrollDown) { *yValue = fmin(*yValue + 15, 0); }
|
||||
return true;
|
||||
case SCANCODE_PAGE_UP:
|
||||
gDjuiChatBox->scrolling = true;
|
||||
if (canScrollUp) { *yValue = fmax(*yValue - pageAmount, yMax); }
|
||||
return true;
|
||||
case SCANCODE_PAGE_DOWN:
|
||||
gDjuiChatBox->scrolling = true;
|
||||
if (canScrollDown) { *yValue = fmin(*yValue + pageAmount, 0); }
|
||||
return true;
|
||||
case SCANCODE_ENTER: djui_chat_box_input_enter(gDjuiChatBox->chatInput); return true;
|
||||
case SCANCODE_ESCAPE: djui_chat_box_input_escape(gDjuiChatBox->chatInput); return true;
|
||||
default: return djui_inputbox_on_key_down(base, scancode);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_chat_box_toggle(void) {
|
||||
if (gDjuiChatBox == NULL) { return; }
|
||||
gDjuiChatBoxFocus = !gDjuiChatBoxFocus;
|
||||
djui_chat_box_set_focus_style();
|
||||
gDjuiChatBox->scrolling = false;
|
||||
gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
|
||||
}
|
||||
|
||||
struct DjuiChatBox* djui_chat_box_create(void) {
|
||||
if (gDjuiChatBox != NULL) {
|
||||
djui_base_destroy(&gDjuiChatBox->base);
|
||||
gDjuiChatBox = NULL;
|
||||
}
|
||||
|
||||
struct DjuiChatBox* chatBox = malloc(sizeof(struct DjuiChatBox));
|
||||
struct DjuiBase* base = &chatBox->base;
|
||||
|
||||
djui_base_init(&gDjuiRoot->base, base, djui_chat_box_render, djui_chat_box_destroy);
|
||||
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(base, 600, 1.0f);
|
||||
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_color(base, 0, 0, 0, 0);
|
||||
djui_base_set_padding(base, 0, 8, 8, 8);
|
||||
|
||||
struct DjuiRect* chatContainer = djui_rect_create(base);
|
||||
struct DjuiBase* ccBase = &chatContainer->base;
|
||||
djui_base_set_size_type(ccBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(ccBase, 1.0f, 0);
|
||||
djui_base_set_color(ccBase, 0, 0, 0, 0);
|
||||
chatBox->chatContainer = chatContainer;
|
||||
|
||||
struct DjuiFlowLayout* chatFlow = djui_flow_layout_create(ccBase);
|
||||
struct DjuiBase* cfBase = &chatFlow->base;
|
||||
djui_base_set_location(cfBase, 0, 0);
|
||||
djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(cfBase, 1.0f, 2);
|
||||
djui_base_set_color(cfBase, 0, 0, 0, 128);
|
||||
djui_base_set_padding(cfBase, 2, 2, 2, 2);
|
||||
djui_flow_layout_set_margin(chatFlow, 2);
|
||||
djui_flow_layout_set_flow_direction(chatFlow, DJUI_FLOW_DIR_UP);
|
||||
cfBase->addChildrenToHead = true;
|
||||
cfBase->abandonAfterChildRenderFail = true;
|
||||
chatBox->chatFlow = chatFlow;
|
||||
|
||||
struct DjuiInputbox* chatInput = djui_inputbox_create(base, 200);
|
||||
struct DjuiBase* ciBase = &chatInput->base;
|
||||
djui_base_set_size_type(ciBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(ciBase, 1.0f, 32);
|
||||
djui_base_set_alignment(ciBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
djui_interactable_hook_key(&chatInput->base, djui_chat_box_input_on_key_down, djui_inputbox_on_key_up);
|
||||
chatBox->chatInput = chatInput;
|
||||
|
||||
gDjuiChatBox = chatBox;
|
||||
djui_chat_box_set_focus_style();
|
||||
return chatBox;
|
||||
}
|
17
src/pc/djui/djui_chat_box.h
Normal file
17
src/pc/djui/djui_chat_box.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiChatBox {
|
||||
struct DjuiBase base;
|
||||
struct DjuiRect* chatContainer;
|
||||
struct DjuiFlowLayout* chatFlow;
|
||||
struct DjuiInputbox* chatInput;
|
||||
bool scrolling;
|
||||
};
|
||||
|
||||
extern struct DjuiChatBox* gDjuiChatBox;
|
||||
extern bool gDjuiChatBoxFocus;
|
||||
|
||||
void djui_chat_box_toggle(void);
|
||||
struct DjuiChatBox* djui_chat_box_create(void);
|
91
src/pc/djui/djui_chat_message.c
Normal file
91
src/pc/djui/djui_chat_message.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <stdio.h>
|
||||
#include "pc/network/network.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
#include "game/mario_misc.h"
|
||||
#include "djui.h"
|
||||
|
||||
#define DJUI_CHAT_LIFE_TIME 10.0f
|
||||
|
||||
static void djui_chat_message_render(struct DjuiBase* base) {
|
||||
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
|
||||
struct DjuiBase* ctBase = &chatMessage->message->base;
|
||||
|
||||
f32 seconds = (clock() - chatMessage->createTime) / (f32)CLOCKS_PER_SEC;
|
||||
f32 f = 1.0f;
|
||||
if (seconds >= (DJUI_CHAT_LIFE_TIME - 1)) {
|
||||
f = fmax(1.0f - (seconds - (DJUI_CHAT_LIFE_TIME - 1)), 0.0f);
|
||||
f *= f;
|
||||
f *= f;
|
||||
}
|
||||
|
||||
if (gDjuiChatBoxFocus) {
|
||||
djui_base_set_color(base, 0, 0, 0, 64);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255);
|
||||
djui_text_set_drop_shadow(chatMessage->message, 0, 0, 0, 200);
|
||||
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, 1.0f, chatMessage->base.height.value);
|
||||
} else {
|
||||
djui_base_set_color(base, 0, 0, 0, 150 * f);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255 * f);
|
||||
djui_text_set_drop_shadow(chatMessage->message, 0, 0, 0, 200 * f);
|
||||
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, chatMessage->messageWidth, chatMessage->base.height.value);
|
||||
}
|
||||
|
||||
djui_rect_render(base);
|
||||
}
|
||||
|
||||
static void djui_chat_message_destroy(struct DjuiBase* base) {
|
||||
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
|
||||
free(chatMessage);
|
||||
}
|
||||
|
||||
struct DjuiChatMessage* djui_chat_message_create_from(u8 globalIndex, char* message) {
|
||||
u8* rgb = get_player_color(globalIndex, 0);
|
||||
u8 rgb2[3] = { 0 };
|
||||
for (int i = 0; i < 3; i++) { rgb2[i] = fmin((f32)rgb[i] * 1.3f + 32.0f, 255); }
|
||||
char chatMsg[256] = { 0 };
|
||||
snprintf(chatMsg, 256, "\\#%02x%02x%02x\\%s:\\#dcdcdc\\ %s", rgb2[0], rgb2[1], rgb2[2], "Player", message);
|
||||
play_sound((globalIndex == gNetworkPlayerLocal->globalIndex) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
|
||||
return djui_chat_message_create(chatMsg);
|
||||
}
|
||||
|
||||
struct DjuiChatMessage* djui_chat_message_create(char* message) {
|
||||
struct DjuiChatMessage* chatMessage = malloc(sizeof(struct DjuiChatMessage));
|
||||
struct DjuiBase* base = &chatMessage->base;
|
||||
djui_base_init(&gDjuiChatBox->chatFlow->base, base, djui_chat_message_render, djui_chat_message_destroy);
|
||||
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, 1.0f, 0);
|
||||
djui_base_set_color(base, 0, 0, 0, 64);
|
||||
djui_base_set_padding(base, 2, 4, 2, 4);
|
||||
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
|
||||
f32 maxTextWidth = gDjuiChatBox->base.width.value - gDjuiChatBox->base.padding.left.value - gDjuiChatBox->base.padding.right.value - base->padding.left.value - base->padding.right.value;
|
||||
|
||||
struct DjuiText* chatText = djui_text_create(base, message);
|
||||
struct DjuiBase* ctBase = &chatText->base;
|
||||
djui_base_set_size_type(ctBase, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(ctBase, maxTextWidth, 1.0f);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255);
|
||||
djui_base_set_location(ctBase, 0, 0);
|
||||
djui_text_set_alignment(chatText, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_text_set_drop_shadow(chatText, 0, 0, 0, 200);
|
||||
chatMessage->message = chatText;
|
||||
chatMessage->createTime = clock();
|
||||
|
||||
// figure out chat message height
|
||||
chatText->base.comp.width = maxTextWidth;
|
||||
f32 messageHeight = djui_text_count_lines(chatText, 10) * (chatText->font->lineHeight * chatText->font->defaultFontScale) + 8;
|
||||
djui_base_set_size(base, 1.0f, messageHeight);
|
||||
gDjuiChatBox->chatFlow->base.height.value += messageHeight + gDjuiChatBox->chatFlow->margin.value;
|
||||
if (!gDjuiChatBox->scrolling) {
|
||||
gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
|
||||
}
|
||||
|
||||
// figure out chat message width
|
||||
f32 messageWidth = djui_text_find_width(chatText, 10);
|
||||
chatMessage->messageWidth = messageWidth + 8;
|
||||
|
||||
return chatMessage;
|
||||
}
|
14
src/pc/djui/djui_chat_message.h
Normal file
14
src/pc/djui/djui_chat_message.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include <time.h>
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiChatMessage {
|
||||
struct DjuiBase base;
|
||||
struct DjuiText* message;
|
||||
f32 messageWidth;
|
||||
clock_t createTime;
|
||||
};
|
||||
|
||||
struct DjuiChatMessage* djui_chat_message_create_from(u8 globalIndex, char* message);
|
||||
struct DjuiChatMessage* djui_chat_message_create(char* message);
|
91
src/pc/djui/djui_checkbox.c
Normal file
91
src/pc/djui/djui_checkbox.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include "djui.h"
|
||||
|
||||
static void djui_checkbox_set_default_style(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 173, 173, 173, 255);
|
||||
djui_base_set_color(&checkbox->rect->base, 0, 0, 0, 0);
|
||||
djui_base_set_color(&checkbox->text->base, 200, 200, 200, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, 200, 200, 200, 255);
|
||||
}
|
||||
|
||||
static void djui_checkbox_on_hover(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 0, 120, 215, 255);
|
||||
djui_base_set_color(&checkbox->text->base, 229, 241, 251, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, 229, 241, 251, 255);
|
||||
}
|
||||
|
||||
static void djui_checkbox_get_cursor_hover_location(struct DjuiBase* base, f32* x, f32* y) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
struct DjuiBase* rectBase = &checkbox->rect->base;
|
||||
*x = (rectBase->elem.x + rectBase->elem.width * 3.0f / 4.0f);
|
||||
*y = (rectBase->elem.y + rectBase->elem.height * 3.0f / 4.0f);
|
||||
}
|
||||
|
||||
static void djui_checkbox_on_hover_end(struct DjuiBase* base) {
|
||||
djui_checkbox_set_default_style(base);
|
||||
}
|
||||
|
||||
static void djui_checkbox_on_cursor_down_begin(struct DjuiBase* base, bool inputCursor) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 20, 170, 255, 255);
|
||||
djui_base_set_color(&checkbox->rect->base, 255, 255, 255, 32);
|
||||
djui_base_set_color(&checkbox->text->base, 229, 241, 251, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, 255, 255, 255, 255);
|
||||
*checkbox->value = !(*checkbox->value);
|
||||
djui_base_set_visible(&checkbox->rectValue->base, *checkbox->value);
|
||||
if (base != NULL && base->interactable != NULL && base->interactable->on_value_change != NULL) {
|
||||
base->interactable->on_value_change(base);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_checkbox_on_cursor_down_end(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_checkbox_set_default_style(base);
|
||||
}
|
||||
|
||||
static void djui_checkbox_destroy(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
free(checkbox);
|
||||
}
|
||||
|
||||
struct DjuiCheckbox* djui_checkbox_create(struct DjuiBase* parent, const char* message, bool* value) {
|
||||
struct DjuiCheckbox* checkbox = malloc(sizeof(struct DjuiCheckbox));
|
||||
struct DjuiBase* base = &checkbox->base;
|
||||
|
||||
checkbox->value = value;
|
||||
|
||||
djui_base_init(parent, base, NULL, djui_checkbox_destroy);
|
||||
djui_interactable_create(base);
|
||||
djui_interactable_hook_hover(base, djui_checkbox_on_hover, djui_checkbox_on_hover_end);
|
||||
djui_interactable_hook_cursor_down(base, djui_checkbox_on_cursor_down_begin, NULL, djui_checkbox_on_cursor_down_end);
|
||||
|
||||
struct DjuiText* text = djui_text_create(&checkbox->base, message);
|
||||
djui_base_set_alignment(&text->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&text->base, 1.0f, 1.0f);
|
||||
djui_text_set_alignment(text, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
djui_text_set_drop_shadow(text, 120, 120, 120, 64);
|
||||
checkbox->text = text;
|
||||
|
||||
struct DjuiRect* rect = djui_rect_create(&checkbox->base);
|
||||
djui_base_set_alignment(&rect->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&rect->base, DJUI_SVT_ASPECT_RATIO, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&rect->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&rect->base, 0, 0, 0, 0);
|
||||
djui_base_set_border_width(&rect->base, 2);
|
||||
checkbox->rect = rect;
|
||||
|
||||
struct DjuiRect* rectValue = djui_rect_create(&rect->base);
|
||||
djui_base_set_size_type(&rectValue->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rectValue->base, 16, 16);
|
||||
djui_base_set_alignment(&rectValue->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_visible(&rectValue->base, *value);
|
||||
checkbox->rectValue = rectValue;
|
||||
|
||||
djui_checkbox_set_default_style(base);
|
||||
|
||||
base->get_cursor_hover_location = djui_checkbox_get_cursor_hover_location;
|
||||
|
||||
return checkbox;
|
||||
}
|
13
src/pc/djui/djui_checkbox.h
Normal file
13
src/pc/djui/djui_checkbox.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiCheckbox {
|
||||
struct DjuiBase base;
|
||||
struct DjuiRect* rect;
|
||||
struct DjuiRect* rectValue;
|
||||
struct DjuiText* text;
|
||||
bool* value;
|
||||
};
|
||||
|
||||
struct DjuiCheckbox* djui_checkbox_create(struct DjuiBase* parent, const char* message, bool* value);
|
152
src/pc/djui/djui_cursor.c
Normal file
152
src/pc/djui/djui_cursor.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "djui.h"
|
||||
#include "pc/controller/controller_mouse.h"
|
||||
#include "pc/controller/controller_sdl.h"
|
||||
|
||||
extern ALIGNED8 u8 gd_texture_hand_open[];
|
||||
extern ALIGNED8 u8 gd_texture_hand_closed[];
|
||||
|
||||
static struct DjuiImage* sMouseCursor = NULL;
|
||||
|
||||
static bool sCursorMouseControlled = false;
|
||||
static struct DjuiBase* sInputControlledBase = NULL;
|
||||
|
||||
static f32 sSavedMouseX = 0;
|
||||
static f32 sSavedMouseY = 0;
|
||||
f32 gCursorX = 0;
|
||||
f32 gCursorY = 0;
|
||||
void djui_cursor_set_visible(bool visible) {
|
||||
if (sMouseCursor) {
|
||||
djui_base_set_visible(&sMouseCursor->base, visible);
|
||||
}
|
||||
sSavedMouseX = mouse_window_x;
|
||||
sSavedMouseY = mouse_window_y;
|
||||
}
|
||||
|
||||
bool djui_cursor_inside_base(struct DjuiBase* base) {
|
||||
struct DjuiBaseRect* clip = &base->elem;
|
||||
if (gCursorX < clip->x) { return false; }
|
||||
if (gCursorX > clip->x + clip->width) { return false; }
|
||||
if (gCursorY < clip->y) { return false; }
|
||||
if (gCursorY > clip->y + clip->height) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
static void djui_cursor_base_hover_location(struct DjuiBase* base, f32* x, f32* y) {
|
||||
base->get_cursor_hover_location(base, x, y);
|
||||
}
|
||||
|
||||
void djui_cursor_input_controlled_center(struct DjuiBase* base) {
|
||||
if (!sCursorMouseControlled) {
|
||||
sInputControlledBase = base;
|
||||
djui_cursor_set_visible(base != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static f32 djui_cursor_base_distance(struct DjuiBase* base, f32 xScale, f32 yScale) {
|
||||
f32 x, y;
|
||||
djui_cursor_base_hover_location(base, &x, &y);
|
||||
x -= gCursorX;
|
||||
y -= gCursorY;
|
||||
return sqrtf((x * x) * xScale + (y * y) * yScale);
|
||||
}
|
||||
|
||||
static void djui_cursor_move_check(s8 xDir, s8 yDir, struct DjuiBase** pick, struct DjuiBase* base) {
|
||||
if (!base->visible) { return; }
|
||||
if (!base->enabled) { return; }
|
||||
|
||||
if (base->interactable != NULL) {
|
||||
f32 x1, y1, x2, y2;
|
||||
x1 = base->elem.x;
|
||||
y1 = base->elem.y;
|
||||
x2 = base->elem.x + base->elem.width;
|
||||
y2 = base->elem.y + base->elem.height;
|
||||
bool xWithin = (gCursorX >= x1 && gCursorX <= x2) || sCursorMouseControlled;
|
||||
bool yWithin = (gCursorY >= y1 && gCursorY <= y2) || sCursorMouseControlled;
|
||||
|
||||
bool valid = false;
|
||||
if (yDir > 0 && gCursorY < y1 && xWithin) { valid = true; }
|
||||
if (yDir < 0 && gCursorY > y2 && xWithin) { valid = true; }
|
||||
if (xDir > 0 && gCursorX < x1 && yWithin) { valid = true; }
|
||||
if (xDir < 0 && gCursorX > x2 && yWithin) { valid = true; }
|
||||
|
||||
f32 xH, yH;
|
||||
djui_cursor_base_hover_location(base, &xH, &yH);
|
||||
if (valid) {
|
||||
if (*pick == NULL) {
|
||||
*pick = base;
|
||||
} else {
|
||||
f32 pickDist = djui_cursor_base_distance(*pick, xDir ? 1.0f : 2.0f, yDir ? 1.0f : 2.0f);
|
||||
f32 baseDist = djui_cursor_base_distance(base, xDir ? 1.0f : 2.0f, yDir ? 1.0f : 2.0f);
|
||||
if (baseDist < pickDist) { *pick = base; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check all children
|
||||
struct DjuiBaseChild* child = base->child;
|
||||
while (child != NULL) {
|
||||
djui_cursor_move_check(xDir, yDir, pick, child->base);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_cursor_move(s8 xDir, s8 yDir) {
|
||||
if (xDir == 0 && yDir == 0) { return; }
|
||||
|
||||
struct DjuiBase* pick = NULL;
|
||||
djui_cursor_move_check(xDir, yDir, &pick, &gDjuiRoot->base);
|
||||
if (pick != NULL) {
|
||||
sCursorMouseControlled = false;
|
||||
djui_cursor_input_controlled_center(pick);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_cursor_update(void) {
|
||||
#if defined(CAPI_SDL2) || defined(CAPI_SDL1)
|
||||
if (djui_interactable_is_binding()) { return; }
|
||||
if (sMouseCursor == NULL) { return; }
|
||||
if (!djui_panel_is_active()) { return; }
|
||||
|
||||
controller_sdl_read_mouse_window();
|
||||
|
||||
// check if mouse is in control again
|
||||
static bool sFirstUpdate = true;
|
||||
if (sFirstUpdate) {
|
||||
sFirstUpdate = false;
|
||||
sCursorMouseControlled = false;
|
||||
sSavedMouseX = mouse_window_x;
|
||||
sSavedMouseY = mouse_window_y;
|
||||
} else if (!sCursorMouseControlled || (sMouseCursor && !sMouseCursor->base.visible)) {
|
||||
f32 dist = sqrtf(powf(mouse_window_x - sSavedMouseX, 2) + powf(mouse_window_y - sSavedMouseY, 2));
|
||||
if (dist > 5) {
|
||||
sCursorMouseControlled = true;
|
||||
djui_cursor_set_visible(true);
|
||||
}
|
||||
}
|
||||
|
||||
// update mouse cursor
|
||||
if (sCursorMouseControlled) {
|
||||
gCursorX = mouse_window_x;
|
||||
gCursorY = mouse_window_y;
|
||||
} else if (sInputControlledBase != NULL) {
|
||||
djui_cursor_base_hover_location(sInputControlledBase, &gCursorX, &gCursorY);
|
||||
}
|
||||
|
||||
// set cursor position
|
||||
djui_base_set_location(&sMouseCursor->base, gCursorX - 13, gCursorY - 13);
|
||||
|
||||
// set cursor sprite
|
||||
if ((gInteractablePad.button & PAD_BUTTON_A) || (mouse_window_buttons & MOUSE_BUTTON_1)) {
|
||||
djui_image_set_image(sMouseCursor, gd_texture_hand_closed, 32, 32, 16);
|
||||
} else {
|
||||
djui_image_set_image(sMouseCursor, gd_texture_hand_open, 32, 32, 16);
|
||||
}
|
||||
#endif
|
||||
djui_base_render(&sMouseCursor->base);
|
||||
}
|
||||
|
||||
void djui_cursor_create(void) {
|
||||
sMouseCursor = djui_image_create(NULL, gd_texture_hand_open, 32, 32, 16);
|
||||
djui_base_set_location(&sMouseCursor->base, 0, 0);
|
||||
djui_base_set_size(&sMouseCursor->base, 64, 64);
|
||||
}
|
13
src/pc/djui/djui_cursor.h
Normal file
13
src/pc/djui/djui_cursor.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include "djui_base.h"
|
||||
|
||||
extern f32 gCursorX;
|
||||
extern f32 gCursorY;
|
||||
|
||||
void djui_cursor_set_visible(bool visible);
|
||||
bool djui_cursor_inside_base(struct DjuiBase* base);
|
||||
void djui_cursor_input_controlled_center(struct DjuiBase* base);
|
||||
void djui_cursor_move(s8 xDir, s8 yDir);
|
||||
void djui_cursor_update(void);
|
||||
void djui_cursor_create(void);
|
60
src/pc/djui/djui_flow_layout.c
Normal file
60
src/pc/djui/djui_flow_layout.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "djui.h"
|
||||
|
||||
////////////////
|
||||
// properties //
|
||||
////////////////
|
||||
|
||||
void djui_flow_layout_set_flow_direction(struct DjuiFlowLayout* layout, enum DjuiFlowDirection flowDirection) {
|
||||
layout->flowDirection = flowDirection;
|
||||
}
|
||||
|
||||
void djui_flow_layout_set_margin(struct DjuiFlowLayout* layout, f32 margin) {
|
||||
layout->margin.value = margin;
|
||||
}
|
||||
|
||||
void djui_flow_layout_set_margin_type(struct DjuiFlowLayout* layout, enum DjuiScreenValueType marginType) {
|
||||
layout->margin.type = marginType;
|
||||
}
|
||||
|
||||
////////////
|
||||
// events //
|
||||
////////////
|
||||
|
||||
static void djui_flow_layout_on_child_render(struct DjuiBase* base, struct DjuiBase* child) {
|
||||
struct DjuiFlowLayout* layout = (struct DjuiFlowLayout*)base;
|
||||
switch (layout->flowDirection) {
|
||||
case DJUI_FLOW_DIR_DOWN:
|
||||
base->comp.y += (child->elem.height + layout->margin.value);
|
||||
base->comp.height -= (child->elem.height + layout->margin.value);
|
||||
break;
|
||||
case DJUI_FLOW_DIR_UP:
|
||||
base->comp.height -= (child->elem.height + layout->margin.value);
|
||||
break;
|
||||
case DJUI_FLOW_DIR_RIGHT:
|
||||
base->comp.x += (child->elem.width + layout->margin.value);
|
||||
base->comp.width -= (child->elem.width + layout->margin.value);
|
||||
break;
|
||||
case DJUI_FLOW_DIR_LEFT:
|
||||
base->comp.width -= (child->elem.width + layout->margin.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_flow_layout_destroy(struct DjuiBase* base) {
|
||||
struct DjuiFlowLayout* layout = (struct DjuiFlowLayout*)base;
|
||||
free(layout);
|
||||
}
|
||||
|
||||
struct DjuiFlowLayout* djui_flow_layout_create(struct DjuiBase* parent) {
|
||||
struct DjuiFlowLayout* layout = malloc(sizeof(struct DjuiFlowLayout));
|
||||
struct DjuiBase* base = &layout->base;
|
||||
|
||||
djui_base_init(parent, base, djui_rect_render, djui_flow_layout_destroy);
|
||||
djui_base_set_size(base, 256, 512);
|
||||
|
||||
djui_flow_layout_set_flow_direction(layout, DJUI_FLOW_DIR_DOWN);
|
||||
djui_flow_layout_set_margin(layout, 8);
|
||||
|
||||
layout->base.on_child_render = djui_flow_layout_on_child_render;
|
||||
return layout;
|
||||
}
|
15
src/pc/djui/djui_flow_layout.h
Normal file
15
src/pc/djui/djui_flow_layout.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiFlowLayout {
|
||||
struct DjuiBase base;
|
||||
enum DjuiFlowDirection flowDirection;
|
||||
struct DjuiScreenValue margin;
|
||||
};
|
||||
|
||||
void djui_flow_layout_set_flow_direction(struct DjuiFlowLayout* layout, enum DjuiFlowDirection flowDirection);
|
||||
void djui_flow_layout_set_margin(struct DjuiFlowLayout* layout, f32 margin);
|
||||
void djui_flow_layout_set_margin_type(struct DjuiFlowLayout* layout, enum DjuiScreenValueType marginType);
|
||||
|
||||
struct DjuiFlowLayout* djui_flow_layout_create(struct DjuiBase* parent);
|
98
src/pc/djui/djui_font.c
Normal file
98
src/pc/djui/djui_font.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "djui.h"
|
||||
#include "game/segment2.h"
|
||||
|
||||
///////////////////////////////////
|
||||
// font 0 (built-in normal font) //
|
||||
///////////////////////////////////
|
||||
|
||||
static Vtx djui_font_normal_vertices[] = {
|
||||
{{{ 0, -1, 0}, 0, { 0, 256}, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 0.5f, -1, 0}, 0, { 0, 0}, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 0.5f, 0, 0}, 0, { 512, 0}, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 0, 0, 0}, 0, { 512, 256}, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
};
|
||||
|
||||
static const Gfx djui_font_normal_text_begin[] = {
|
||||
gsDPPipeSync(),
|
||||
gsSPClearGeometryMode(G_LIGHTING),
|
||||
gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
|
||||
gsDPSetEnvColor(255, 255, 255, 255),
|
||||
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
|
||||
gsDPSetTextureFilter(G_TF_POINT),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
static const Gfx djui_font_normal_text_settings[] = {
|
||||
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
|
||||
gsDPLoadSync(),
|
||||
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((16 * 8 + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1, CALC_DXT(16, G_IM_SIZ_4b_BYTES)),
|
||||
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD),
|
||||
gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC),
|
||||
gsSPVertex(djui_font_normal_vertices, 4, 0),
|
||||
gsSPExecuteDjui(G_TEXCLIP_DJUI),
|
||||
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
static void djui_font_normal_render_char(char c) {
|
||||
extern const u8* const font_normal_chars[];
|
||||
void* fontChar = (void*)font_normal_chars[c - '!'];
|
||||
if (fontChar == NULL) { fontChar = (void*)font_normal_chars[94]; }
|
||||
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, (void*)fontChar);
|
||||
gSPDisplayList(gDisplayListHead++, djui_font_normal_text_settings);
|
||||
}
|
||||
|
||||
static f32 djui_font_normal_char_width(char c) {
|
||||
if (c == ' ') { return 0.30f; }
|
||||
extern const f32 font_normal_widths[];
|
||||
return font_normal_widths[c - '!'];
|
||||
}
|
||||
|
||||
static const struct DjuiFont sDjuiFontNormal = {
|
||||
.charWidth = 0.5f,
|
||||
.charHeight = 1.0f,
|
||||
.lineHeight = 0.8125f,
|
||||
.defaultFontScale = 32.0f,
|
||||
.rotatedUV = true,
|
||||
.textBeginDisplayList = djui_font_normal_text_begin,
|
||||
.render_char = djui_font_normal_render_char,
|
||||
.char_width = djui_font_normal_char_width,
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// font 1 (custom title font) //
|
||||
////////////////////////////////
|
||||
|
||||
static void djui_font_title_render_char(char c) {
|
||||
extern const u8* const font_title_chars[];
|
||||
djui_gfx_render_texture(font_title_chars[c - '!'], 64, 64, 32);
|
||||
}
|
||||
|
||||
static f32 djui_font_title_char_width(char c) {
|
||||
if (c == ' ') { return 0.30f; }
|
||||
extern const f32 font_title_widths[];
|
||||
return font_title_widths[c - '!'];
|
||||
}
|
||||
|
||||
static const struct DjuiFont sDjuiFontTitle = {
|
||||
.charWidth = 1.0f,
|
||||
.charHeight = 0.9f,
|
||||
.lineHeight = 0.7f,
|
||||
.defaultFontScale = 64.0f,
|
||||
.rotatedUV = false,
|
||||
.textBeginDisplayList = NULL,
|
||||
.render_char = djui_font_title_render_char,
|
||||
.char_width = djui_font_title_char_width,
|
||||
};
|
||||
|
||||
///////////////
|
||||
// font list //
|
||||
///////////////
|
||||
|
||||
struct DjuiFont gDjuiFonts[] = {
|
||||
sDjuiFontNormal,
|
||||
sDjuiFontTitle,
|
||||
};
|
17
src/pc/djui/djui_font.h
Normal file
17
src/pc/djui/djui_font.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiFont {
|
||||
f32 charWidth;
|
||||
f32 charHeight;
|
||||
f32 lineHeight;
|
||||
f32 defaultFontScale;
|
||||
u8 textureBitSize;
|
||||
bool rotatedUV;
|
||||
const Gfx* textBeginDisplayList;
|
||||
void (*render_char)(char);
|
||||
f32 (*char_width)(char);
|
||||
};
|
||||
|
||||
extern struct DjuiFont gDjuiFonts[];
|
29
src/pc/djui/djui_gbi.h
Normal file
29
src/pc/djui/djui_gbi.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#define G_TEXCLIP_DJUI 0xe1
|
||||
#define G_TEXOVERRIDE_DJUI 0xe0
|
||||
#define G_EXECUTE_DJUI 0xdd
|
||||
|
||||
#define gSetClippingDjui(pkt, cmd, rot, x1, y1, x2, y2) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
_g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL( x1, 16, 8) | \
|
||||
_SHIFTL( y1, 8, 8) | _SHIFTL(rot, 0, 8); \
|
||||
_g->words.w1 = _SHIFTL(x2, 16, 8) | _SHIFTL(y2, 8, 8); \
|
||||
}
|
||||
|
||||
#define gSetOverrideDjui(pkt, cmd, texture, w, h, bitSize) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
_g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL(w, 16, 8) | \
|
||||
_SHIFTL(h, 8, 8) | _SHIFTL(bitSize, 0, 8); \
|
||||
_g->words.w1 = (uintptr_t)(texture); \
|
||||
}
|
||||
|
||||
#define gsSPExecuteDjui(word) \
|
||||
{{ \
|
||||
_SHIFTL(G_EXECUTE_DJUI, 24, 8), (unsigned int)(word) \
|
||||
}}
|
||||
|
||||
#define gDPSetTextureClippingDjui(pkt, rot, x1, y1, x2, y2) gSetClippingDjui(pkt, G_TEXCLIP_DJUI, rot, x1, y1, x2, y2)
|
||||
#define gDPSetTextureOverrideDjui(pkt, texture, w, h, bitSize) gSetOverrideDjui(pkt, G_TEXOVERRIDE_DJUI, texture, w, h, bitSize)
|
128
src/pc/djui/djui_gfx.c
Normal file
128
src/pc/djui/djui_gfx.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include <ultra64.h>
|
||||
#include "sm64.h"
|
||||
#include "djui.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/segment2.h"
|
||||
#include "src/pc/pc_main.h"
|
||||
#include "src/pc/gfx/gfx_window_manager_api.h"
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
static const Vtx vertex_djui_simple_rect[] = {
|
||||
{{{ 0, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 1, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 1, 0, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 0, 0, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
};
|
||||
|
||||
const Gfx dl_djui_simple_rect[] = {
|
||||
gsDPPipeSync(),
|
||||
gsSPClearGeometryMode(G_LIGHTING),
|
||||
gsDPSetCombineMode(G_CC_FADE, G_CC_FADE),
|
||||
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
|
||||
gsSPVertex(vertex_djui_simple_rect, 4, 0),
|
||||
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
static const Vtx vertex_djui_image[] = {
|
||||
{{{ 0, -1, 0 }, 0, { 0, 512 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 1, -1, 0 }, 0, { 512, 512 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 1, 0, 0 }, 0, { 512, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
{{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
};
|
||||
|
||||
const Gfx dl_djui_image[] = {
|
||||
gsDPPipeSync(),
|
||||
gsSPClearGeometryMode(G_LIGHTING),
|
||||
gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
|
||||
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
|
||||
gsDPSetTextureFilter(G_TF_POINT),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
|
||||
gsDPLoadTextureBlock(NULL, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
||||
gsSPExecuteDjui(G_TEXOVERRIDE_DJUI),
|
||||
gsSPVertex(vertex_djui_image, 4, 0),
|
||||
gsSPExecuteDjui(G_TEXCLIP_DJUI),
|
||||
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
|
||||
gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
static u8 djui_gfx_power_of_two(u32 value) {
|
||||
switch (value) {
|
||||
case 2: return 1;
|
||||
case 4: return 2;
|
||||
case 8: return 3;
|
||||
case 16: return 4;
|
||||
case 32: return 5;
|
||||
case 64: return 6;
|
||||
case 128: return 7;
|
||||
case 256: return 8;
|
||||
case 512: return 9;
|
||||
case 1024: return 10;
|
||||
default: return 11;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize) {
|
||||
gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize);
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_image);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
void djui_gfx_position_translate(f32* x, f32* y) {
|
||||
u32 windowWidth, windowHeight;
|
||||
wm_api->get_dimensions(&windowWidth, &windowHeight);
|
||||
*x = GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + *x * ((f32)SCREEN_HEIGHT / (f32)windowHeight);
|
||||
*y = SCREEN_HEIGHT - *y * ((f32)SCREEN_HEIGHT / (f32)windowHeight);
|
||||
}
|
||||
|
||||
void djui_gfx_scale_translate(f32* width, f32* height) {
|
||||
u32 windowWidth, windowHeight;
|
||||
wm_api->get_dimensions(&windowWidth, &windowHeight);
|
||||
|
||||
*width = *width * ((f32)SCREEN_HEIGHT / (f32)windowHeight);
|
||||
*height = *height * ((f32)SCREEN_HEIGHT / (f32)windowHeight);
|
||||
}
|
||||
|
||||
void djui_gfx_size_translate(f32* size) {
|
||||
u32 windowWidth, windowHeight;
|
||||
wm_api->get_dimensions(&windowWidth, &windowHeight);
|
||||
|
||||
*size = *size * ((f32)SCREEN_HEIGHT / (f32)windowHeight);
|
||||
}
|
||||
|
||||
bool djui_gfx_add_clipping_specific(struct DjuiBase* base, bool rotatedUV, f32 dX, f32 dY, f32 dW, f32 dH) {
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
|
||||
f32 clipX2 = clip->x + clip->width;
|
||||
f32 clipY2 = clip->y + clip->height;
|
||||
|
||||
f32 dX2 = dX + dW;
|
||||
f32 dY2 = dY + dH;
|
||||
|
||||
// completely clipped
|
||||
if (dX2 < clip->x) { return true; }
|
||||
if (dX > clipX2) { return true; }
|
||||
if (dY2 < clip->y) { return true; }
|
||||
if (dY > clipY2) { return true; }
|
||||
|
||||
f32 dClipX1 = fmax((clip->x - dX) / dW, 0);
|
||||
f32 dClipY1 = fmax((clip->y - dY) / dH, 0);
|
||||
f32 dClipX2 = fmax((dX - (clipX2 - dW)) / dW, 0);
|
||||
f32 dClipY2 = fmax((dY - (clipY2 - dH)) / dH, 0);
|
||||
|
||||
if ((dClipX1 != 0) || (dClipY1 != 0) || (dClipX2 != 0) || (dClipY2 != 0)) {
|
||||
gDPSetTextureClippingDjui(gDisplayListHead++, rotatedUV, (u8)(dClipX1 * 255), (u8)(dClipY1 * 255), (u8)(dClipX2 * 255), (u8)(dClipY2 * 255));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool djui_gfx_add_clipping(struct DjuiBase* base) {
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
return djui_gfx_add_clipping_specific(base, false, comp->x, comp->y, comp->width, comp->height);
|
||||
}
|
19
src/pc/djui/djui_gfx.h
Normal file
19
src/pc/djui/djui_gfx.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include "djui_base.h"
|
||||
|
||||
#define DJUI_MTX_PUSH 1
|
||||
#define DJUI_MTX_NOPUSH 2
|
||||
|
||||
extern const Gfx dl_djui_simple_rect[];
|
||||
extern const Gfx dl_djui_img_begin[];
|
||||
extern const Gfx dl_djui_img_end[];
|
||||
|
||||
void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize);
|
||||
|
||||
void djui_gfx_position_translate(f32* x, f32* y);
|
||||
void djui_gfx_scale_translate(f32* width, f32* height);
|
||||
void djui_gfx_size_translate(f32* size);
|
||||
|
||||
bool djui_gfx_add_clipping_specific(struct DjuiBase* base, bool rotatedUV, f32 dX, f32 dY, f32 dW, f32 dH);
|
||||
bool djui_gfx_add_clipping(struct DjuiBase* base);
|
60
src/pc/djui/djui_image.c
Normal file
60
src/pc/djui/djui_image.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "djui.h"
|
||||
#include "game/segment2.h"
|
||||
#include "src/pc/network/network.h"
|
||||
|
||||
////////////////
|
||||
// properties //
|
||||
////////////////
|
||||
|
||||
void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
|
||||
image->texture = texture;
|
||||
image->textureWidth = textureWidth;
|
||||
image->textureHeight = textureHeight;
|
||||
image->textureBitSize = textureBitSize;
|
||||
}
|
||||
|
||||
////////////
|
||||
// events //
|
||||
////////////
|
||||
|
||||
static void djui_image_render(struct DjuiBase* base) {
|
||||
struct DjuiImage* image = (struct DjuiImage*)base;
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiBaseRect* clip = &base->clip;
|
||||
|
||||
// translate position
|
||||
f32 translatedX = comp->x;
|
||||
f32 translatedY = comp->y;
|
||||
djui_gfx_position_translate(&translatedX, &translatedY);
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
|
||||
|
||||
// translate size
|
||||
f32 translatedWidth = comp->width;
|
||||
f32 translatedHeight = comp->height;
|
||||
djui_gfx_scale_translate(&translatedWidth, &translatedHeight);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedWidth, translatedHeight, 1.0f);
|
||||
|
||||
// render
|
||||
if (!djui_gfx_add_clipping(base)) {
|
||||
gDPSetEnvColor(gDisplayListHead++, base->color.r, base->color.g, base->color.b, base->color.a);
|
||||
djui_gfx_render_texture(image->texture, image->textureWidth, image->textureHeight, image->textureBitSize);
|
||||
}
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
static void djui_image_destroy(struct DjuiBase* base) {
|
||||
struct DjuiImage* image = (struct DjuiImage*)base;
|
||||
free(image);
|
||||
}
|
||||
|
||||
struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
|
||||
struct DjuiImage* image = malloc(sizeof(struct DjuiImage));
|
||||
struct DjuiBase* base = &image->base;
|
||||
|
||||
djui_base_init(parent, base, djui_image_render, djui_image_destroy);
|
||||
|
||||
djui_image_set_image(image, texture, textureWidth, textureHeight, textureBitSize);
|
||||
|
||||
return image;
|
||||
}
|
15
src/pc/djui/djui_image.h
Normal file
15
src/pc/djui/djui_image.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiImage {
|
||||
struct DjuiBase base;
|
||||
const u8* texture;
|
||||
u16 textureWidth;
|
||||
u16 textureHeight;
|
||||
u16 textureBitSize;
|
||||
};
|
||||
|
||||
void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
|
||||
|
||||
struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
|
540
src/pc/djui/djui_inputbox.c
Normal file
540
src/pc/djui/djui_inputbox.c
Normal file
|
@ -0,0 +1,540 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "djui.h"
|
||||
#include "pc/gfx/gfx_window_manager_api.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "game/segment2.h"
|
||||
#include "pc/controller/controller_keyboard.h"
|
||||
|
||||
#define DJUI_INPUTBOX_YOFF (-2)
|
||||
#define DJUI_INPUTBOX_MAX_BLINK 50
|
||||
#define DJUI_INPUTBOX_MID_BLINK (DJUI_INPUTBOX_MAX_BLINK / 2)
|
||||
#define DJUI_INPUTBOX_CURSOR_WIDTH (2.0f / 32.0f)
|
||||
|
||||
static u8 sHeldShift = 0;
|
||||
static u8 sHeldControl = 0;
|
||||
static u8 sCursorBlink = 0;
|
||||
|
||||
static void djui_inputbox_on_change(struct DjuiInputbox* inputbox) {
|
||||
struct DjuiBase* base = &inputbox->base;
|
||||
if (base != NULL && base->interactable != NULL && base->interactable->on_value_change != NULL) {
|
||||
base->interactable->on_value_change(base);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_inputbox_set_text_color(struct DjuiInputbox* inputbox, u8 r, u8 g, u8 b, u8 a) {
|
||||
inputbox->textColor.r = r;
|
||||
inputbox->textColor.g = g;
|
||||
inputbox->textColor.b = b;
|
||||
inputbox->textColor.a = a;
|
||||
}
|
||||
|
||||
void djui_inputbox_set_text(struct DjuiInputbox* inputbox, char* text) {
|
||||
snprintf(inputbox->buffer, inputbox->bufferSize, "%s", text);
|
||||
}
|
||||
|
||||
void djui_inputbox_select_all(struct DjuiInputbox* inputbox) {
|
||||
inputbox->selection[1] = 0;
|
||||
inputbox->selection[0] = strlen(inputbox->buffer);
|
||||
}
|
||||
|
||||
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(struct DjuiInputbox*)) {
|
||||
inputbox->on_enter_press = on_enter_press;
|
||||
}
|
||||
|
||||
void djui_inputbox_hook_escape_press(struct DjuiInputbox* inputbox, void (*on_escape_press)(struct DjuiInputbox*)) {
|
||||
inputbox->on_escape_press = on_escape_press;
|
||||
}
|
||||
|
||||
static void djui_inputbox_set_default_style(struct DjuiBase* base) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
if (inputbox->base.enabled) {
|
||||
djui_base_set_border_color(base, 150, 150, 150, 255);
|
||||
djui_base_set_color(&inputbox->base, 240, 240, 240, 255);
|
||||
} else {
|
||||
djui_base_set_border_color(base, 90, 90, 90, 255);
|
||||
djui_base_set_color(&inputbox->base, 140, 140, 140, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_hover(struct DjuiBase* base) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
djui_base_set_border_color(base, 0, 120, 215, 255);
|
||||
djui_base_set_color(&inputbox->base, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_hover_end(struct DjuiBase* base) {
|
||||
djui_inputbox_set_default_style(base);
|
||||
}
|
||||
|
||||
static u16 djui_inputbox_get_cursor_index(struct DjuiInputbox* inputbox) {
|
||||
struct DjuiBaseRect* comp = &inputbox->base.comp;
|
||||
struct DjuiFont* font = &gDjuiFonts[0];
|
||||
|
||||
f32 cX = (gCursorX - (comp->x + inputbox->viewX)) / font->defaultFontScale;
|
||||
f32 x = 0;
|
||||
u16 index = 0;
|
||||
for (u16 i = 0; i < inputbox->bufferSize; i++) {
|
||||
char c = inputbox->buffer[i];
|
||||
if (x < cX) {
|
||||
index = i;
|
||||
}
|
||||
if (c == '\0') { break; }
|
||||
x += font->char_width(c);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_cursor_down(struct DjuiBase* base) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
u16 index = djui_inputbox_get_cursor_index(inputbox);
|
||||
inputbox->selection[0] = index;
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_cursor_down_end(struct DjuiBase* base) {
|
||||
djui_inputbox_set_default_style(base);
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_cursor_down_begin(struct DjuiBase* base, bool inputCursor) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
u16 index = djui_inputbox_get_cursor_index(inputbox);
|
||||
u16 selLength = abs(inputbox->selection[0] - inputbox->selection[1]);
|
||||
if (selLength != strlen(inputbox->buffer) || djui_interactable_is_input_focus(base)) {
|
||||
inputbox->selection[0] = index;
|
||||
inputbox->selection[1] = index;
|
||||
djui_interactable_hook_cursor_down(base, djui_inputbox_on_cursor_down_begin, djui_inputbox_on_cursor_down, djui_inputbox_on_cursor_down_end);
|
||||
} else {
|
||||
djui_interactable_hook_cursor_down(base, djui_inputbox_on_cursor_down_begin, NULL, djui_inputbox_on_cursor_down_end);
|
||||
}
|
||||
sCursorBlink = 0;
|
||||
djui_interactable_set_input_focus(base);
|
||||
}
|
||||
|
||||
static u16 djui_inputbox_jump_word_left(char* msg, u16 len, u16 i) {
|
||||
if (i == 0) { return i; }
|
||||
|
||||
s32 lastI = i;
|
||||
bool seenNonSpace = false;
|
||||
while (true) {
|
||||
if (msg[i] == ' ' && seenNonSpace) { i = lastI; break; }
|
||||
lastI = i;
|
||||
i--;
|
||||
if (i <= 0) { i = 0; break; }
|
||||
if (msg[i] != ' ') { seenNonSpace = true; }
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static u16 djui_inputbox_jump_word_right(char *msg, u16 len, u16 i) {
|
||||
if (i >= len) { return len; }
|
||||
|
||||
bool seenSpace = false;
|
||||
while (true) {
|
||||
i++;
|
||||
if (i >= len) { i = len; break; }
|
||||
if (msg[i] != ' ' && seenSpace) { break; }
|
||||
if (msg[i] == ' ') { seenSpace = true; }
|
||||
};
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void djui_inputbox_delete_selection(struct DjuiInputbox *inputbox) {
|
||||
u16 *sel = inputbox->selection;
|
||||
char *msg = inputbox->buffer;
|
||||
u16 len = strlen(msg);
|
||||
|
||||
if (sel[0] != sel[1]) {
|
||||
u16 s1 = fmin(sel[0], sel[1]);
|
||||
u16 s2 = fmax(sel[0], sel[1]);
|
||||
memmove(&msg[s1], &msg[s2], (len + 1) - s2);
|
||||
sel[0] = s1;
|
||||
sel[1] = s1;
|
||||
}
|
||||
djui_inputbox_on_change(inputbox);
|
||||
}
|
||||
|
||||
bool djui_inputbox_on_key_down(struct DjuiBase *base, int scancode) {
|
||||
struct DjuiInputbox *inputbox = (struct DjuiInputbox *) base;
|
||||
u16 *sel = inputbox->selection;
|
||||
char *msg = inputbox->buffer;
|
||||
u16 len = strlen(msg);
|
||||
u16 s1 = fmin(sel[0], sel[1]);
|
||||
u16 s2 = fmax(sel[0], sel[1]);
|
||||
|
||||
switch (scancode) {
|
||||
case SCANCODE_CONTROL_LEFT: sHeldControl |= (1 << 0); return true;
|
||||
case SCANCODE_CONTROL_RIGHT: sHeldControl |= (1 << 1); return true;
|
||||
case SCANCODE_SHIFT_LEFT: sHeldShift |= (1 << 0); return true;
|
||||
case SCANCODE_SHIFT_RIGHT: sHeldShift |= (1 << 1); return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_LEFT) {
|
||||
if (sHeldControl) {
|
||||
sel[0] = djui_inputbox_jump_word_left(msg, len, sel[0]);
|
||||
} else if (sel[0] > 0) {
|
||||
sel[0]--;
|
||||
}
|
||||
if (!sHeldShift) { sel[1] = sel[0]; }
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_RIGHT) {
|
||||
if (sHeldControl) {
|
||||
sel[0] = djui_inputbox_jump_word_right(msg, len, sel[0]);
|
||||
} else if (sel[0] < len) {
|
||||
sel[0]++;
|
||||
}
|
||||
if (!sHeldShift) { sel[1] = sel[0]; }
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_HOME) {
|
||||
sel[0] = 0;
|
||||
if (!sHeldShift) { sel[1] = sel[0]; }
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_END) {
|
||||
sel[0] = len;
|
||||
if (!sHeldShift) { sel[1] = sel[0]; }
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_BACKSPACE) {
|
||||
if (sel[0] == sel[1]) {
|
||||
if (sHeldControl) {
|
||||
sel[0] = djui_inputbox_jump_word_left(msg, len, sel[0]);
|
||||
} else if (sel[0] > 0) {
|
||||
sel[0]--;
|
||||
}
|
||||
}
|
||||
if (sel[0] != sel[1]) {
|
||||
djui_inputbox_delete_selection(inputbox);
|
||||
}
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_DELETE) {
|
||||
if (sel[0] == sel[1]) {
|
||||
if (sHeldControl) {
|
||||
sel[1] = djui_inputbox_jump_word_right(msg, len, sel[1]);
|
||||
} else if (sel[1] < len) {
|
||||
sel[1]++;
|
||||
}
|
||||
}
|
||||
if (sel[0] != sel[1]) {
|
||||
djui_inputbox_delete_selection(inputbox);
|
||||
}
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((sHeldControl && scancode == SCANCODE_V) || (sHeldShift && scancode == SCANCODE_INSERT)) {
|
||||
djui_interactable_on_text_input(wm_api->get_clipboard_text());
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sHeldControl && (scancode == SCANCODE_C || scancode == SCANCODE_X)) {
|
||||
if (sel[0] != sel[1]) {
|
||||
char clipboardText[256] = { 0 };
|
||||
snprintf(clipboardText, fmin(256, 1 + s2 - s1), "%s", &msg[s1]);
|
||||
wm_api->set_clipboard_text(clipboardText);
|
||||
if (scancode == SCANCODE_X) {
|
||||
djui_inputbox_delete_selection(inputbox);
|
||||
sCursorBlink = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sHeldControl && scancode == SCANCODE_A) {
|
||||
inputbox->selection[0] = len;
|
||||
inputbox->selection[1] = 0;
|
||||
sCursorBlink = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_ESCAPE) {
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
if (inputbox->on_escape_press) {
|
||||
inputbox->on_escape_press(inputbox);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_ENTER) {
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
if (inputbox->on_enter_press) {
|
||||
inputbox->on_enter_press(inputbox);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void djui_inputbox_on_key_up(struct DjuiBase *base, int scancode) {
|
||||
switch (scancode) {
|
||||
case SCANCODE_CONTROL_LEFT: sHeldControl &= ~(1 << 0); break;
|
||||
case SCANCODE_CONTROL_RIGHT: sHeldControl &= ~(1 << 1); break;
|
||||
case SCANCODE_SHIFT_LEFT: sHeldShift &= ~(1 << 0); break;
|
||||
case SCANCODE_SHIFT_RIGHT: sHeldShift &= ~(1 << 1); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_focus_begin(struct DjuiBase* base) {
|
||||
sHeldControl = 0;
|
||||
sHeldShift = 0;
|
||||
wm_api->start_text_input();
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_focus_end(struct DjuiBase* base) {
|
||||
wm_api->stop_text_input();
|
||||
}
|
||||
|
||||
static void djui_inputbox_on_text_input(struct DjuiBase *base, char* text) {
|
||||
struct DjuiInputbox *inputbox = (struct DjuiInputbox *) base;
|
||||
char* msg = inputbox->buffer;
|
||||
int msgLen = strlen(msg);
|
||||
int textLen = strlen(text);
|
||||
|
||||
// truncate
|
||||
if (textLen + msgLen >= inputbox->bufferSize) {
|
||||
int space = (inputbox->bufferSize - msgLen);
|
||||
if (space <= 1) { return; }
|
||||
text[space - 1] = '\0';
|
||||
textLen = space - 1;
|
||||
}
|
||||
|
||||
// erase selection
|
||||
if (inputbox->selection[0] != inputbox->selection[1]) {
|
||||
djui_inputbox_delete_selection(inputbox);
|
||||
}
|
||||
|
||||
// sanitize
|
||||
char *t = text;
|
||||
while (*t != '\0') {
|
||||
if (*t == '\n') { *t = ' '; }
|
||||
else if (*t == '\r') { *t = ' '; }
|
||||
else if (*t == ' ') { ; }
|
||||
else if (*t < '!' || *t > '~') { *t = '?'; }
|
||||
t++;
|
||||
}
|
||||
|
||||
// back up current message
|
||||
char* sMsg = malloc(sizeof(char) * (inputbox->bufferSize));
|
||||
memcpy(sMsg, msg, inputbox->bufferSize);
|
||||
|
||||
// insert text
|
||||
u16 sel = inputbox->selection[0];
|
||||
snprintf(&msg[sel], (inputbox->bufferSize - sel), "%s%s", text, &sMsg[sel]);
|
||||
free(sMsg);
|
||||
|
||||
// adjust cursor
|
||||
inputbox->selection[0] += strlen(text);
|
||||
inputbox->selection[1] = inputbox->selection[0];
|
||||
sCursorBlink = 0;
|
||||
djui_inputbox_on_change(inputbox);
|
||||
}
|
||||
|
||||
static void djui_inputbox_render_char(struct DjuiInputbox* inputbox, char c, f32* drawX, f32* additionalShift) {
|
||||
struct DjuiBaseRect* comp = &inputbox->base.comp;
|
||||
struct DjuiFont* font = &gDjuiFonts[0];
|
||||
f32 dX = comp->x + *drawX;
|
||||
f32 dY = comp->y + DJUI_INPUTBOX_YOFF;
|
||||
f32 dW = font->charWidth * font->defaultFontScale;
|
||||
f32 dH = font->charHeight * font->defaultFontScale;
|
||||
|
||||
f32 charWidth = font->char_width(c);
|
||||
*drawX += charWidth * font->defaultFontScale;
|
||||
|
||||
if (c != ' ' && !djui_gfx_add_clipping_specific(&inputbox->base, font->rotatedUV, dX, dY, dW, dH)) {
|
||||
if (*additionalShift > 0) {
|
||||
create_dl_translation_matrix(DJUI_MTX_NOPUSH, *additionalShift, 0, 0);
|
||||
*additionalShift = 0;
|
||||
}
|
||||
font->render_char(c);
|
||||
}
|
||||
*additionalShift += charWidth;
|
||||
}
|
||||
|
||||
static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) {
|
||||
struct DjuiFont* font = &gDjuiFonts[0];
|
||||
|
||||
// make selection well formed
|
||||
u16 selection[2] = { 0 };
|
||||
selection[0] = fmin(inputbox->selection[0], inputbox->selection[1]);
|
||||
selection[1] = fmax(inputbox->selection[0], inputbox->selection[1]);
|
||||
|
||||
char* msg = inputbox->buffer;
|
||||
f32 x = 0;
|
||||
f32 width = 0;
|
||||
for (u16 i = 0; i < selection[1]; i++) {
|
||||
if (i < selection[0]) {
|
||||
x += font->char_width(msg[i]);
|
||||
} else {
|
||||
width += font->char_width(msg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
sCursorBlink = (sCursorBlink + 1) % DJUI_INPUTBOX_MAX_BLINK;
|
||||
|
||||
// render only cursor when there is no selection width
|
||||
if (selection[0] == selection[1]) {
|
||||
if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) {
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, x - DJUI_INPUTBOX_CURSOR_WIDTH / 2.0f, -0.1f, 0);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, DJUI_INPUTBOX_CURSOR_WIDTH, 0.8f, 1.0f);
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// clip selection box
|
||||
// note: this is incredibly confusing due to being in font-space instead of screen-space
|
||||
f32 clipLow = -inputbox->viewX / font->defaultFontScale;
|
||||
if (x < clipLow) {
|
||||
width -= clipLow - x;
|
||||
x = clipLow;
|
||||
}
|
||||
f32 clipHigh = (inputbox->base.clip.width / font->defaultFontScale) - x + clipLow;
|
||||
if (width > clipHigh) {
|
||||
width = clipHigh;
|
||||
}
|
||||
|
||||
// render selection box
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, x, -0.1f, 0);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, width, 0.8f, 1.0f);
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 120, 215, 255);
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
|
||||
// render selection cursor
|
||||
if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) {
|
||||
f32 cX = (inputbox->selection[0] < inputbox->selection[1]) ? x : (x + width);
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, cX - DJUI_INPUTBOX_CURSOR_WIDTH / 2.0f, -0.1f, 0);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, DJUI_INPUTBOX_CURSOR_WIDTH, 0.8f, 1.0f);
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 127, 0, 255);
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_inputbox_keep_selection_in_view(struct DjuiInputbox* inputbox) {
|
||||
struct DjuiFont* font = &gDjuiFonts[0];
|
||||
|
||||
// calculate where our cursor is
|
||||
f32 cursorX = inputbox->viewX;
|
||||
char* msg = inputbox->buffer;
|
||||
for (u16 i = 0; i < inputbox->selection[0]; i++) {
|
||||
cursorX += font->char_width(msg[i]) * font->defaultFontScale;
|
||||
}
|
||||
|
||||
// shift viewing window
|
||||
if (cursorX > inputbox->base.comp.width) {
|
||||
inputbox->viewX -= cursorX - inputbox->base.comp.width;
|
||||
} else if (cursorX < 0) {
|
||||
inputbox->viewX -= cursorX;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_inputbox_render(struct DjuiBase* base) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
struct DjuiBaseRect* comp = &base->comp;
|
||||
struct DjuiFont* font = &gDjuiFonts[0];
|
||||
djui_rect_render(base);
|
||||
|
||||
// shift the viewing window to keep the selection in view
|
||||
djui_inputbox_keep_selection_in_view(inputbox);
|
||||
|
||||
// translate position
|
||||
f32 translatedX = comp->x + inputbox->viewX;
|
||||
f32 translatedY = comp->y + DJUI_INPUTBOX_YOFF;
|
||||
djui_gfx_position_translate(&translatedX, &translatedY);
|
||||
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
|
||||
|
||||
// compute font size
|
||||
f32 translatedFontSize = font->defaultFontScale;
|
||||
djui_gfx_size_translate(&translatedFontSize);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedFontSize, translatedFontSize, 1.0f);
|
||||
|
||||
// render selection
|
||||
djui_inputbox_render_selection(inputbox);
|
||||
|
||||
// begin font
|
||||
gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList);
|
||||
|
||||
// set color
|
||||
gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a);
|
||||
|
||||
// make selection well formed
|
||||
u16 selection[2] = { 0 };
|
||||
selection[0] = fmin(inputbox->selection[0], inputbox->selection[1]);
|
||||
selection[1] = fmax(inputbox->selection[0], inputbox->selection[1]);
|
||||
|
||||
// render text
|
||||
char* msg = inputbox->buffer;
|
||||
f32 drawX = inputbox->viewX;
|
||||
f32 additionalShift = 0;
|
||||
bool wasInsideSelection = false;
|
||||
for (u16 i = 0; i < inputbox->bufferSize; i++) {
|
||||
if (msg[i] == '\0') { break; }
|
||||
|
||||
// deal with seleciton color
|
||||
if (selection[0] != selection[1]) {
|
||||
bool insideSelection = (i >= selection[0]) && (i < selection[1]);
|
||||
if (insideSelection && !wasInsideSelection) {
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
} else if (!insideSelection && wasInsideSelection) {
|
||||
gDPSetEnvColor(gDisplayListHead++, inputbox->textColor.r, inputbox->textColor.g, inputbox->textColor.b, inputbox->textColor.a);
|
||||
}
|
||||
wasInsideSelection = insideSelection;
|
||||
}
|
||||
|
||||
// render character
|
||||
djui_inputbox_render_char(inputbox, msg[i], &drawX, &additionalShift);
|
||||
}
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
}
|
||||
|
||||
static void djui_inputbox_destroy(struct DjuiBase* base) {
|
||||
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
|
||||
free(inputbox->buffer);
|
||||
free(inputbox);
|
||||
}
|
||||
|
||||
struct DjuiInputbox* djui_inputbox_create(struct DjuiBase* parent, u16 bufferSize) {
|
||||
struct DjuiInputbox* inputbox = malloc(sizeof(struct DjuiInputbox));
|
||||
struct DjuiBase* base = &inputbox->base;
|
||||
memset(inputbox, 0, sizeof(struct DjuiInputbox));
|
||||
inputbox->bufferSize = bufferSize;
|
||||
inputbox->buffer = malloc(sizeof(char) * bufferSize);
|
||||
memset(inputbox->buffer, 0, sizeof(char) * bufferSize);
|
||||
|
||||
djui_base_init(parent, base, djui_inputbox_render, djui_inputbox_destroy);
|
||||
djui_base_set_size(base, 200, 32);
|
||||
djui_base_set_border_width(base, 2);
|
||||
djui_inputbox_set_text_color(inputbox, 0, 0, 0, 255);
|
||||
djui_interactable_create(base);
|
||||
djui_interactable_hook_hover(base, djui_inputbox_on_hover, djui_inputbox_on_hover_end);
|
||||
djui_interactable_hook_cursor_down(base, djui_inputbox_on_cursor_down_begin, djui_inputbox_on_cursor_down, djui_inputbox_on_cursor_down_end);
|
||||
djui_interactable_hook_key(base, djui_inputbox_on_key_down, djui_inputbox_on_key_up);
|
||||
djui_interactable_hook_focus(base, djui_inputbox_on_focus_begin, NULL, djui_inputbox_on_focus_end);
|
||||
djui_interactable_hook_text_input(base, djui_inputbox_on_text_input);
|
||||
djui_interactable_hook_enabled_change(base, djui_inputbox_set_default_style);
|
||||
djui_inputbox_set_default_style(base);
|
||||
|
||||
return inputbox;
|
||||
}
|
24
src/pc/djui/djui_inputbox.h
Normal file
24
src/pc/djui/djui_inputbox.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiInputbox {
|
||||
struct DjuiBase base;
|
||||
char* buffer;
|
||||
u16 bufferSize;
|
||||
u16 selection[2];
|
||||
f32 viewX;
|
||||
struct DjuiColor textColor;
|
||||
void (*on_enter_press)(struct DjuiInputbox*);
|
||||
void (*on_escape_press)(struct DjuiInputbox*);
|
||||
};
|
||||
|
||||
void djui_inputbox_set_text_color(struct DjuiInputbox* inputbox, u8 r, u8 g, u8 b, u8 a);
|
||||
void djui_inputbox_set_text(struct DjuiInputbox* inputbox, char* text);
|
||||
void djui_inputbox_select_all(struct DjuiInputbox* inputbox);
|
||||
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(struct DjuiInputbox*));
|
||||
void djui_inputbox_hook_escape_press(struct DjuiInputbox* inputbox, void (*on_escape_press)(struct DjuiInputbox*));
|
||||
bool djui_inputbox_on_key_down(struct DjuiBase* base, int scancode);
|
||||
void djui_inputbox_on_key_up(struct DjuiBase* base, int scancode);
|
||||
|
||||
struct DjuiInputbox* djui_inputbox_create(struct DjuiBase* parent, u16 bufferSize);
|
430
src/pc/djui/djui_interactable.c
Normal file
430
src/pc/djui/djui_interactable.c
Normal file
|
@ -0,0 +1,430 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "djui.h"
|
||||
|
||||
#include "src/pc/controller/controller_sdl.h"
|
||||
#include "src/pc/controller/controller_mouse.h"
|
||||
#include "src/pc/controller/controller_keyboard.h"
|
||||
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
enum PadHoldDirection { PAD_HOLD_DIR_NONE, PAD_HOLD_DIR_UP, PAD_HOLD_DIR_DOWN, PAD_HOLD_DIR_LEFT, PAD_HOLD_DIR_RIGHT };
|
||||
static enum PadHoldDirection sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
|
||||
static u16 sKeyboardButtons = 0;
|
||||
|
||||
static bool sIgnoreInteractableUntilCursorReleased = false;
|
||||
|
||||
static struct DjuiBase* sInteractableFocus = NULL;
|
||||
static struct DjuiBase* sInteractableBinding = NULL;
|
||||
static struct DjuiBase* sHovered = NULL;
|
||||
static struct DjuiBase* sMouseDown = NULL;
|
||||
bool gInteractableOverridePad = false;
|
||||
OSContPad gInteractablePad = { 0 };
|
||||
static OSContPad sLastInteractablePad = { 0 };
|
||||
static int sLastMouseButtons = 0;
|
||||
|
||||
static void djui_interactable_on_click(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_click == NULL) { return; }
|
||||
base->interactable->on_click(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_hover(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_hover == NULL) { return; }
|
||||
base->interactable->on_hover(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_hover_end(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_hover == NULL) { return; }
|
||||
base->interactable->on_hover_end(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_cursor_down_begin(struct DjuiBase* base, bool inputCursor) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_cursor_down_begin == NULL) { return; }
|
||||
|
||||
if (sHovered != NULL) {
|
||||
djui_interactable_on_hover_end(sHovered);
|
||||
sHovered = NULL;
|
||||
}
|
||||
|
||||
base->interactable->on_cursor_down_begin(base, inputCursor);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_cursor_down(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_cursor_down == NULL) { return; }
|
||||
|
||||
base->interactable->on_cursor_down(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_cursor_down_end(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_cursor_down_end == NULL) { return; }
|
||||
base->interactable->on_cursor_down_end(base);
|
||||
|
||||
if (djui_cursor_inside_base(base)) {
|
||||
djui_interactable_on_click(base);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_interactable_on_focus_begin(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_focus_begin == NULL) { return; }
|
||||
base->interactable->on_focus_begin(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_focus(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_focus == NULL) { return; }
|
||||
base->interactable->on_focus(base, &gInteractablePad);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_focus_end(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_focus_end == NULL) { return; }
|
||||
base->interactable->on_focus_end(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_value_change(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_value_change == NULL) { return; }
|
||||
base->interactable->on_value_change(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_on_bind(struct DjuiBase* base) {
|
||||
if (base == NULL) { return; }
|
||||
if (base->interactable == NULL) { return; }
|
||||
if (base->interactable->on_bind == NULL) { return; }
|
||||
base->interactable->on_bind(base);
|
||||
}
|
||||
|
||||
static void djui_interactable_cursor_update_active(struct DjuiBase* base) {
|
||||
if (!base->visible) { return; }
|
||||
if (!base->enabled) { return; }
|
||||
|
||||
static struct DjuiBase* insideParent = NULL;
|
||||
|
||||
if (!djui_cursor_inside_base(base)) { return; }
|
||||
|
||||
if (base->interactable != NULL) {
|
||||
sHovered = base;
|
||||
insideParent = base;
|
||||
} else if (insideParent == NULL) {
|
||||
sHovered = NULL;
|
||||
}
|
||||
|
||||
// check all children
|
||||
struct DjuiBaseChild* child = base->child;
|
||||
while (child != NULL) {
|
||||
djui_interactable_cursor_update_active(child->base);
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
if (insideParent == base) {
|
||||
insideParent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool djui_interactable_is_binding(void) {
|
||||
return sInteractableBinding != NULL;
|
||||
}
|
||||
|
||||
void djui_interactable_set_binding(struct DjuiBase* base) {
|
||||
sInteractableBinding = base;
|
||||
djui_cursor_set_visible(base == NULL);
|
||||
if (base == NULL) {
|
||||
sIgnoreInteractableUntilCursorReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_interactable_set_input_focus(struct DjuiBase* base) {
|
||||
djui_interactable_on_focus_end(base);
|
||||
sInteractableFocus = base;
|
||||
djui_interactable_on_focus_begin(base);
|
||||
djui_cursor_set_visible(base == NULL);
|
||||
}
|
||||
|
||||
bool djui_interactable_is_input_focus(struct DjuiBase* base) {
|
||||
return sInteractableFocus == base;
|
||||
}
|
||||
|
||||
bool djui_interactable_on_key_down(int scancode) {
|
||||
|
||||
bool keyFocused = (sInteractableFocus != NULL)
|
||||
&& (sInteractableFocus->interactable != NULL)
|
||||
&& (sInteractableFocus->interactable->on_key_down != NULL);
|
||||
|
||||
if (keyFocused) {
|
||||
bool consume = sInteractableFocus->interactable->on_key_down(sInteractableFocus, scancode);
|
||||
if (consume) {
|
||||
sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
|
||||
sKeyboardButtons = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_ESCAPE) {
|
||||
// pressed escape button on keyboard
|
||||
djui_panel_back();
|
||||
}
|
||||
|
||||
if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus) {
|
||||
bool pressChat = false;
|
||||
for (int i = 0; i < MAX_BINDS; i++) {
|
||||
if (scancode == (int)configKeyChat[i]) { pressChat = true; }
|
||||
}
|
||||
|
||||
if (pressChat) {
|
||||
djui_chat_box_toggle();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (scancode) {
|
||||
case SCANCODE_UP: sKeyboardHoldDirection = PAD_HOLD_DIR_UP; return true;
|
||||
case SCANCODE_DOWN: sKeyboardHoldDirection = PAD_HOLD_DIR_DOWN; return true;
|
||||
case SCANCODE_LEFT: sKeyboardHoldDirection = PAD_HOLD_DIR_LEFT; return true;
|
||||
case SCANCODE_RIGHT: sKeyboardHoldDirection = PAD_HOLD_DIR_RIGHT; return true;
|
||||
case SCANCODE_ENTER: sKeyboardButtons |= PAD_BUTTON_A; return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void djui_interactable_on_key_up(int scancode) {
|
||||
|
||||
bool keyFocused = (sInteractableFocus != NULL)
|
||||
&& (sInteractableFocus->interactable != NULL)
|
||||
&& (sInteractableFocus->interactable->on_key_up != NULL);
|
||||
|
||||
if (keyFocused) {
|
||||
sInteractableFocus->interactable->on_key_up(sInteractableFocus, scancode);
|
||||
sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
|
||||
sKeyboardButtons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
OSContPad* pad = &gInteractablePad;
|
||||
switch (scancode) {
|
||||
case SCANCODE_UP: if (sKeyboardHoldDirection == PAD_HOLD_DIR_UP) { sKeyboardHoldDirection = PAD_HOLD_DIR_NONE; pad->stick_y = 0; } break;
|
||||
case SCANCODE_DOWN: if (sKeyboardHoldDirection == PAD_HOLD_DIR_DOWN) { sKeyboardHoldDirection = PAD_HOLD_DIR_NONE; pad->stick_y = 0; } break;
|
||||
case SCANCODE_LEFT: if (sKeyboardHoldDirection == PAD_HOLD_DIR_LEFT) { sKeyboardHoldDirection = PAD_HOLD_DIR_NONE; pad->stick_x = 0; } break;
|
||||
case SCANCODE_RIGHT: if (sKeyboardHoldDirection == PAD_HOLD_DIR_RIGHT) { sKeyboardHoldDirection = PAD_HOLD_DIR_NONE; pad->stick_x = 0; } break;
|
||||
case SCANCODE_ENTER: sKeyboardButtons &= ~PAD_BUTTON_A; break;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_interactable_on_text_input(char* text) {
|
||||
if (sInteractableFocus == NULL) { return; }
|
||||
if (sInteractableFocus->interactable == NULL) { return; }
|
||||
if (sInteractableFocus->interactable->on_text_input == NULL) { return; }
|
||||
sInteractableFocus->interactable->on_text_input(sInteractableFocus, text);
|
||||
}
|
||||
|
||||
void djui_interactable_update_pad(void) {
|
||||
OSContPad* pad = &gInteractablePad;
|
||||
|
||||
pad->button |= sKeyboardButtons;
|
||||
|
||||
static enum PadHoldDirection lastPadHoldDirection = PAD_HOLD_DIR_NONE;
|
||||
static clock_t padHoldTimer = 0;
|
||||
|
||||
enum PadHoldDirection padHoldDirection = sKeyboardHoldDirection;
|
||||
if (padHoldDirection != PAD_HOLD_DIR_NONE) {
|
||||
switch (padHoldDirection) {
|
||||
case PAD_HOLD_DIR_UP: pad->stick_x = 0; pad->stick_y = -64; break;
|
||||
case PAD_HOLD_DIR_DOWN: pad->stick_x = 0; pad->stick_y = 64; break;
|
||||
case PAD_HOLD_DIR_LEFT: pad->stick_x = -64; pad->stick_y = 0; break;
|
||||
case PAD_HOLD_DIR_RIGHT: pad->stick_x = 64; pad->stick_y = 0; break;
|
||||
default: break;
|
||||
}
|
||||
} else if (pad->stick_x == 0 && pad->stick_y == 0) {
|
||||
padHoldDirection = PAD_HOLD_DIR_NONE;
|
||||
} else if (abs(pad->stick_x) > abs(pad->stick_y)) {
|
||||
padHoldDirection = (pad->stick_x < 0) ? PAD_HOLD_DIR_LEFT : PAD_HOLD_DIR_RIGHT;
|
||||
} else {
|
||||
padHoldDirection = (pad->stick_y > 0) ? PAD_HOLD_DIR_UP : PAD_HOLD_DIR_DOWN;
|
||||
}
|
||||
|
||||
bool validPadHold = false;
|
||||
if (padHoldDirection == PAD_HOLD_DIR_NONE) {
|
||||
// nothing to do
|
||||
} else if (padHoldDirection != lastPadHoldDirection) {
|
||||
padHoldTimer = clock() + CLOCKS_PER_SEC * 0.25f;
|
||||
validPadHold = true;
|
||||
} else if (clock() > padHoldTimer) {
|
||||
padHoldTimer = clock() + CLOCKS_PER_SEC * 0.10f;
|
||||
validPadHold = true;
|
||||
}
|
||||
|
||||
if (validPadHold && sInteractableFocus == NULL) {
|
||||
switch (padHoldDirection) {
|
||||
case PAD_HOLD_DIR_UP: djui_cursor_move( 0, -1); break;
|
||||
case PAD_HOLD_DIR_DOWN: djui_cursor_move( 0, 1); break;
|
||||
case PAD_HOLD_DIR_LEFT: djui_cursor_move(-1, 0); break;
|
||||
case PAD_HOLD_DIR_RIGHT: djui_cursor_move( 1, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
lastPadHoldDirection = padHoldDirection;
|
||||
}
|
||||
|
||||
void djui_interactable_update(void) {
|
||||
// update pad
|
||||
djui_interactable_update_pad();
|
||||
|
||||
// prevent pressing buttons when they should be ignored
|
||||
int mouseButtons = mouse_window_buttons;
|
||||
u16 padButtons = gInteractablePad.button;
|
||||
if (sIgnoreInteractableUntilCursorReleased) {
|
||||
if ((padButtons & PAD_BUTTON_A) || (mouseButtons & MOUSE_BUTTON_1)) {
|
||||
padButtons &= ~PAD_BUTTON_A;
|
||||
mouseButtons &= ~MOUSE_BUTTON_1;
|
||||
} else {
|
||||
sIgnoreInteractableUntilCursorReleased = false;
|
||||
}
|
||||
}
|
||||
|
||||
// update focused
|
||||
if (sInteractableFocus) {
|
||||
u16 mainButtons = PAD_BUTTON_A | PAD_BUTTON_B;
|
||||
if ((mouseButtons & MOUSE_BUTTON_1) && !(sLastMouseButtons && MOUSE_BUTTON_1) && !djui_cursor_inside_base(sInteractableFocus)) {
|
||||
// clicked outside of focused
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
} else if ((padButtons & mainButtons) && !(sLastInteractablePad.button & mainButtons)) {
|
||||
// pressed main face button
|
||||
djui_interactable_set_input_focus(NULL);
|
||||
} else {
|
||||
djui_interactable_on_focus(sInteractableFocus);
|
||||
}
|
||||
} else if ((padButtons & PAD_BUTTON_B) && !(sLastInteractablePad.button & PAD_BUTTON_B)) {
|
||||
// pressed back button on controller
|
||||
djui_panel_back();
|
||||
} else if ((padButtons & PAD_BUTTON_START) && !(sLastInteractablePad.button & PAD_BUTTON_START)) {
|
||||
// pressed start button
|
||||
if (gDjuiPanelPauseCreated) { djui_panel_shutdown(); }
|
||||
}
|
||||
|
||||
if (sInteractableBinding != NULL) {
|
||||
djui_interactable_on_bind(sInteractableBinding);
|
||||
} else if ((padButtons & PAD_BUTTON_A) || (mouseButtons & MOUSE_BUTTON_1)) {
|
||||
// cursor down events
|
||||
if (sHovered != NULL) {
|
||||
sMouseDown = sHovered;
|
||||
sHovered = NULL;
|
||||
djui_interactable_on_cursor_down_begin(sMouseDown, !mouseButtons);
|
||||
} else {
|
||||
djui_interactable_on_cursor_down(sMouseDown);
|
||||
}
|
||||
} else {
|
||||
// cursor up event
|
||||
if (sMouseDown != NULL) {
|
||||
djui_interactable_on_cursor_down_end(sMouseDown);
|
||||
sMouseDown = NULL;
|
||||
}
|
||||
struct DjuiBase* lastHovered = sHovered;
|
||||
sHovered = NULL;
|
||||
djui_interactable_cursor_update_active(&gDjuiRoot->base);
|
||||
if (lastHovered != sHovered) {
|
||||
djui_interactable_on_hover_end(lastHovered);
|
||||
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, gDefaultSoundArgs);
|
||||
}
|
||||
djui_interactable_on_hover(sHovered);
|
||||
}
|
||||
|
||||
sLastInteractablePad = gInteractablePad;
|
||||
sLastMouseButtons = mouseButtons;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_hover(struct DjuiBase* base,
|
||||
void (*on_hover)(struct DjuiBase*),
|
||||
void (*on_hover_end)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_hover = on_hover;
|
||||
interactable->on_hover_end = on_hover_end;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_cursor_down(struct DjuiBase* base,
|
||||
void (*on_cursor_down_begin)(struct DjuiBase*, bool),
|
||||
void (*on_cursor_down)(struct DjuiBase*),
|
||||
void (*on_cursor_down_end)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_cursor_down_begin = on_cursor_down_begin;
|
||||
interactable->on_cursor_down = on_cursor_down;
|
||||
interactable->on_cursor_down_end = on_cursor_down_end;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_focus(struct DjuiBase* base,
|
||||
void (*on_focus_begin)(struct DjuiBase*),
|
||||
void (*on_focus)(struct DjuiBase*, OSContPad*),
|
||||
void (*on_focus_end)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_focus_begin = on_focus_begin;
|
||||
interactable->on_focus = on_focus;
|
||||
interactable->on_focus_end = on_focus_end;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_click(struct DjuiBase* base,
|
||||
void (*on_click)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_click = on_click;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_value_change(struct DjuiBase* base,
|
||||
void (*on_value_change)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_value_change = on_value_change;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_bind(struct DjuiBase* base,
|
||||
void (*on_bind)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable* interactable = base->interactable;
|
||||
interactable->on_bind = on_bind;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_key(struct DjuiBase* base,
|
||||
bool (*on_key_down)(struct DjuiBase*, int),
|
||||
void (*on_key_up)(struct DjuiBase*, int)) {
|
||||
struct DjuiInteractable *interactable = base->interactable;
|
||||
interactable->on_key_down = on_key_down;
|
||||
interactable->on_key_up = on_key_up;
|
||||
|
||||
}
|
||||
|
||||
void djui_interactable_hook_text_input(struct DjuiBase *base,
|
||||
void (*on_text_input)(struct DjuiBase*, char*)) {
|
||||
struct DjuiInteractable *interactable = base->interactable;
|
||||
interactable->on_text_input = on_text_input;
|
||||
}
|
||||
|
||||
void djui_interactable_hook_enabled_change(struct DjuiBase *base,
|
||||
void (*on_enabled_change)(struct DjuiBase*)) {
|
||||
struct DjuiInteractable *interactable = base->interactable;
|
||||
interactable->on_enabled_change = on_enabled_change;
|
||||
}
|
||||
|
||||
void djui_interactable_create(struct DjuiBase* base) {
|
||||
|
||||
if (base->interactable != NULL) {
|
||||
free(base->interactable);
|
||||
}
|
||||
|
||||
struct DjuiInteractable* interactable = malloc(sizeof(struct DjuiInteractable));
|
||||
memset(interactable, 0, sizeof(struct DjuiInteractable));
|
||||
base->interactable = interactable;
|
||||
}
|
89
src/pc/djui/djui_interactable.h
Normal file
89
src/pc/djui/djui_interactable.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
#include "djui_base.h"
|
||||
|
||||
#define PAD_BUTTON_A ((u16)(1 << 15))
|
||||
#define PAD_BUTTON_B ((u16)(1 << 14))
|
||||
#define PAD_BUTTON_START ((u16)(1 << 12))
|
||||
|
||||
#define MOUSE_BUTTON_1 ((u16)(1 << 0))
|
||||
|
||||
#define SCANCODE_UP 328
|
||||
#define SCANCODE_DOWN 336
|
||||
#define SCANCODE_LEFT 331
|
||||
#define SCANCODE_RIGHT 333
|
||||
#define SCANCODE_PAGE_DOWN 337
|
||||
#define SCANCODE_PAGE_UP 329
|
||||
|
||||
|
||||
#define SCANCODE_ENTER 28
|
||||
#define SCANCODE_SPACE 57
|
||||
#define SCANCODE_ESCAPE 1
|
||||
|
||||
#pragma pack(1)
|
||||
struct DjuiInteractable {
|
||||
bool enabled;
|
||||
void (*on_hover)(struct DjuiBase*);
|
||||
void (*on_hover_end)(struct DjuiBase*);
|
||||
void (*on_cursor_down_begin)(struct DjuiBase*, bool);
|
||||
void (*on_cursor_down)(struct DjuiBase*);
|
||||
void (*on_cursor_down_end)(struct DjuiBase*);
|
||||
void (*on_focus_begin)(struct DjuiBase*);
|
||||
void (*on_focus)(struct DjuiBase*, OSContPad*);
|
||||
void (*on_focus_end)(struct DjuiBase*);
|
||||
void (*on_click)(struct DjuiBase*);
|
||||
void (*on_value_change)(struct DjuiBase*);
|
||||
void (*on_bind)(struct DjuiBase*);
|
||||
bool (*on_key_down)(struct DjuiBase*, int scancode);
|
||||
void (*on_key_up)(struct DjuiBase*, int scancode);
|
||||
void (*on_text_input)(struct DjuiBase*, char* text);
|
||||
void (*on_enabled_change)(struct DjuiBase*);
|
||||
};
|
||||
|
||||
extern bool gInteractableOverridePad;
|
||||
extern OSContPad gInteractablePad;
|
||||
|
||||
bool djui_interactable_is_binding(void);
|
||||
void djui_interactable_set_binding(struct DjuiBase* base);
|
||||
void djui_interactable_set_input_focus(struct DjuiBase* base);
|
||||
bool djui_interactable_is_input_focus(struct DjuiBase* base);
|
||||
bool djui_interactable_on_key_down(int scancode);
|
||||
void djui_interactable_on_key_up(int scancode);
|
||||
void djui_interactable_on_text_input(char *text);
|
||||
|
||||
void djui_interactable_update(void);
|
||||
|
||||
void djui_interactable_hook_hover(struct DjuiBase* base,
|
||||
void (*on_hover)(struct DjuiBase*),
|
||||
void (*on_hover_end)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_cursor_down(struct DjuiBase* base,
|
||||
void (*on_cursor_down_begin)(struct DjuiBase*, bool),
|
||||
void (*on_cursor_down)(struct DjuiBase*),
|
||||
void (*on_cursor_down_end)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_focus(struct DjuiBase* base,
|
||||
void (*on_focus_begin)(struct DjuiBase*),
|
||||
void (*on_focus)(struct DjuiBase*, OSContPad*),
|
||||
void (*on_focus_end)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_click(struct DjuiBase* base,
|
||||
void (*on_click)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_value_change(struct DjuiBase* base,
|
||||
void (*on_value_change)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_bind(struct DjuiBase* base,
|
||||
void (*on_bind)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_hook_key(struct DjuiBase* base,
|
||||
bool (*on_key_down)(struct DjuiBase*, int),
|
||||
void (*on_key_up)(struct DjuiBase*, int));
|
||||
|
||||
void djui_interactable_hook_text_input(struct DjuiBase* base,
|
||||
void (*on_text_input)(struct DjuiBase*, char*));
|
||||
|
||||
void djui_interactable_hook_enabled_change(struct DjuiBase *base,
|
||||
void (*on_enabled_change)(struct DjuiBase*));
|
||||
|
||||
void djui_interactable_create(struct DjuiBase* base);
|
152
src/pc/djui/djui_panel.c
Normal file
152
src/pc/djui/djui_panel.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "audio_defines.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
struct DjuiPanel {
|
||||
struct DjuiBase* base;
|
||||
struct DjuiPanel* parent;
|
||||
struct DjuiBase* defaultElementBase;
|
||||
};
|
||||
|
||||
static struct DjuiPanel* sPanelList = NULL;
|
||||
static struct DjuiPanel* sPanelRemoving = NULL;
|
||||
static f32 sMoveAmount = 0;
|
||||
|
||||
bool djui_panel_is_active(void) {
|
||||
return (sPanelList != NULL);
|
||||
}
|
||||
|
||||
void djui_panel_add(struct DjuiBase* caller, struct DjuiBase* panelBase, struct DjuiBase* defaultElementBase) {
|
||||
bool firstPanel = (sPanelList == NULL);
|
||||
gDjuiPanelJoinMessageVisible = false;
|
||||
|
||||
// remember element that triggered this panel add
|
||||
if (sPanelList != NULL) {
|
||||
sPanelList->defaultElementBase = caller;
|
||||
}
|
||||
|
||||
// hide second from the top immediately
|
||||
if (sPanelList != NULL && sPanelList->parent != NULL) {
|
||||
djui_base_set_visible(sPanelList->parent->base, false);
|
||||
}
|
||||
|
||||
// allocate panel
|
||||
struct DjuiPanel* panel = malloc(sizeof(struct DjuiPanel));
|
||||
panel->parent = sPanelList;
|
||||
panel->base = panelBase;
|
||||
panel->defaultElementBase = defaultElementBase;
|
||||
sPanelList = panel;
|
||||
|
||||
// deselect cursor input
|
||||
djui_cursor_input_controlled_center(NULL);
|
||||
|
||||
// hide new panel off screen initially
|
||||
djui_base_set_location(panelBase, 0, -gDjuiRoot->base.height.value);
|
||||
|
||||
// disable panels
|
||||
djui_base_set_enabled(panel->base, false);
|
||||
if (panel->parent != NULL) {
|
||||
djui_base_set_enabled(panel->parent->base, false);
|
||||
}
|
||||
|
||||
// reset move amount
|
||||
sMoveAmount = 0;
|
||||
|
||||
if (firstPanel) {
|
||||
djui_base_set_location(panelBase, 0, 0);
|
||||
djui_cursor_input_controlled_center(panel->defaultElementBase);
|
||||
djui_base_set_enabled(panel->base, true);
|
||||
} else {
|
||||
play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_panel_back(void) {
|
||||
if (sPanelList == NULL) { return; }
|
||||
if (sPanelList->parent == NULL) {
|
||||
if (gDjuiPanelPauseCreated) { djui_panel_shutdown(); }
|
||||
return;
|
||||
}
|
||||
|
||||
// deselect cursor input
|
||||
djui_cursor_input_controlled_center(NULL);
|
||||
|
||||
// remember which panel to remove
|
||||
sPanelRemoving = sPanelList;
|
||||
|
||||
// disable old active
|
||||
djui_base_set_enabled(sPanelRemoving->base, false);
|
||||
|
||||
// set the previous active
|
||||
sPanelList = sPanelList->parent;
|
||||
|
||||
// reset move amount
|
||||
sMoveAmount = 0;
|
||||
|
||||
// set new active as visible
|
||||
djui_base_set_visible(sPanelList->base, true);
|
||||
|
||||
// play a sound
|
||||
play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs);
|
||||
|
||||
gDjuiPanelJoinMessageVisible = false;
|
||||
}
|
||||
|
||||
void djui_panel_update(void) {
|
||||
if (sPanelList == NULL) { return; }
|
||||
if (sPanelList->base == NULL) { return; }
|
||||
if (sPanelList->base->elem.height == 0) { return; }
|
||||
|
||||
struct DjuiBase* activeBase = sPanelList->base;
|
||||
struct DjuiBase* parentBase = (sPanelList->parent == NULL) ? NULL : sPanelList->parent->base;
|
||||
struct DjuiBase* removingBase = (sPanelRemoving == NULL) ? NULL : sPanelRemoving->base;
|
||||
|
||||
float moveMax = activeBase->elem.height;
|
||||
if (sMoveAmount >= moveMax) { return; }
|
||||
|
||||
sMoveAmount += moveMax / 10.0f;
|
||||
if (sMoveAmount >= moveMax) {
|
||||
sMoveAmount = moveMax;
|
||||
if (parentBase != NULL) {
|
||||
djui_base_set_visible(parentBase, false);
|
||||
}
|
||||
djui_base_set_enabled(activeBase, true);
|
||||
djui_cursor_input_controlled_center(sPanelList->defaultElementBase);
|
||||
|
||||
if (removingBase != NULL) {
|
||||
djui_base_destroy(removingBase);
|
||||
free(sPanelRemoving);
|
||||
sPanelRemoving = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (removingBase != NULL) {
|
||||
activeBase->y.value = moveMax - moveMax * smoothstep(0, moveMax, sMoveAmount);
|
||||
if (sPanelRemoving != NULL) {
|
||||
removingBase->y.value = activeBase->y.value - removingBase->elem.height;
|
||||
}
|
||||
} else if (parentBase != NULL) {
|
||||
activeBase->y.value = moveMax * smoothstep(0, moveMax, sMoveAmount) - moveMax;
|
||||
parentBase->y.value = activeBase->y.value + moveMax;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_panel_shutdown(void) {
|
||||
struct DjuiPanel* panel = sPanelList;
|
||||
while (panel != NULL) {
|
||||
struct DjuiPanel* next = panel->parent;
|
||||
djui_base_destroy(panel->base);
|
||||
free(panel);
|
||||
panel = next;
|
||||
}
|
||||
|
||||
sPanelList = NULL;
|
||||
sPanelRemoving = NULL;
|
||||
sMoveAmount = 0;
|
||||
gInteractableOverridePad = false;
|
||||
gDjuiPanelJoinMessageVisible = false;
|
||||
gDjuiPanelMainCreated = false;
|
||||
gDjuiPanelPauseCreated = false;
|
||||
djui_cursor_set_visible(false);
|
||||
}
|
11
src/pc/djui/djui_panel.h
Normal file
11
src/pc/djui/djui_panel.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
#define DJUI_DEFAULT_PANEL_WIDTH (410.0f + (16 * 2.0f))
|
||||
#define DJUI_PANEL_HEADER_OFFSET (-8)
|
||||
|
||||
bool djui_panel_is_active(void);
|
||||
void djui_panel_add(struct DjuiBase* caller, struct DjuiBase* panelBase, struct DjuiBase* defaultElementBase);
|
||||
void djui_panel_back(void);
|
||||
void djui_panel_update(void);
|
||||
void djui_panel_shutdown(void);
|
62
src/pc/djui/djui_panel_camera.c
Normal file
62
src/pc/djui/djui_panel_camera.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
void djui_panel_camera_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 32 * 10 + 64 * 1 + 16 * 10;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\C\\#1be700\\A\\#00b3ff\\M\\#ffef00\\E\\#ff0800\\R\\#1be700\\A");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
|
||||
{
|
||||
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(&body->base, "Free Camera", &configEnableCamera);
|
||||
djui_base_set_size_type(&checkbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox1->base, 1.0f, 32);
|
||||
defaultBase = &checkbox1->base;
|
||||
|
||||
struct DjuiCheckbox* checkbox2 = djui_checkbox_create(&body->base, "Analog Camera", &configCameraAnalog);
|
||||
djui_base_set_size_type(&checkbox2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox2->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox3 = djui_checkbox_create(&body->base, "Mouse Look", &configCameraMouse);
|
||||
djui_base_set_size_type(&checkbox3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox3->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox4 = djui_checkbox_create(&body->base, "Invert X", &configCameraInvertX);
|
||||
djui_base_set_size_type(&checkbox4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox4->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox5 = djui_checkbox_create(&body->base, "Invert Y", &configCameraInvertY);
|
||||
djui_base_set_size_type(&checkbox5->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox5->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider1 = djui_slider_create(&body->base, "X Sensitivity", &configCameraXSens, 1, 100);
|
||||
djui_base_set_size_type(&slider1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider1->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider2 = djui_slider_create(&body->base, "Y Sensitivity", &configCameraYSens, 1, 100);
|
||||
djui_base_set_size_type(&slider2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider2->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider3 = djui_slider_create(&body->base, "Aggression", &configCameraAggr, 0, 100);
|
||||
djui_base_set_size_type(&slider3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider3->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider4 = djui_slider_create(&body->base, "Pan Level", &configCameraPan, 0, 100);
|
||||
djui_base_set_size_type(&slider4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider4->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider5 = djui_slider_create(&body->base, "Deceleration", &configCameraDegrade, 0, 100);
|
||||
djui_base_set_size_type(&slider5->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider5->base, 1.0f, 32);
|
||||
|
||||
struct DjuiButton* button6 = djui_button_create(&body->base, "Back");
|
||||
djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button6->base, 1.0f, 64);
|
||||
djui_button_set_style(button6, 1);
|
||||
djui_interactable_hook_click(&button6->base, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_camera.h
Normal file
4
src/pc/djui/djui_panel_camera.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_camera_create(struct DjuiBase* caller);
|
47
src/pc/djui/djui_panel_cheats.c
Normal file
47
src/pc/djui/djui_panel_cheats.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "djui.h"
|
||||
#include "pc/cheats.h"
|
||||
|
||||
void djui_panel_cheats_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 32 * 5 + 64 * 1 + 16 * 6;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\C\\#1be700\\H\\#00b3ff\\E\\#ffef00\\A\\#ff0800\\T\\#1be700\\S");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
|
||||
{
|
||||
{
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon jump", &Cheats.MoonJump);
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
defaultBase = &checkbox->base;
|
||||
}
|
||||
{
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God mode", &Cheats.GodMode);
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
}
|
||||
{
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite lives", &Cheats.InfiniteLives);
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
}
|
||||
{
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super speed", &Cheats.SuperSpeed);
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
}
|
||||
{
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive controls", &Cheats.Responsive);
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
}
|
||||
|
||||
struct DjuiButton* button1 = djui_button_create(&body->base, "Back");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 1.0f, 64);
|
||||
djui_button_set_style(button1, 1);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_cheats.h
Normal file
4
src/pc/djui/djui_panel_cheats.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_cheats_create(struct DjuiBase* caller);
|
38
src/pc/djui/djui_panel_confirm.c
Normal file
38
src/pc/djui/djui_panel_confirm.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
|
||||
void djui_panel_confirm_create(struct DjuiBase* caller, char* title, char* message, void (*on_yes_click)(struct DjuiBase*)) {
|
||||
f32 bodyHeight = 64 * 2 + 16 * 1;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, title);
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiText* text = djui_text_create(&body->base, message);
|
||||
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text->base, 1.0f, 64);
|
||||
djui_base_set_color(&text->base, 200, 200, 200, 255);
|
||||
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
|
||||
struct DjuiRect* rect1 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect1->base, 1.0f, 64);
|
||||
djui_base_set_color(&rect1->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&rect1->base, "No");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
|
||||
defaultBase = &button1->base;
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&rect1->base, "Yes");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button2->base, on_yes_click);
|
||||
}
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
5
src/pc/djui/djui_panel_confirm.h
Normal file
5
src/pc/djui/djui_panel_confirm.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_confirm_create(struct DjuiBase* caller, char* title, char* message, void (*on_yes_click)(struct DjuiBase*));
|
||||
|
49
src/pc/djui/djui_panel_controls.c
Normal file
49
src/pc/djui/djui_panel_controls.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
void djui_panel_controls_create(struct DjuiBase* caller) {
|
||||
f32 bindBodyHeight = 32 * 11 + 1 * 10;
|
||||
f32 bodyHeight = bindBodyHeight + 16 * 3 + 32 * 2 + 64;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\C\\#1be700\\O\\#00b3ff\\N\\#ffef00\\T\\#ff0800\\R\\#1be700\\O\\#00b3ff\\L\\#ffef00\\S");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiFlowLayout* bindBody = djui_flow_layout_create(&body->base);
|
||||
djui_base_set_size_type(&bindBody->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&bindBody->base, 1.0f, bindBodyHeight);
|
||||
djui_base_set_color(&bindBody->base, 0, 0, 0, 0);
|
||||
djui_flow_layout_set_margin(bindBody, 1);
|
||||
{
|
||||
struct DjuiBind* bind1 = djui_bind_create(&bindBody->base, "A", configKeyA);
|
||||
djui_bind_create(&bindBody->base, "B", configKeyB);
|
||||
djui_bind_create(&bindBody->base, "Start", configKeyStart);
|
||||
djui_bind_create(&bindBody->base, "L", configKeyL);
|
||||
djui_bind_create(&bindBody->base, "R", configKeyR);
|
||||
djui_bind_create(&bindBody->base, "Z", configKeyZ);
|
||||
djui_bind_create(&bindBody->base, "C Up", configKeyCUp);
|
||||
djui_bind_create(&bindBody->base, "C Down", configKeyCDown);
|
||||
djui_bind_create(&bindBody->base, "C Left", configKeyCLeft);
|
||||
djui_bind_create(&bindBody->base, "C Right", configKeyCRight);
|
||||
djui_bind_create(&bindBody->base, "Chat", configKeyChat);
|
||||
defaultBase = &bind1->buttons[0]->base;
|
||||
}
|
||||
|
||||
struct DjuiSlider* slider1 = djui_slider_create(&body->base, "Deadzone", &configStickDeadzone, 0, 100);
|
||||
djui_base_set_size_type(&slider1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider1->base, 1.0f, 32);
|
||||
|
||||
struct DjuiSlider* slider2 = djui_slider_create(&body->base, "Rumble Strength", &configRumbleStrength, 0, 100);
|
||||
djui_base_set_size_type(&slider2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&slider2->base, 1.0f, 32);
|
||||
|
||||
struct DjuiButton* button6 = djui_button_create(&body->base, "Back");
|
||||
djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button6->base, 1.0f, 64);
|
||||
djui_button_set_style(button6, 1);
|
||||
djui_interactable_hook_click(&button6->base, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_controls.h
Normal file
4
src/pc/djui/djui_panel_controls.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_controls_create(struct DjuiBase* caller);
|
66
src/pc/djui/djui_panel_debug.c
Normal file
66
src/pc/djui/djui_panel_debug.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include "djui.h"
|
||||
|
||||
static struct DjuiRect* sDjuiRect = NULL;
|
||||
static struct DjuiText* sDjuiText = NULL;
|
||||
|
||||
static struct DjuiRect* sDjuiRect2 = NULL;
|
||||
static struct DjuiText* sDjuiText2 = NULL;
|
||||
|
||||
static void djui_panel_debug_render_pre(struct DjuiBase* base, bool* skipRender) {
|
||||
static u32 sTimer = 0;
|
||||
sTimer++;
|
||||
if (sDjuiText != NULL) {
|
||||
djui_base_set_location(&sDjuiText->base,
|
||||
32.0f + cos(sTimer / 20.0f) * 100.0f,
|
||||
32.0f + sin(sTimer / 62.0f) * 50.0f);
|
||||
djui_text_set_font_scale(sDjuiText, 16.0f + sin((sTimer) / 72.0f) * 4.0f);
|
||||
}
|
||||
|
||||
if (sDjuiText2 != NULL) {
|
||||
djui_base_set_location(&sDjuiText2->base,
|
||||
32.0f + cos(sTimer / 20.0f) * 100.0f,
|
||||
32.0f + sin(sTimer / 62.0f) * 100.0f);
|
||||
djui_text_set_font_scale(sDjuiText2, 64.0f + sin((sTimer) / 72.0f) * 8.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void djui_panel_debug_create(void) {
|
||||
sDjuiRect = djui_rect_create(&gDjuiRoot->base);
|
||||
djui_base_set_location(&sDjuiRect->base, 64, 64);
|
||||
djui_base_set_size(&sDjuiRect->base, 300, 100);
|
||||
djui_base_set_color(&sDjuiRect->base, 0, 0, 0, 255);
|
||||
djui_base_set_alignment(&sDjuiRect->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
sDjuiRect->base.on_render_pre = djui_panel_debug_render_pre;
|
||||
|
||||
sDjuiText = djui_text_create(&sDjuiRect->base, "hello\nworld");
|
||||
djui_base_set_location(&sDjuiText->base, 0, 0);
|
||||
djui_base_set_size(&sDjuiText->base, 300, 300);
|
||||
djui_base_set_color(&sDjuiText->base, 255, 255, 255, 255);
|
||||
djui_text_set_drop_shadow(sDjuiText, 255, 0, 0, 255);
|
||||
djui_text_set_alignment(sDjuiText, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
|
||||
sDjuiRect2 = djui_rect_create(&gDjuiRoot->base);
|
||||
djui_base_set_location(&sDjuiRect2->base, 64, 64);
|
||||
djui_base_set_size(&sDjuiRect2->base, 300, 100);
|
||||
djui_base_set_color(&sDjuiRect2->base, 100, 100, 100, 255);
|
||||
djui_base_set_alignment(&sDjuiRect2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM);
|
||||
|
||||
sDjuiText2 = djui_text_create(&sDjuiRect2->base, "hello\nworld");
|
||||
djui_base_set_location(&sDjuiText2->base, 0, 0);
|
||||
djui_base_set_size(&sDjuiText2->base, 400, 400);
|
||||
djui_base_set_color(&sDjuiText2->base, 255, 255, 255, 255);
|
||||
djui_text_set_drop_shadow(sDjuiText2, 255, 0, 0, 255);
|
||||
djui_text_set_alignment(sDjuiText2, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_text_set_font(sDjuiText2, &gDjuiFonts[1]);
|
||||
|
||||
struct DjuiText* alphabet = djui_text_create(&gDjuiRoot->base, "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n01234567890\nthe quick brown fox jumps over the lazy dog\ngeqkbnfjsortelydg\nTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOG\nGEQKBNFJSORTELYDG");
|
||||
djui_base_set_location(&alphabet->base, 0, 0);
|
||||
djui_base_set_size(&alphabet->base, 400, 400);
|
||||
djui_base_set_size_type(&alphabet->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&alphabet->base, 1, 1);
|
||||
djui_base_set_color(&alphabet->base, 255, 255, 255, 255);
|
||||
djui_text_set_drop_shadow(alphabet, 255, 0, 0, 255);
|
||||
djui_text_set_alignment(alphabet, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_text_set_font(alphabet, &gDjuiFonts[1]);
|
||||
djui_text_set_font_scale(alphabet, 64);
|
||||
}
|
4
src/pc/djui/djui_panel_debug.h
Normal file
4
src/pc/djui/djui_panel_debug.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_debug_create(void);
|
45
src/pc/djui/djui_panel_display.c
Normal file
45
src/pc/djui/djui_panel_display.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
static void djui_panel_display_apply(struct DjuiBase* caller) {
|
||||
configWindow.settings_changed = true;
|
||||
}
|
||||
|
||||
void djui_panel_display_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 32 * 5 + 64 * 1 + 16 * 4;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\D\\#1be700\\I\\#00b3ff\\S\\#ffef00\\P\\#ff0800\\L\\#1be700\\A\\#00b3ff\\Y");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
|
||||
{
|
||||
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(&body->base, "Fullscreen", &configWindow.fullscreen);
|
||||
djui_base_set_size_type(&checkbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox1->base, 1.0f, 32);
|
||||
djui_interactable_hook_value_change(&checkbox1->base, djui_panel_display_apply);
|
||||
defaultBase = &checkbox1->base;
|
||||
|
||||
struct DjuiCheckbox* checkbox2 = djui_checkbox_create(&body->base, "VSync", &configWindow.vsync);
|
||||
djui_base_set_size_type(&checkbox2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox2->base, 1.0f, 32);
|
||||
djui_interactable_hook_value_change(&checkbox2->base, djui_panel_display_apply);
|
||||
|
||||
struct DjuiCheckbox* checkbox4 = djui_checkbox_create(&body->base, "HUD", &configHUD);
|
||||
djui_base_set_size_type(&checkbox4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox4->base, 1.0f, 32);
|
||||
|
||||
char* choices[3] = { "Nearest", "Linear", "Tripoint" };
|
||||
struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(&body->base, "Filtering", choices, 3, &configFiltering);
|
||||
djui_base_set_size_type(&selectionbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&selectionbox1->base, 1.0f, 32);
|
||||
|
||||
struct DjuiButton* button6 = djui_button_create(&body->base, "Back");
|
||||
djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button6->base, 1.0f, 64);
|
||||
djui_button_set_style(button6, 1);
|
||||
djui_interactable_hook_click(&button6->base, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_display.h
Normal file
4
src/pc/djui/djui_panel_display.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_display_create(struct DjuiBase* caller);
|
178
src/pc/djui/djui_panel_host.c
Normal file
178
src/pc/djui/djui_panel_host.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
#include <stdio.h>
|
||||
#include "djui.h"
|
||||
#include "game/save_file.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/cheats.h"
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
#define DJUI_HOST_NS_IS_SOCKET (configNetworkSystem == 1)
|
||||
#else
|
||||
#define DJUI_HOST_NS_IS_SOCKET (true)
|
||||
#endif
|
||||
|
||||
struct DjuiInputbox* sInputboxPort = NULL;
|
||||
static unsigned int sKnockbackIndex = 0;
|
||||
|
||||
static void djui_panel_host_network_system_change(struct DjuiBase* base) {
|
||||
struct DjuiSelectionbox* selectionbox = (struct DjuiSelectionbox*)base;
|
||||
djui_base_set_enabled(&sInputboxPort->base, DJUI_HOST_NS_IS_SOCKET);
|
||||
}
|
||||
|
||||
static bool djui_panel_host_port_valid(void) {
|
||||
char* buffer = sInputboxPort->buffer;
|
||||
int port = 0;
|
||||
while (*buffer != '\0') {
|
||||
if (*buffer < '0' || *buffer > '9') { return false; }
|
||||
port *= 10;
|
||||
port += (*buffer - '0');
|
||||
buffer++;
|
||||
}
|
||||
return port >= 1024 && port <= 65535;
|
||||
}
|
||||
|
||||
static void djui_panel_host_port_text_change(struct DjuiBase* caller) {
|
||||
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
|
||||
if (djui_panel_host_port_valid()) {
|
||||
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
|
||||
} else {
|
||||
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_panel_host_knockback_change(struct DjuiBase* caller) {
|
||||
switch (sKnockbackIndex) {
|
||||
case 0: configPlayerKnockbackStrength = 10; break;
|
||||
case 1: configPlayerKnockbackStrength = 25; break;
|
||||
default: configPlayerKnockbackStrength = 75; break;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_panel_host_do_host(struct DjuiBase* caller) {
|
||||
if (!djui_panel_host_port_valid()) {
|
||||
djui_interactable_set_input_focus(&sInputboxPort->base);
|
||||
djui_inputbox_select_all(sInputboxPort);
|
||||
return;
|
||||
}
|
||||
configHostPort = atoi(sInputboxPort->buffer);
|
||||
djui_panel_host_message_create(caller);
|
||||
}
|
||||
|
||||
void djui_panel_host_create(struct DjuiBase* caller) {
|
||||
#ifdef DISCORD_SDK
|
||||
f32 bodyHeight = 32 * 7 + 64 * 2 + 16 * 9;
|
||||
#else
|
||||
f32 bodyHeight = 32 * 6 + 64 * 2 + 16 * 8;
|
||||
#endif
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\H\\#1be700\\O\\#00b3ff\\S\\#ffef00\\T");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
#ifdef DISCORD_SDK
|
||||
char* nChoices[2] = { "Discord", "Direct Connection" };
|
||||
struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(&body->base, "Network system", nChoices, 2, &configNetworkSystem);
|
||||
djui_base_set_size_type(&selectionbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&selectionbox1->base, 1.0f, 32);
|
||||
djui_interactable_hook_value_change(&selectionbox1->base, djui_panel_host_network_system_change);
|
||||
#endif
|
||||
|
||||
struct DjuiRect* rect1 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect1->base, 1.0f, 32);
|
||||
djui_base_set_color(&rect1->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiText* text1 = djui_text_create(&rect1->base, "Port");
|
||||
djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_color(&text1->base, 200, 200, 200, 255);
|
||||
djui_base_set_size(&text1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
|
||||
struct DjuiInputbox* inputbox1 = djui_inputbox_create(&rect1->base, 32);
|
||||
djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&inputbox1->base, 0.5f, 32);
|
||||
djui_base_set_alignment(&inputbox1->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
char portString[32] = { 0 };
|
||||
snprintf(portString, 32, "%d", configHostPort);
|
||||
djui_inputbox_set_text(inputbox1, portString);
|
||||
djui_interactable_hook_value_change(&inputbox1->base, djui_panel_host_port_text_change);
|
||||
#ifdef DISCORD_SDK
|
||||
djui_base_set_enabled(&inputbox1->base, DJUI_HOST_NS_IS_SOCKET);
|
||||
#endif
|
||||
sInputboxPort = inputbox1;
|
||||
}
|
||||
|
||||
struct DjuiRect* rect2 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect2->base, 1.0f, 32);
|
||||
djui_base_set_color(&rect2->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiText* text1 = djui_text_create(&rect2->base, "Save Slot");
|
||||
djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_color(&text1->base, 200, 200, 200, 255);
|
||||
djui_base_set_size(&text1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
|
||||
char starString[32] = { 0 };
|
||||
snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(configHostSaveSlot - 1, 0, 24));
|
||||
struct DjuiButton* button1 = djui_button_create(&rect2->base, starString);
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.5f, 32);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_host_save_create);
|
||||
}
|
||||
|
||||
char* iChoices[3] = { "Non-solid", "Solid", "Friendly Fire" };
|
||||
struct DjuiSelectionbox* selectionbox2 = djui_selectionbox_create(&body->base, "Player interaction", iChoices, 3, &configPlayerInteraction);
|
||||
djui_base_set_size_type(&selectionbox2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&selectionbox2->base, 1.0f, 32);
|
||||
|
||||
char* kChoices[3] = { "Weak", "Normal", "Too much" };
|
||||
sKnockbackIndex = (configPlayerKnockbackStrength <= 20)
|
||||
? 0
|
||||
: ((configPlayerKnockbackStrength <= 40) ? 1 : 2);
|
||||
struct DjuiSelectionbox* selectionbox3 = djui_selectionbox_create(&body->base, "Knockback strength", kChoices, 3, &sKnockbackIndex);
|
||||
djui_base_set_size_type(&selectionbox3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&selectionbox3->base, 1.0f, 32);
|
||||
djui_interactable_hook_value_change(&selectionbox3->base, djui_panel_host_knockback_change);
|
||||
|
||||
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(&body->base, "Stay in level after star", &configStayInLevelAfterStar);
|
||||
djui_base_set_size_type(&checkbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox1->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox2 = djui_checkbox_create(&body->base, "Play intro cutscene", &configSkipIntro);
|
||||
djui_base_set_size_type(&checkbox2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox2->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox3 = djui_checkbox_create(&body->base, "Share lives", &configShareLives);
|
||||
djui_base_set_size_type(&checkbox3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox3->base, 1.0f, 32);
|
||||
|
||||
struct DjuiCheckbox* checkbox4 = djui_checkbox_create(&body->base, "Enable cheats", &configEnableCheats);
|
||||
djui_base_set_size_type(&checkbox4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox4->base, 1.0f, 32);
|
||||
|
||||
struct DjuiRect* rect3 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect3->base, 1.0f, 64);
|
||||
djui_base_set_color(&rect3->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&rect3->base, "Back");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_button_set_style(button1, 1);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&rect3->base, "Host");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_host_do_host);
|
||||
defaultBase = &button2->base;
|
||||
}
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_host.h
Normal file
4
src/pc/djui/djui_panel_host.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_host_create(struct DjuiBase* caller);
|
109
src/pc/djui/djui_panel_host_message.c
Normal file
109
src/pc/djui/djui_panel_host_message.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include <stdio.h>
|
||||
#include "djui.h"
|
||||
#include "src/pc/network/network.h"
|
||||
#include "src/pc/network/discord/discord.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
static char* sWarningDiscord = "\
|
||||
Invite friends by right clicking their name on Discord and clicking on\n\
|
||||
'\\#d0d0ff\\Invite to Game\\#c8c8c8\\'.\n\n\
|
||||
You can invite channels of servers as well by clicking the \\#d0d0ff\\plus\\#c8c8c8\\ button next to the place where you enter chat.\n\n\
|
||||
Game Activity \\#ffa0a0\\must be\\#c8c8c8\\ enabled in your\nDiscord user settings.\n\n\
|
||||
Appearing offline \\#ffa0a0\\will prevent\\#c8c8c8\\ invites from being sent.\
|
||||
";
|
||||
static char* sWarningDiscord2 = "\\#ffa0a0\\Error:\\#c8c8c8\\ Could not detect Discord.\n\n\\#a0a0a0\\Try closing the game,\nrestarting Discord,\nand opening the game again.";
|
||||
#endif
|
||||
|
||||
static char* sWarningSocket = "\
|
||||
Direct connections \\#ffa0a0\\require you\\#c8c8c8\\ to configure port forwarding in your router.\n\n\
|
||||
Forward port '\\#d0d0ff\\%d\\#c8c8c8\\' for UDP.\
|
||||
";
|
||||
|
||||
void djui_panel_host_message_do_host(struct DjuiBase* caller) {
|
||||
djui_panel_shutdown();
|
||||
extern s16 gCurrSaveFileNum;
|
||||
gCurrSaveFileNum = configHostSaveSlot;
|
||||
#ifndef DISCORD_SDK
|
||||
configNetworkSystem = 1;
|
||||
network_set_system(NS_SOCKET);
|
||||
#else
|
||||
if (configNetworkSystem == 0) {
|
||||
network_set_system(NS_DISCORD);
|
||||
} else {
|
||||
network_set_system(NS_SOCKET);
|
||||
}
|
||||
#endif
|
||||
network_init(NT_SERVER);
|
||||
extern s16 gChangeLevel;
|
||||
gChangeLevel = 16;
|
||||
}
|
||||
|
||||
void djui_panel_host_message_create(struct DjuiBase* caller) {
|
||||
f32 warningLines = 0;
|
||||
char* warningMessage = NULL;
|
||||
bool hideHostButton = false;
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
if (!configNetworkSystem) {
|
||||
warningLines = gDiscordFailed ? 5 : 13;
|
||||
warningMessage = gDiscordFailed ? sWarningDiscord2 : sWarningDiscord;
|
||||
hideHostButton = gDiscordFailed;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
warningLines = 5;
|
||||
warningMessage = malloc(sizeof(char) * 256);
|
||||
sprintf(warningMessage, sWarningSocket, configHostPort);
|
||||
}
|
||||
|
||||
f32 textHeight = 32 * 0.8125f * warningLines + 8;
|
||||
f32 bodyHeight = textHeight + 16 + 64;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\I\\#1be700\\N\\#00b3ff\\F\\#ffef00\\O");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiText* text1 = djui_text_create(&body->base, warningMessage);
|
||||
djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text1->base, 1.0f, textHeight);
|
||||
djui_base_set_color(&text1->base, 200, 200, 200, 255);
|
||||
|
||||
struct DjuiRect* rect1 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect1->base, 1.0f, 64);
|
||||
djui_base_set_color(&rect1->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&rect1->base, "Back");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_button_set_style(button1, 1);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&rect1->base, "Host");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_host_message_do_host);
|
||||
defaultBase = &button2->base;
|
||||
|
||||
if (hideHostButton) {
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 1.0f, 64);
|
||||
defaultBase = &button1->base;
|
||||
djui_base_set_visible(&button2->base, false);
|
||||
djui_base_set_enabled(&button2->base, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
#ifdef DISCORD_SDK
|
||||
if (configNetworkSystem)
|
||||
#endif
|
||||
{
|
||||
free(warningMessage);
|
||||
}
|
||||
}
|
4
src/pc/djui/djui_panel_host_message.h
Normal file
4
src/pc/djui/djui_panel_host_message.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_host_message_create(struct DjuiBase* caller);
|
67
src/pc/djui/djui_panel_host_save.c
Normal file
67
src/pc/djui/djui_panel_host_save.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include <stdio.h>
|
||||
#include "djui.h"
|
||||
#include "game/save_file.h"
|
||||
#include "pc/configfile.h"
|
||||
|
||||
static struct DjuiBase* sSaveButtonCaller = NULL;
|
||||
static struct DjuiButton* sSaveButtons[4] = { NULL };
|
||||
|
||||
static void djui_panel_host_save_update_button(struct DjuiButton* button, int slot) {
|
||||
char starString[32] = { 0 };
|
||||
snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(slot, 0, 24));
|
||||
djui_text_set_text(button->text, starString);
|
||||
}
|
||||
|
||||
static void djui_panel_host_save_button_click(struct DjuiBase* caller) {
|
||||
configHostSaveSlot = caller->tag + 1;
|
||||
djui_panel_host_save_update_button((struct DjuiButton*)sSaveButtonCaller, configHostSaveSlot - 1);
|
||||
djui_panel_menu_back(caller);
|
||||
}
|
||||
|
||||
static void djui_panel_host_save_erase_yes(struct DjuiBase* caller) {
|
||||
save_file_erase(caller->tag);
|
||||
djui_panel_host_save_update_button(sSaveButtons[caller->tag], caller->tag);
|
||||
djui_panel_menu_back(caller);
|
||||
}
|
||||
|
||||
static void djui_panel_host_save_erase(struct DjuiBase* caller) {
|
||||
djui_panel_confirm_create(caller,
|
||||
"\\#ff0800\\E\\#1be700\\R\\#00b3ff\\A\\#ffef00\\S\\#ff0800\\E",
|
||||
"Are you sure you want to erase this save slot?",
|
||||
djui_panel_host_save_erase_yes);
|
||||
}
|
||||
|
||||
void djui_panel_host_save_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 32 * 4 + 64 * 1 + 16 * 5;
|
||||
sSaveButtonCaller = caller;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\S\\#1be700\\A\\#00b3ff\\V\\#ffef00\\E");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
struct DjuiRect* rect1 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect1->base, 1.0f, 32);
|
||||
djui_base_set_color(&rect1->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&rect1->base, "");
|
||||
djui_panel_host_save_update_button(button1, i);
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.74f, 32);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_host_save_button_click);
|
||||
button1->base.tag = i;
|
||||
if (i == (int)(configHostSaveSlot - 1)) { defaultBase = &button1->base; }
|
||||
sSaveButtons[i] = button1;
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&rect1->base, "erase");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 0.24f, 32);
|
||||
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_host_save_erase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_host_save.h
Normal file
4
src/pc/djui/djui_panel_host_save.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_host_save_create(struct DjuiBase* caller);
|
212
src/pc/djui/djui_panel_join.c
Normal file
212
src/pc/djui/djui_panel_join.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
#include <stdio.h>
|
||||
#include "djui.h"
|
||||
#include "src/pc/network/network.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
static char* sJoiningDiscord = "\
|
||||
To join a \\#d0d0ff\\Discord\\#c8c8c8\\ lobby:\n\n\
|
||||
Keep the game open and click the join button on the invite.\n\n\
|
||||
If the invite says that the game has ended, click the name of the person that sent the invite to refresh it.\
|
||||
";
|
||||
#endif
|
||||
|
||||
static char* sJoiningDirect = "\
|
||||
Enter \\#d0d0ff\\direct connection\\#c8c8c8\\ IP and port:\
|
||||
";
|
||||
|
||||
static struct DjuiInputbox* sInputboxIp = NULL;
|
||||
|
||||
static bool djui_panel_join_ip_parse_numbers(char** msg) {
|
||||
int num = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char c = **msg;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// is number
|
||||
num *= 10;
|
||||
num += (c - '0');
|
||||
*msg = *msg + 1;
|
||||
} else if (i == 0) {
|
||||
return false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return num >= 0 && num <= 127;
|
||||
}
|
||||
|
||||
static bool djui_panel_join_ip_parse_period(char** msg) {
|
||||
char c = **msg;
|
||||
bool isPeriod = (c == '.');
|
||||
if (isPeriod) { *msg = *msg + 1; }
|
||||
return isPeriod;
|
||||
}
|
||||
|
||||
static bool djui_panel_join_ip_parse_spacer(char** msg) {
|
||||
char c = **msg;
|
||||
bool isSpacer = (c == ':' || c == ' ');
|
||||
if (isSpacer) { *msg = *msg + 1; }
|
||||
return isSpacer;
|
||||
}
|
||||
|
||||
static bool djui_panel_join_ip_parse_port(char** msg) {
|
||||
int num = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
char c = **msg;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// is number
|
||||
num *= 10;
|
||||
num += (c - '0');
|
||||
*msg = *msg + 1;
|
||||
} else if (i == 0) {
|
||||
return false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return num >= 1024 && num <= 65535;
|
||||
}
|
||||
|
||||
static bool djui_panel_join_ip_valid(char* buffer) {
|
||||
char** msg = &buffer;
|
||||
if (!djui_panel_join_ip_parse_numbers(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_period(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_numbers(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_period(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_numbers(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_period(msg)) { return false; }
|
||||
if (!djui_panel_join_ip_parse_numbers(msg)) { return false; }
|
||||
if (djui_panel_join_ip_parse_spacer(msg)) {
|
||||
if (!djui_panel_join_ip_parse_port(msg)) { return false; }
|
||||
}
|
||||
|
||||
return (**msg == '\0');
|
||||
}
|
||||
|
||||
static void djui_panel_join_ip_text_change(struct DjuiBase* caller) {
|
||||
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
|
||||
if (djui_panel_join_ip_valid(inputbox1->buffer)) {
|
||||
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
|
||||
} else {
|
||||
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_panel_join_ip_text_set_new(void) {
|
||||
char buffer[256] = { 0 };
|
||||
snprintf(buffer, 256, "%s", sInputboxIp->buffer);
|
||||
|
||||
bool afterSpacer = false;
|
||||
int port = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (buffer[i] == ' ' || buffer[i] == ':') {
|
||||
buffer[i] = '\0';
|
||||
afterSpacer = true;
|
||||
} else if (buffer[i] == '\0') {
|
||||
break;
|
||||
} else if (afterSpacer && buffer[i] >= '0' && buffer[i] <= '9') {
|
||||
port *= 10;
|
||||
port += buffer[i] - '0';
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(configJoinIp, MAX_CONFIG_STRING, "%s", buffer);
|
||||
if (port >= 1 && port <= 65535) {
|
||||
configJoinPort = port;
|
||||
} else {
|
||||
configJoinPort = DEFAULT_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_panel_join_ip_text_set(struct DjuiInputbox* inputbox1) {
|
||||
char buffer[256] = { 0 };
|
||||
if (strlen(configJoinIp) > 0 && configJoinPort != DEFAULT_PORT) {
|
||||
snprintf(buffer, 256, "%s:%d", configJoinIp, configJoinPort);
|
||||
} else if (strlen(configJoinIp) > 0) {
|
||||
snprintf(buffer, 256, "%s", configJoinIp);
|
||||
} else {
|
||||
snprintf(buffer, 256, "127.0.0.1");
|
||||
}
|
||||
|
||||
djui_inputbox_set_text(inputbox1, buffer);
|
||||
djui_inputbox_select_all(inputbox1);
|
||||
}
|
||||
|
||||
void djui_panel_join_do_join(struct DjuiBase* caller) {
|
||||
if (!djui_panel_join_ip_valid(sInputboxIp->buffer)) {
|
||||
djui_interactable_set_input_focus(&sInputboxIp->base);
|
||||
djui_inputbox_select_all(sInputboxIp);
|
||||
return;
|
||||
}
|
||||
djui_panel_join_ip_text_set_new();
|
||||
network_set_system(NS_SOCKET);
|
||||
network_init(NT_CLIENT);
|
||||
djui_panel_join_message_create(caller);
|
||||
}
|
||||
|
||||
void djui_panel_join_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 2 + 32 + 16 * 2 + 64;
|
||||
|
||||
u16 directLines = 1;
|
||||
f32 directTextHeight = 32 * 0.8125f * directLines + 8;
|
||||
bodyHeight += directTextHeight + 16;
|
||||
|
||||
#ifdef DISCORD_SDK
|
||||
u16 discordLines = 8;
|
||||
f32 discordTextHeight = 32 * 0.8125f * discordLines + 8;
|
||||
bodyHeight += discordTextHeight + 16;
|
||||
#endif
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\J\\#1be700\\O\\#00b3ff\\I\\#ffef00\\N");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
#ifdef DISCORD_SDK
|
||||
struct DjuiText* text1 = djui_text_create(&body->base, sJoiningDiscord);
|
||||
djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text1->base, 1.0f, discordTextHeight);
|
||||
djui_base_set_color(&text1->base, 200, 200, 200, 255);
|
||||
#endif
|
||||
struct DjuiRect* rect1 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect1->base, 1.0f, 2);
|
||||
djui_base_set_color(&rect1->base, 150, 150, 150, 255);
|
||||
|
||||
struct DjuiText* text2 = djui_text_create(&body->base, sJoiningDirect);
|
||||
djui_base_set_size_type(&text2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text2->base, 1.0f, directTextHeight);
|
||||
djui_base_set_color(&text2->base, 200, 200, 200, 255);
|
||||
|
||||
struct DjuiInputbox* inputbox1 = djui_inputbox_create(&body->base, 256);
|
||||
djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&inputbox1->base, 1.0f, 32.0f);
|
||||
djui_interactable_hook_value_change(&inputbox1->base, djui_panel_join_ip_text_change);
|
||||
sInputboxIp = inputbox1;
|
||||
djui_panel_join_ip_text_set(inputbox1);
|
||||
|
||||
struct DjuiRect* rect2 = djui_rect_create(&body->base);
|
||||
djui_base_set_size_type(&rect2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&rect2->base, 1.0f, 64);
|
||||
djui_base_set_color(&rect2->base, 0, 0, 0, 0);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&rect2->base, "Back");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_button_set_style(button1, 1);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_menu_back);
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&rect2->base, "Join");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 0.485f, 64);
|
||||
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_join_do_join);
|
||||
defaultBase = &button2->base;
|
||||
}
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_join.h
Normal file
4
src/pc/djui/djui_panel_join.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_join_create(struct DjuiBase* caller);
|
75
src/pc/djui/djui_panel_join_message.c
Normal file
75
src/pc/djui/djui_panel_join_message.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/network/network.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
#define DJUI_JOIN_MESSAGE_ELAPSE 60
|
||||
bool gDjuiPanelJoinMessageVisible = false;
|
||||
static struct DjuiText* sPanelText = NULL;
|
||||
static bool sDisplayingError = false;
|
||||
|
||||
void djui_panel_join_message_error(char* message) {
|
||||
djui_panel_join_message_create(NULL);
|
||||
sDisplayingError = true;
|
||||
djui_text_set_text(sPanelText, message);
|
||||
}
|
||||
|
||||
void djui_panel_join_message_cancel(struct DjuiBase* caller) {
|
||||
network_shutdown(true);
|
||||
djui_panel_menu_back(caller);
|
||||
}
|
||||
|
||||
void djui_panel_join_message_render_pre(struct DjuiBase* base, UNUSED bool* unused) {
|
||||
if (sDisplayingError) { return; }
|
||||
struct DjuiText* text1 = (struct DjuiText*)base;
|
||||
u16 lastElapse = (base->tag / DJUI_JOIN_MESSAGE_ELAPSE);
|
||||
base->tag = (base->tag + 1) % (DJUI_JOIN_MESSAGE_ELAPSE * 3);
|
||||
u16 elapse = (base->tag / DJUI_JOIN_MESSAGE_ELAPSE);
|
||||
if (lastElapse != elapse) {
|
||||
switch (base->tag / DJUI_JOIN_MESSAGE_ELAPSE) {
|
||||
case 0: djui_text_set_text(text1, "..."); break;
|
||||
case 1: djui_text_set_text(text1, "."); break;
|
||||
default: djui_text_set_text(text1, ".."); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void djui_panel_join_message_create(struct DjuiBase* caller) {
|
||||
// make sure main panel was created
|
||||
if (!gDjuiPanelMainCreated) { djui_panel_main_create(caller); }
|
||||
|
||||
// don't recreate panel if it's already visible
|
||||
if (gDjuiPanelJoinMessageVisible) { return; }
|
||||
|
||||
f32 bodyHeight = 64 + 16;
|
||||
|
||||
u16 directLines = 8;
|
||||
f32 directTextHeight = 32 * 0.8125f * directLines + 8;
|
||||
bodyHeight += directTextHeight + 16;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\J\\#1be700\\O\\#00b3ff\\I\\#ffef00\\N\\#1be700\\I\\#00b3ff\\N\\#ffef00\\G");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiText* text1 = djui_text_create(&body->base, "...");
|
||||
djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&text1->base, 1.0f, directTextHeight);
|
||||
djui_base_set_color(&text1->base, 200, 200, 200, 255);
|
||||
djui_text_set_alignment(text1, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
text1->base.tag = 0;
|
||||
text1->base.on_render_pre = djui_panel_join_message_render_pre;
|
||||
sPanelText = text1;
|
||||
|
||||
struct DjuiButton* button1 = djui_button_create(&body->base, "Cancel");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 1.0f, 64);
|
||||
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_button_set_style(button1, 1);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_join_message_cancel);
|
||||
defaultBase = &button1->base;
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
gDjuiPanelJoinMessageVisible = true;
|
||||
sDisplayingError = false;
|
||||
}
|
7
src/pc/djui/djui_panel_join_message.h
Normal file
7
src/pc/djui/djui_panel_join_message.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
extern bool gDjuiPanelJoinMessageVisible;
|
||||
|
||||
void djui_panel_join_message_error(char* message);
|
||||
void djui_panel_join_message_create(struct DjuiBase* caller);
|
60
src/pc/djui/djui_panel_main.c
Normal file
60
src/pc/djui/djui_panel_main.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/controller/controller_sdl.h"
|
||||
|
||||
bool gDjuiPanelMainCreated = false;
|
||||
|
||||
static void djui_panel_main_quit_yes(struct DjuiBase* caller) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void djui_panel_main_quit(struct DjuiBase* caller) {
|
||||
djui_panel_confirm_create(caller,
|
||||
"\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T",
|
||||
"Are you sure you want to quit?",
|
||||
djui_panel_main_quit_yes);
|
||||
}
|
||||
|
||||
void djui_panel_main_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 64 * 4 + 16 * 3;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\SM\\#1be700\\64\\#00b3ff\\EX\n\\#ffef00\\COOP");
|
||||
{
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
struct DjuiButton* button1 = djui_button_create(&body->base, "Host");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 1.0f, 64);
|
||||
djui_cursor_input_controlled_center(&button1->base);
|
||||
djui_interactable_hook_click(&button1->base, djui_panel_host_create);
|
||||
defaultBase = &button1->base;
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&body->base, "Join");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_join_create);
|
||||
|
||||
struct DjuiButton* button3 = djui_button_create(&body->base, "Options");
|
||||
djui_base_set_size_type(&button3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button3->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button3->base, djui_panel_options_create);
|
||||
|
||||
struct DjuiButton* button4 = djui_button_create(&body->base, "Quit");
|
||||
djui_base_set_size_type(&button4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button4->base, 1.0f, 64);
|
||||
djui_button_set_style(button4, 1);
|
||||
djui_interactable_hook_click(&button4->base, djui_panel_main_quit);
|
||||
}
|
||||
|
||||
char* version = get_version();
|
||||
struct DjuiText* footer = djui_text_create(&panel->base, version);
|
||||
djui_base_set_size_type(&footer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&footer->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&footer->base, 50, 50, 50, 255);
|
||||
djui_text_set_alignment(footer, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
gInteractableOverridePad = true;
|
||||
gDjuiPanelMainCreated = true;
|
||||
}
|
6
src/pc/djui/djui_panel_main.h
Normal file
6
src/pc/djui/djui_panel_main.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
extern bool gDjuiPanelMainCreated;
|
||||
|
||||
void djui_panel_main_create(struct DjuiBase* caller);
|
36
src/pc/djui/djui_panel_menu.c
Normal file
36
src/pc/djui/djui_panel_menu.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
#include "src/pc/configfile.h"
|
||||
|
||||
void djui_panel_menu_back(struct DjuiBase* base) {
|
||||
djui_panel_back();
|
||||
}
|
||||
|
||||
struct DjuiThreePanel* djui_panel_menu_create(f32 bodyHeight, char* headerText) {
|
||||
struct DjuiThreePanel* panel = djui_three_panel_create(&gDjuiRoot->base, 64, bodyHeight, 0);
|
||||
djui_base_set_size_type(&panel->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&panel->base, DJUI_DEFAULT_PANEL_WIDTH, 1.0f);
|
||||
djui_base_set_color(&panel->base, 0, 0, 0, 240);
|
||||
djui_base_set_border_color(&panel->base, 0, 0, 0, 200);
|
||||
djui_base_set_border_width(&panel->base, 8);
|
||||
djui_base_set_padding(&panel->base, 16, 16, 16, 16);
|
||||
{
|
||||
struct DjuiText* header = djui_text_create(&panel->base, headerText);
|
||||
djui_base_set_size_type(&header->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&header->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&header->base, 255, 8, 0, 255);
|
||||
djui_base_set_location(&header->base, 0, DJUI_PANEL_HEADER_OFFSET);
|
||||
djui_text_set_alignment(header, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
|
||||
djui_text_set_font(header, &gDjuiFonts[1]);
|
||||
djui_text_set_font_scale(header, gDjuiFonts[1].defaultFontScale);
|
||||
|
||||
struct DjuiFlowLayout* body = djui_flow_layout_create(&panel->base);
|
||||
djui_base_set_alignment(&body->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&body->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&body->base, 1.0f, bodyHeight);
|
||||
djui_base_set_color(&body->base, 0, 0, 0, 0);
|
||||
djui_flow_layout_set_margin(body, 16);
|
||||
djui_flow_layout_set_flow_direction(body, DJUI_FLOW_DIR_DOWN);
|
||||
}
|
||||
return panel;
|
||||
}
|
5
src/pc/djui/djui_panel_menu.h
Normal file
5
src/pc/djui/djui_panel_menu.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_menu_back(struct DjuiBase* base);
|
||||
struct DjuiThreePanel* djui_panel_menu_create(f32 bodyHeight, char* headerText);
|
45
src/pc/djui/djui_panel_options.c
Normal file
45
src/pc/djui/djui_panel_options.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "djui.h"
|
||||
#include "src/pc/utils/misc.h"
|
||||
|
||||
void djui_panel_options_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 64 * 5 + 16 * 4;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\O\\#1be700\\P\\#00b3ff\\T\\#ffef00\\I\\#ff0800\\O\\#1be700\\N\\#00b3ff\\S");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
{
|
||||
/*struct DjuiButton* button1 = djui_button_create(&body->base, "Player");
|
||||
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button1->base, 1.0f, 64);
|
||||
defaultBase = &button1->base;*/
|
||||
|
||||
struct DjuiButton* button2 = djui_button_create(&body->base, "Camera");
|
||||
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button2->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button2->base, djui_panel_camera_create);
|
||||
defaultBase = &button2->base;
|
||||
|
||||
struct DjuiButton* button3 = djui_button_create(&body->base, "Controls");
|
||||
djui_base_set_size_type(&button3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button3->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button3->base, djui_panel_controls_create);
|
||||
|
||||
struct DjuiButton* button4 = djui_button_create(&body->base, "Display");
|
||||
djui_base_set_size_type(&button4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button4->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button4->base, djui_panel_display_create);
|
||||
|
||||
struct DjuiButton* button5 = djui_button_create(&body->base, "Sound");
|
||||
djui_base_set_size_type(&button5->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button5->base, 1.0f, 64);
|
||||
djui_interactable_hook_click(&button5->base, djui_panel_sound_create);
|
||||
|
||||
struct DjuiButton* button6 = djui_button_create(&body->base, "Back");
|
||||
djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button6->base, 1.0f, 64);
|
||||
djui_button_set_style(button6, 1);
|
||||
djui_interactable_hook_click(&button6->base, djui_panel_menu_back);
|
||||
}
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
}
|
4
src/pc/djui/djui_panel_options.h
Normal file
4
src/pc/djui/djui_panel_options.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "djui.h"
|
||||
|
||||
void djui_panel_options_create(struct DjuiBase* caller);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue