mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Generate dynamic model lists with CMake, + refactor
* When building with CMake, dynamic model lists are now generated * Factored common code out of generate_*_list.js files to deduplicate * Better separated generated model lists from main game code `dynamic_asset_data.c` and `dynamic_animated_asset_data.c` previously #included the corresponding generated headers, and `dynamic_asset_loader.c` declared externs for the contents. This messiness was likely done so the generated code would be built automatically (the Makefile globs all C files under `src/`). Now, model list data is output to C source files which are built explicitly. This, with some refactoring, allows the previously mentioned source files and externs to be removed. This is a bit hacky in the Makefile but will be automatic under CMake by using target properties. * Reorganized some files under `tools/`
This commit is contained in:
parent
9643719a31
commit
1d0b22df61
|
@ -19,11 +19,6 @@ set(SOX "sox")
|
|||
set(VPK "vpk")
|
||||
set(VTF2PNG "vtf2png")
|
||||
|
||||
set(CONVERT_ASSET "${PROJECT_SOURCE_DIR}/tools/convert_asset.py")
|
||||
set(EXPORT_FBX "${PROJECT_SOURCE_DIR}/tools/export_fbx.py")
|
||||
set(GEN_LEVEL_LIST "${PROJECT_SOURCE_DIR}/tools/generate_level_list.js")
|
||||
set(GEN_SOUND_IDS "${PROJECT_SOURCE_DIR}/tools/generate_sound_ids.js")
|
||||
set(JSOX "${PROJECT_SOURCE_DIR}/tools/jsox.js")
|
||||
set(SKELETOOL64 "${PROJECT_SOURCE_DIR}/skelatool64/skeletool64")
|
||||
|
||||
# Directories
|
||||
|
|
28
Makefile
28
Makefile
|
@ -359,7 +359,9 @@ ANIM_LIST = build/assets/models/pedestal_anim.o \
|
|||
build/assets/models/props/switch001_anim.o
|
||||
|
||||
MODEL_HEADERS = $(MODEL_LIST:%.blend=build/%.h)
|
||||
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o)
|
||||
MODEL_OBJECTS = $(MODEL_LIST:%.blend=build/%_geo.o) \
|
||||
build/assets/models/dynamic_model_list.o \
|
||||
build/assets/models/dynamic_animated_model_list.o
|
||||
|
||||
DYNAMIC_MODEL_HEADERS = $(DYNAMIC_MODEL_LIST:%.blend=build/%.h)
|
||||
DYNAMIC_MODEL_OBJECTS = $(DYNAMIC_MODEL_LIST:%.blend=build/%_geo.o)
|
||||
|
@ -415,8 +417,6 @@ build/src/scene/render_plan.o: $(MODEL_HEADERS)
|
|||
build/src/scene/security_camera.o: build/src/audio/clips.h build/assets/models/props/security_camera.h build/assets/models/dynamic_animated_model_list.h
|
||||
build/src/scene/signage.o: $(MODEL_HEADERS)
|
||||
build/src/scene/switch.o: build/assets/models/props/switch001.h build/assets/materials/static.h build/assets/models/dynamic_animated_model_list.h
|
||||
build/src/util/dynamic_asset_data.o: build/assets/models/dynamic_model_list_data.h
|
||||
build/src/util/dynamic_animated_asset_data.o: build/assets/models/dynamic_animated_model_list_data.h
|
||||
build/src/util/dynamic_asset_loader.o: build/assets/models/dynamic_model_list.h build/assets/models/dynamic_animated_model_list.h
|
||||
build/src/menu/audio_options.o: build/src/audio/subtitles.h
|
||||
build/src/menu/video_options.o: build/src/audio/subtitles.h
|
||||
|
@ -460,7 +460,7 @@ LUA_FILES = $(shell find tools/ -type f -name '*.lua')
|
|||
|
||||
build/%.fbx: %.blend
|
||||
@mkdir -p $(@D)
|
||||
$(BLENDER_3_6) $< --background --python tools/export_fbx.py -- $@
|
||||
$(BLENDER_3_6) $< --background --python tools/models/export_fbx.py -- $@
|
||||
|
||||
build/assets/test_chambers/%.h build/assets/test_chambers/%_geo.c build/assets/test_chambers/%_anim.c: build/assets/test_chambers/%.fbx assets/test_chambers/%.yaml build/assets/materials/static.h build/src/audio/subtitles.h $(SKELATOOL64) $(TEXTURE_IMAGES) $(LUA_FILES)
|
||||
$(SKELATOOL64) --script tools/level_scripts/export_level.lua --fixed-point-scale ${SCENE_SCALE} --model-scale 0.01 --name $(<:build/assets/test_chambers/%.fbx=%) -m assets/materials/static.skm.yaml -o $(<:%.fbx=%.h) $<
|
||||
|
@ -478,17 +478,17 @@ build/assets/materials/%_mat.o: build/assets/materials/%_mat.c
|
|||
levels: $(TEST_CHAMBER_HEADERS)
|
||||
echo $(TEST_CHAMBER_HEADERS)
|
||||
|
||||
build/assets/test_chambers/level_list.h: $(TEST_CHAMBER_HEADERS) tools/generate_level_list.js
|
||||
build/assets/test_chambers/level_list.h: $(TEST_CHAMBER_HEADERS) tools/models/generate_level_list.js tools/models/model_list_utils.js
|
||||
@mkdir -p $(@D)
|
||||
node tools/generate_level_list.js $@ $(TEST_CHAMBER_HEADERS)
|
||||
node tools/models/generate_level_list.js $@ $(TEST_CHAMBER_HEADERS)
|
||||
|
||||
build/assets/models/dynamic_model_list.h build/assets/models/dynamic_model_list_data.h: $(DYNAMIC_MODEL_HEADERS) tools/generate_dynamic_model_list.js build/assets/models/cube/cube.h
|
||||
build/assets/models/dynamic_model_list.h build/assets/models/dynamic_model_list.c: $(DYNAMIC_MODEL_HEADERS) tools/models/generate_dynamic_model_list.js tools/models/model_list_utils.js build/assets/models/cube/cube.h
|
||||
@mkdir -p $(@D)
|
||||
node tools/generate_dynamic_model_list.js build/assets/models/dynamic_model_list.h build/assets/models/dynamic_model_list_data.h $(DYNAMIC_MODEL_HEADERS)
|
||||
node tools/models/generate_dynamic_model_list.js build/assets/models/dynamic_model_list.h $(DYNAMIC_MODEL_HEADERS)
|
||||
|
||||
build/assets/models/dynamic_animated_model_list.h build/assets/models/dynamic_animated_model_list_data.h: $(DYNAMIC_ANIMATED_MODEL_HEADERS) tools/generate_dynamic_animated_model_list.js
|
||||
build/assets/models/dynamic_animated_model_list.h build/assets/models/dynamic_animated_model_list.c: $(DYNAMIC_ANIMATED_MODEL_HEADERS) tools/models/generate_dynamic_animated_model_list.js tools/models/model_list_utils.js
|
||||
@mkdir -p $(@D)
|
||||
node tools/generate_dynamic_animated_model_list.js build/assets/models/dynamic_animated_model_list.h build/assets/models/dynamic_animated_model_list_data.h $(DYNAMIC_ANIMATED_MODEL_HEADERS)
|
||||
node tools/models/generate_dynamic_animated_model_list.js build/assets/models/dynamic_animated_model_list.h $(DYNAMIC_ANIMATED_MODEL_HEADERS)
|
||||
|
||||
build/levels.ld: $(TEST_CHAMBER_OBJECTS) tools/generate_level_ld.js
|
||||
@mkdir -p $(@D)
|
||||
|
@ -536,9 +536,9 @@ build/assets/%.aifc: assets/%.sox portal_pak_dir/%.wav
|
|||
sox $(<:assets/%.sox=portal_pak_dir/%.wav) $(shell cat $<) $(@:%.aifc=%.wav)
|
||||
$(SFZ2N64) -o $@ $(@:%.aifc=%.wav)
|
||||
|
||||
build/assets/%.aifc: assets/%.jsox tools/jsox.js portal_pak_dir/%.wav
|
||||
build/assets/%.aifc: assets/%.jsox tools/sound/jsox.js portal_pak_dir/%.wav
|
||||
@mkdir -p $(@D)
|
||||
node tools/jsox.js $< $(<:assets/%.jsox=portal_pak_dir/%.wav) $(@:%.aifc=%.wav)
|
||||
node tools/sound/jsox.js $< $(<:assets/%.jsox=portal_pak_dir/%.wav) $(@:%.aifc=%.wav)
|
||||
$(SFZ2N64) -o $@ $(@:%.aifc=%.wav)
|
||||
|
||||
build/assets/%.aifc: assets/%.msox portal_pak_dir/%.mp3
|
||||
|
@ -554,9 +554,9 @@ build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl: $(SOUND_C
|
|||
|
||||
build/asm/sound_data.o: build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl
|
||||
|
||||
build/src/audio/clips.h build/src/audio/languages.h build/src/audio/languages.c: tools/generate_sound_ids.js $(SOUND_CLIPS)
|
||||
build/src/audio/clips.h build/src/audio/languages.h build/src/audio/languages.c: tools/sound/generate_sound_ids.js $(SOUND_CLIPS)
|
||||
@mkdir -p $(@D)
|
||||
node tools/generate_sound_ids.js -o $(@D) -p SOUNDS_ $(SOUND_CLIPS)
|
||||
node tools/sound/generate_sound_ids.js -o $(@D) -p SOUNDS_ $(SOUND_CLIPS)
|
||||
|
||||
build/src/audio/clips.o: build/src/audio/clips.h
|
||||
build/src/decor/decor_object_list.o: build/src/audio/clips.h
|
||||
|
|
|
@ -24,6 +24,11 @@ set(MODEL_SCALE 0.01)
|
|||
# Scaling factor for render space
|
||||
set(SCENE_SCALE 128)
|
||||
|
||||
# Tools for asset conversion
|
||||
set(CONVERT_ASSET "${PROJECT_SOURCE_DIR}/tools/convert_asset.py")
|
||||
set(EXPORT_FBX "${PROJECT_SOURCE_DIR}/tools/models/export_fbx.py")
|
||||
set(MODEL_LIST_UTILS "${PROJECT_SOURCE_DIR}/tools/models/model_list_utils.js")
|
||||
|
||||
add_subdirectory(materials)
|
||||
add_subdirectory(models)
|
||||
add_subdirectory(sound)
|
||||
|
|
|
@ -1,14 +1,51 @@
|
|||
cmake_path(
|
||||
RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR
|
||||
BASE_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE RELATIVE_CURRENT_DIR
|
||||
)
|
||||
|
||||
##################
|
||||
## Model export ##
|
||||
##################
|
||||
|
||||
# TODO: dynamic and animated models
|
||||
|
||||
set(MODELS
|
||||
# Models whose data is loaded/unloaded as needed
|
||||
set(DYNAMIC_MODELS
|
||||
cube/cube
|
||||
props/autoportal_frame/autoportal_frame
|
||||
props/box_dropper_glass
|
||||
props/cylinder_test
|
||||
props/lab_chair
|
||||
props/lab_desk/lab_desk01
|
||||
props/lab_desk/lab_desk02
|
||||
props/lab_desk/lab_desk03
|
||||
props/lab_desk/lab_desk04
|
||||
props/lab_monitor
|
||||
props/light_rail_endcap
|
||||
props/portal_cleanser
|
||||
props/radio
|
||||
signage/clock
|
||||
signage/clock_digits
|
||||
)
|
||||
|
||||
# Animated models whose data is loaded/unloaded as needed
|
||||
set(DYNAMIC_ANIMATED_MODELS
|
||||
pedestal
|
||||
props/box_dropper
|
||||
props/button
|
||||
props/combine_ball_catcher
|
||||
props/combine_ball_launcher
|
||||
props/door_01
|
||||
props/door_02
|
||||
props/security_camera
|
||||
props/switch001
|
||||
)
|
||||
|
||||
# All models
|
||||
set(MODELS
|
||||
${DYNAMIC_MODELS}
|
||||
${DYNAMIC_ANIMATED_MODELS}
|
||||
fleck_ash2
|
||||
grav_flare
|
||||
pedestal
|
||||
player/chell
|
||||
portal_gun/ball_trail
|
||||
portal_gun/v_portalgun
|
||||
|
@ -21,32 +58,10 @@ set(MODELS
|
|||
portal/portal_orange
|
||||
portal/portal_orange_face
|
||||
portal/portal_orange_filled
|
||||
props/autoportal_frame/autoportal_frame
|
||||
props/box_dropper
|
||||
props/box_dropper_glass
|
||||
props/button
|
||||
props/combine_ball_catcher
|
||||
props/combine_ball_launcher
|
||||
props/cylinder_test
|
||||
props/door_01
|
||||
props/door_02
|
||||
props/lab_chair
|
||||
props/lab_desk/lab_desk01
|
||||
props/lab_desk/lab_desk02
|
||||
props/lab_desk/lab_desk03
|
||||
props/lab_desk/lab_desk04
|
||||
props/lab_monitor
|
||||
props/light_rail_endcap
|
||||
props/portal_cleanser
|
||||
props/radio
|
||||
props/round_elevator
|
||||
props/round_elevator_collision
|
||||
props/round_elevator_interior
|
||||
props/security_camera
|
||||
props/signage
|
||||
props/switch001
|
||||
signage/clock
|
||||
signage/clock_digits
|
||||
)
|
||||
|
||||
# Most models depend on both of these. Some only depend on one or the other,
|
||||
|
@ -56,13 +71,10 @@ set(MODEL_DEFAULT_MATERIALS
|
|||
${ASSETS_DIR}/materials/objects.skm.yaml
|
||||
)
|
||||
|
||||
function(_add_model_export_command MODEL_NAME OUTPUT_VARIABLE)
|
||||
cmake_path(
|
||||
RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR
|
||||
BASE_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE RELATIVE_CURRENT_DIR
|
||||
)
|
||||
set(GEN_DYNAMIC_MODEL_LIST "${PROJECT_SOURCE_DIR}/tools/models/generate_dynamic_model_list.js")
|
||||
set(GEN_DYNAMIC_ANIM_MODEL_LIST "${PROJECT_SOURCE_DIR}/tools/models/generate_dynamic_animated_model_list.js")
|
||||
|
||||
function(_add_model_export_command MODEL_NAME OUTPUT_VARIABLE)
|
||||
set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}.blend")
|
||||
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/${RELATIVE_CURRENT_DIR}/${MODEL_NAME}.fbx")
|
||||
|
||||
|
@ -121,7 +133,7 @@ function(_add_model_generate_command MODEL_NAME MODEL_FBX OUTPUT_LIST)
|
|||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR}
|
||||
COMMAND
|
||||
${CONVERT_ASSET}
|
||||
${PYTHON3} ${CONVERT_ASSET}
|
||||
${SKELETOOL64}
|
||||
${MODEL_FBX}
|
||||
${MODEL_FLAGS}
|
||||
|
@ -184,3 +196,73 @@ add_custom_target(
|
|||
models
|
||||
DEPENDS ${MODEL_GENERATED_FILES}
|
||||
)
|
||||
|
||||
# Add commands for generating dynamic model lists
|
||||
|
||||
set(MODEL_GENERATED_HEADERS ${MODEL_GENERATED_FILES})
|
||||
list(FILTER MODEL_GENERATED_HEADERS INCLUDE REGEX "\.h$")
|
||||
|
||||
set(DYNAMIC_MODEL_HEADERS "")
|
||||
set(DYNAMIC_ANIMATED_MODEL_HEADERS "")
|
||||
|
||||
foreach(GENERATED_HEADER ${MODEL_GENERATED_HEADERS})
|
||||
cmake_path(
|
||||
RELATIVE_PATH GENERATED_HEADER
|
||||
BASE_DIRECTORY "${CMAKE_BINARY_DIR}/${RELATIVE_CURRENT_DIR}"
|
||||
OUTPUT_VARIABLE MODEL_NAME
|
||||
)
|
||||
cmake_path(
|
||||
REMOVE_EXTENSION MODEL_NAME
|
||||
OUTPUT_VARIABLE MODEL_NAME
|
||||
)
|
||||
|
||||
if(MODEL_NAME IN_LIST DYNAMIC_MODELS)
|
||||
list(APPEND DYNAMIC_MODEL_HEADERS ${GENERATED_HEADER})
|
||||
elseif(MODEL_NAME IN_LIST DYNAMIC_ANIMATED_MODELS)
|
||||
list(APPEND DYNAMIC_ANIMATED_MODEL_HEADERS ${GENERATED_HEADER})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(DYNAMIC_MODEL_LIST_OUT_DIR "${CMAKE_BINARY_DIR}/${RELATIVE_CURRENT_DIR}")
|
||||
|
||||
set(DYNAMIC_MODEL_LIST_H "${DYNAMIC_MODEL_LIST_OUT_DIR}/dynamic_model_list.h")
|
||||
set(DYNAMIC_MODEL_LIST_C "${DYNAMIC_MODEL_LIST_OUT_DIR}/dynamic_model_list.c")
|
||||
add_custom_command(
|
||||
DEPENDS
|
||||
${GEN_DYNAMIC_MODEL_LIST} ${MODEL_LIST_UTILS} ${DYNAMIC_MODEL_HEADERS}
|
||||
OUTPUT
|
||||
${DYNAMIC_MODEL_LIST_H} ${DYNAMIC_MODEL_LIST_C}
|
||||
COMMAND
|
||||
${NODEJS} ${GEN_DYNAMIC_MODEL_LIST}
|
||||
${DYNAMIC_MODEL_LIST_H}
|
||||
${DYNAMIC_MODEL_HEADERS}
|
||||
COMMENT
|
||||
"Generating dynamic model list"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(DYNAMIC_ANIMATED_MODEL_LIST_H "${DYNAMIC_MODEL_LIST_OUT_DIR}/dynamic_animated_model_list.h")
|
||||
set(DYNAMIC_ANIMATED_MODEL_LIST_C "${DYNAMIC_MODEL_LIST_OUT_DIR}/dynamic_animated_model_list.c")
|
||||
add_custom_command(
|
||||
DEPENDS
|
||||
${GEN_DYNAMIC_ANIM_MODEL_LIST} ${MODEL_LIST_UTILS} ${DYNAMIC_ANIMATED_MODEL_HEADERS}
|
||||
OUTPUT
|
||||
${DYNAMIC_ANIMATED_MODEL_LIST_H} ${DYNAMIC_ANIMATED_MODEL_LIST_C}
|
||||
COMMAND
|
||||
${NODEJS} ${GEN_DYNAMIC_ANIM_MODEL_LIST}
|
||||
${DYNAMIC_ANIMATED_MODEL_LIST_H}
|
||||
${DYNAMIC_ANIMATED_MODEL_HEADERS}
|
||||
COMMENT
|
||||
"Generating dynamic animated model list"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
model_lists
|
||||
DEPENDS
|
||||
${MODEL_GENERATED_FILES}
|
||||
${DYNAMIC_MODEL_LIST_H}
|
||||
${DYNAMIC_MODEL_LIST_C}
|
||||
${DYNAMIC_ANIMATED_MODEL_LIST_H}
|
||||
${DYNAMIC_ANIMATED_MODEL_LIST_C}
|
||||
)
|
||||
|
|
|
@ -186,6 +186,8 @@ set(INSTRUMENT_BANKS
|
|||
weapons/physcannon/energy_sing_loop4.ins
|
||||
)
|
||||
|
||||
set(JSOX "${PROJECT_SOURCE_DIR}/tools/sound/jsox.js")
|
||||
|
||||
# TODO: remove
|
||||
function(_add_sound_transform_command_direct SOUND_NAME ARGS OUTPUT_LIST)
|
||||
set(INPUT_FILE "${PAK_SOUND_DIR}/${SOUND_NAME}.wav")
|
||||
|
@ -251,7 +253,7 @@ function(_add_sound_transform_command_sox SOUND_SCRIPT INPUT_FILE OUTPUT_FILE)
|
|||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR}
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE} ${CONVERT_ASSET} ${SOX} ${INPUT_FILE} ${SOUND_SCRIPT} ${OUTPUT_FILE}
|
||||
${PYTHON3} ${CONVERT_ASSET} ${SOX} ${INPUT_FILE} ${SOUND_SCRIPT} ${OUTPUT_FILE}
|
||||
COMMENT
|
||||
"Transforming $<PATH:RELATIVE_PATH,${INPUT_FILE},${PROJECT_SOURCE_DIR}>"
|
||||
VERBATIM
|
||||
|
@ -373,6 +375,8 @@ add_custom_target(
|
|||
## Sound table generation ##
|
||||
############################
|
||||
|
||||
set(GEN_SOUND_IDS "${PROJECT_SOURCE_DIR}/tools/sound/generate_sound_ids.js")
|
||||
|
||||
set(SOUND_TABLE_DEPENDENCIES ${SOUNDS_CONVERTED})
|
||||
set(SOUND_TABLE_INPUTS "")
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ set(EXPORT_SCRIPTS
|
|||
${PROJECT_SOURCE_DIR}/tools/level_scripts/yaml_loader.lua
|
||||
)
|
||||
|
||||
set(GEN_LEVEL_LIST "${PROJECT_SOURCE_DIR}/tools/models/generate_level_list.js")
|
||||
|
||||
function(_add_level_export_command LEVEL_NAME OUTPUT_VARIABLE)
|
||||
set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${LEVEL_NAME}/${LEVEL_NAME}.blend")
|
||||
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/${RELATIVE_CURRENT_DIR}/${LEVEL_NAME}/${LEVEL_NAME}.fbx")
|
||||
|
@ -144,7 +146,7 @@ set(LEVEL_LIST "${LEVEL_LIST_OUT_DIR}/level_list.h")
|
|||
|
||||
add_custom_command(
|
||||
DEPENDS
|
||||
${GEN_LEVEL_LIST} ${LEVEL_GENERATED_HEADERS}
|
||||
${GEN_LEVEL_LIST} ${MODEL_LIST_UTILS} ${LEVEL_GENERATED_HEADERS}
|
||||
OUTPUT
|
||||
${LEVEL_LIST}
|
||||
COMMAND
|
||||
|
|
|
@ -13,7 +13,7 @@ add_dependencies(portal
|
|||
|
||||
# TODO: rework when including models in compilation
|
||||
level_list
|
||||
models
|
||||
model_lists
|
||||
)
|
||||
|
||||
###############
|
||||
|
@ -159,10 +159,7 @@ target_sources(portal PRIVATE
|
|||
sk64/skelatool_animator.c
|
||||
sk64/skelatool_armature.c
|
||||
util/assert.c
|
||||
util/dynamic_animated_asset_data.c
|
||||
util/dynamic_asset_data.c
|
||||
util/dynamic_asset_loader.c
|
||||
util/linked_list.c
|
||||
util/memory.c
|
||||
util/profile.c
|
||||
util/rom.c
|
||||
|
|
|
@ -117,7 +117,7 @@ void levelLoad(int index) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct LevelMetadata* metadata = &gLevelList[index];
|
||||
struct LevelMetadata* metadata = &gLevels[index];
|
||||
|
||||
void* memory = malloc(metadata->segmentRomEnd - metadata->segmentRomStart);
|
||||
romCopy(metadata->segmentRomStart, memory, metadata->segmentRomEnd - metadata->segmentRomStart);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __LEVEL_LIST_H__
|
||||
#define __LEVEL_LIST_H__
|
||||
#ifndef __LEVELS_H__
|
||||
#define __LEVELS_H__
|
||||
|
||||
#include "physics/collision_object.h"
|
||||
#include "level_definition.h"
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
#include "../build/assets/models/dynamic_animated_model_list_data.h"
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
#include "../build/assets/models/dynamic_model_list_data.h"
|
|
@ -6,9 +6,6 @@
|
|||
#include "../build/assets/models/dynamic_model_list.h"
|
||||
#include "../build/assets/models/dynamic_animated_model_list.h"
|
||||
|
||||
extern struct DynamicAssetModel gDynamicModels[];
|
||||
extern struct DynamicAnimatedAssetModel gDynamicAnimatedModels[];
|
||||
|
||||
Gfx* gLoadedModels[DYNAMIC_MODEL_COUNT];
|
||||
u32 gModelPointerOffset[DYNAMIC_MODEL_COUNT];
|
||||
|
||||
|
|
|
@ -3,27 +3,11 @@
|
|||
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "dynamic_asset_model.h"
|
||||
|
||||
#include "../sk64/skelatool_armature.h"
|
||||
#include "../sk64/skelatool_clip.h"
|
||||
|
||||
struct DynamicAssetModel {
|
||||
void* addressStart;
|
||||
void* addressEnd;
|
||||
void* segmentStart;
|
||||
Gfx* model;
|
||||
char* name;
|
||||
};
|
||||
|
||||
struct DynamicAnimatedAssetModel {
|
||||
void* addressStart;
|
||||
void* addressEnd;
|
||||
void* segmentStart;
|
||||
struct SKArmatureDefinition* armature;
|
||||
struct SKAnimationClip** clips;
|
||||
short clipCount;
|
||||
char* name;
|
||||
};
|
||||
|
||||
struct SKArmatureWithAnimations {
|
||||
struct SKArmatureDefinition* armature;
|
||||
struct SKAnimationClip** clips;
|
||||
|
|
27
src/util/dynamic_asset_model.h
Normal file
27
src/util/dynamic_asset_model.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef __DYNAMIC_ASSET_MODEL_H__
|
||||
#define __DYNAMIC_ASSET_MODEL_H__
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "../sk64/skelatool_armature.h"
|
||||
#include "../sk64/skelatool_clip.h"
|
||||
|
||||
struct DynamicAssetModel {
|
||||
void* addressStart;
|
||||
void* addressEnd;
|
||||
void* segmentStart;
|
||||
Gfx* model;
|
||||
char* name;
|
||||
};
|
||||
|
||||
struct DynamicAnimatedAssetModel {
|
||||
void* addressStart;
|
||||
void* addressEnd;
|
||||
void* segmentStart;
|
||||
struct SKArmatureDefinition* armature;
|
||||
struct SKAnimationClip** clips;
|
||||
short clipCount;
|
||||
char* name;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,104 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function generateInclude(outputLocation, headerLocation) {
|
||||
return `#include "${path.relative(path.dirname(outputLocation), headerLocation)}"`
|
||||
}
|
||||
|
||||
const InvalidTokenCharacter = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
function getSegmentName(headerLocation) {
|
||||
const levelName = path.basename(headerLocation);
|
||||
const noExtension = levelName.slice(0, levelName.length - path.extname(levelName).length);
|
||||
|
||||
return noExtension.replace(InvalidTokenCharacter, '_');
|
||||
}
|
||||
|
||||
function generateArmatureName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_armature';
|
||||
}
|
||||
|
||||
function generateClipsName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_clips';
|
||||
}
|
||||
|
||||
function generateClipCountName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_').toUpperCase() + '_CLIP_COUNT';
|
||||
}
|
||||
|
||||
function generateDynamicModelName(outputLocation, headerLocation, index) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_DYNAMIC_ANIMATED_MODEL';
|
||||
}
|
||||
|
||||
function generateMetadata(outputLocation, headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return ` {
|
||||
_${segmentName}_geoSegmentRomStart,
|
||||
_${segmentName}_geoSegmentRomEnd,
|
||||
_${segmentName}_geoSegmentStart,
|
||||
&${generateArmatureName(outputLocation, headerLocation)},
|
||||
${generateClipsName(outputLocation, headerLocation)},
|
||||
${generateClipCountName(outputLocation, headerLocation)},
|
||||
"${segmentName}",
|
||||
},`;
|
||||
}
|
||||
|
||||
function generateExterns(headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `
|
||||
extern char _${segmentName}_geoSegmentRomStart[];
|
||||
extern char _${segmentName}_geoSegmentRomEnd[];
|
||||
extern char _${segmentName}_geoSegmentStart[];
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
function generateModelList(outputLocation, headerLocations) {
|
||||
return `struct DynamicAnimatedAssetModel gDynamicAnimatedModels[] = {
|
||||
${headerLocations.map(headerLocation => generateMetadata(outputLocation, headerLocation)).join('\n')}
|
||||
};`
|
||||
}
|
||||
|
||||
function generateMetadataDeclaration(outputLocation, headerLocation, index) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `#define ${generateDynamicModelName(outputLocation, headerLocation).toUpperCase()} ${index}`;
|
||||
}
|
||||
|
||||
function generateModelHeaderList(outputLocation, headerLocations) {
|
||||
return headerLocations.map((headerLocation, index) => generateMetadataDeclaration(outputLocation, headerLocation, index)).join('\n');
|
||||
}
|
||||
|
||||
function generateData(outputLocation, headerLocations) {
|
||||
return `#ifndef __DYNAMIC_ANIMATED_MODEL_LIST_DATA_H__
|
||||
#define __DYNAMIC_ANIMATED_MODEL_LIST_DATA_H__
|
||||
|
||||
#include "util/dynamic_asset_loader.h"
|
||||
|
||||
${headerLocations.map(headerLocation => generateInclude(outputLocation, headerLocation)).join('\n')}
|
||||
|
||||
${headerLocations.map(generateExterns).join('\n')}
|
||||
|
||||
${generateModelList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
function generateHeader(outputLocation, headerLocations) {
|
||||
return `#ifndef __DYNAMIC_ANIMATED_MODEL_LIST_DEFINITION_H__
|
||||
#define __DYNAMIC_ANIMATED_MODEL_LIST_DEFINITION_H__
|
||||
|
||||
#define DYNAMIC_ANIMATED_MODEL_COUNT ${headerLocations.length}
|
||||
|
||||
${generateModelHeaderList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(process.argv[2], generateHeader(process.argv[2], process.argv.slice(4)));
|
||||
fs.writeFileSync(process.argv[3], generateData(process.argv[3], process.argv.slice(4)));
|
|
@ -1,92 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function generateInclude(outputLocation, headerLocation) {
|
||||
return `#include "${path.relative(path.dirname(outputLocation), headerLocation)}"`
|
||||
}
|
||||
|
||||
const InvalidTokenCharacter = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
function getSegmentName(headerLocation) {
|
||||
const levelName = path.basename(headerLocation);
|
||||
const noExtension = levelName.slice(0, levelName.length - path.extname(levelName).length);
|
||||
|
||||
return noExtension.replace(InvalidTokenCharacter, '_');
|
||||
}
|
||||
|
||||
function generateModelName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_model_gfx';
|
||||
}
|
||||
|
||||
function generateDynamicModelName(outputLocation, headerLocation, index) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_dynamic_model';
|
||||
}
|
||||
|
||||
function generateMetadata(outputLocation, headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return ` {
|
||||
_${segmentName}_geoSegmentRomStart,
|
||||
_${segmentName}_geoSegmentRomEnd,
|
||||
_${segmentName}_geoSegmentStart,
|
||||
${generateModelName(outputLocation, headerLocation)},
|
||||
"${segmentName}",
|
||||
},`;
|
||||
}
|
||||
|
||||
function generateExterns(headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `
|
||||
extern char _${segmentName}_geoSegmentRomStart[];
|
||||
extern char _${segmentName}_geoSegmentRomEnd[];
|
||||
extern char _${segmentName}_geoSegmentStart[];
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
function generateModelList(outputLocation, headerLocations) {
|
||||
return `struct DynamicAssetModel gDynamicModels[] = {
|
||||
${headerLocations.map(headerLocation => generateMetadata(outputLocation, headerLocation)).join('\n')}
|
||||
};`
|
||||
}
|
||||
|
||||
function generateMetadataDeclaration(outputLocation, headerLocation, index) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `#define ${generateDynamicModelName(outputLocation, headerLocation).toUpperCase()} ${index}`;
|
||||
}
|
||||
|
||||
function generateModelHeaderList(outputLocation, headerLocations) {
|
||||
return headerLocations.map((headerLocation, index) => generateMetadataDeclaration(outputLocation, headerLocation, index)).join('\n');
|
||||
}
|
||||
|
||||
function generateData(outputLocation, headerLocations) {
|
||||
return `#ifndef __DYNAMIC_MODEL_LIST_DATA_H__
|
||||
#define __DYNAMIC_MODEL_LIST_DATA_H__
|
||||
|
||||
#include "util/dynamic_asset_loader.h"
|
||||
|
||||
${headerLocations.map(headerLocation => generateInclude(outputLocation, headerLocation)).join('\n')}
|
||||
|
||||
${headerLocations.map(generateExterns).join('\n')}
|
||||
|
||||
${generateModelList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
function generateHeader(outputLocation, headerLocations) {
|
||||
return `#ifndef __DYNAMIC_MODEL_LIST_DEFINITION_H__
|
||||
#define __DYNAMIC_MODEL_LIST_DEFINITION_H__
|
||||
|
||||
#define DYNAMIC_MODEL_COUNT ${headerLocations.length}
|
||||
|
||||
${generateModelHeaderList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(process.argv[2], generateHeader(process.argv[2], process.argv.slice(4)));
|
||||
fs.writeFileSync(process.argv[3], generateData(process.argv[3], process.argv.slice(4)));
|
|
@ -1,69 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function generateInclude(outputLocation, headerLocation) {
|
||||
return `#include "${path.relative(path.dirname(outputLocation), headerLocation)}"`
|
||||
}
|
||||
|
||||
const InvalidTokenCharacter = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
function getSegmentName(headerLocation) {
|
||||
const levelName = path.basename(headerLocation);
|
||||
const noExtension = levelName.slice(0, levelName.length - path.extname(levelName).length);
|
||||
|
||||
return noExtension.replace(InvalidTokenCharacter, '_');
|
||||
}
|
||||
|
||||
function generateLevelName(outputLocation, headerLocation) {
|
||||
const relative = path.relative(path.dirname(outputLocation), headerLocation).slice(0, -2);
|
||||
return relative.replace(InvalidTokenCharacter, '_') + '_level';
|
||||
}
|
||||
|
||||
function generateMetadata(outputLocation, headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return ` {
|
||||
&${generateLevelName(outputLocation, headerLocation)},
|
||||
_${segmentName}_geoSegmentRomStart,
|
||||
_${segmentName}_geoSegmentRomEnd,
|
||||
_${segmentName}_geoSegmentStart,
|
||||
},`;
|
||||
}
|
||||
|
||||
function generateExterns(headerLocation) {
|
||||
const segmentName = getSegmentName(headerLocation);
|
||||
return `
|
||||
extern char _${segmentName}_geoSegmentRomStart[];
|
||||
extern char _${segmentName}_geoSegmentRomEnd[];
|
||||
extern char _${segmentName}_geoSegmentStart[];
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
function generateLevelList(outputLocation, headerLocations) {
|
||||
return `struct LevelMetadata gLevelList[] = {
|
||||
${headerLocations.map(headerLocation => generateMetadata(outputLocation, headerLocation)).join('\n')}
|
||||
};
|
||||
`;
|
||||
}
|
||||
|
||||
function generateData(outputLocation, headerLocations) {
|
||||
return `#ifndef __BUILD_LEVEL_LIST_H__
|
||||
#define __BUILD_LEVEL_LIST_H__
|
||||
|
||||
#include "levels/level_metadata.h"
|
||||
|
||||
${headerLocations.map(headerLocation => generateInclude(outputLocation, headerLocation)).join('\n')}
|
||||
|
||||
#define LEVEL_COUNT ${headerLocations.length}
|
||||
|
||||
${headerLocations.map(generateExterns).join('\n')}
|
||||
|
||||
${generateLevelList(outputLocation, headerLocations)}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
const output = process.argv[2];
|
||||
|
||||
fs.writeFileSync(output, generateData(output, process.argv.slice(3)));
|
|
@ -1,6 +0,0 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
for (const wav of fs.readdirSync(process.argv[2])) {
|
||||
fs.writeFileSync(path.join(process.argv[3], wav.slice(0, -4)) + '.sox', process.argv[4]);
|
||||
}
|
36
tools/models/generate_dynamic_animated_model_list.js
Normal file
36
tools/models/generate_dynamic_animated_model_list.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const util = require('./model_list_utils');
|
||||
|
||||
function generateModelListEntry(outputPath, modelHeader) {
|
||||
const modelName = util.generateModelName(modelHeader);
|
||||
return ` {
|
||||
_${modelName}_geoSegmentRomStart,
|
||||
_${modelName}_geoSegmentRomEnd,
|
||||
_${modelName}_geoSegmentStart,
|
||||
&${util.generateRelativeModelName(outputPath, modelHeader, '_armature')},
|
||||
${util.generateRelativeModelName(outputPath, modelHeader, '_clips')},
|
||||
${util.generateRelativeModelName(outputPath, modelHeader, '_clip_count').toUpperCase()},
|
||||
"${modelName}",
|
||||
},`;
|
||||
}
|
||||
|
||||
const [outputHeaderFile, ...modelHeaders] = process.argv.slice(2);
|
||||
const { dir: outputDir, name: outputName } = path.parse(outputHeaderFile);
|
||||
const outputSourceFile = `${outputDir}/${outputName}.c`
|
||||
|
||||
const config = {
|
||||
modelHeaders,
|
||||
modelGroup: "dynamic_animated_model",
|
||||
modelType: "DynamicAnimatedAssetModel",
|
||||
listEntryGenerator: generateModelListEntry
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
outputHeaderFile,
|
||||
util.generateHeader(outputHeaderFile, config)
|
||||
);
|
||||
fs.writeFileSync(
|
||||
outputSourceFile,
|
||||
util.generateData(outputSourceFile, config)
|
||||
);
|
34
tools/models/generate_dynamic_model_list.js
Normal file
34
tools/models/generate_dynamic_model_list.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const util = require('./model_list_utils');
|
||||
|
||||
function generateModelListEntry(outputPath, modelHeader) {
|
||||
const modelName = util.generateModelName(modelHeader);
|
||||
return ` {
|
||||
_${modelName}_geoSegmentRomStart,
|
||||
_${modelName}_geoSegmentRomEnd,
|
||||
_${modelName}_geoSegmentStart,
|
||||
${util.generateRelativeModelName(outputPath, modelHeader, '_model_gfx')},
|
||||
"${modelName}",
|
||||
},`;
|
||||
}
|
||||
|
||||
const [outputHeaderFile, ...modelHeaders] = process.argv.slice(2);
|
||||
const { dir: outputDir, name: outputName } = path.parse(outputHeaderFile);
|
||||
const outputSourceFile = `${outputDir}/${outputName}.c`
|
||||
|
||||
const config = {
|
||||
modelHeaders,
|
||||
modelGroup: "dynamic_model",
|
||||
modelType: "DynamicAssetModel",
|
||||
listEntryGenerator: generateModelListEntry
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
outputHeaderFile,
|
||||
util.generateHeader(outputHeaderFile, config)
|
||||
);
|
||||
fs.writeFileSync(
|
||||
outputSourceFile,
|
||||
util.generateData(outputSourceFile, config)
|
||||
);
|
42
tools/models/generate_level_list.js
Normal file
42
tools/models/generate_level_list.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
const fs = require('fs');
|
||||
const util = require('./model_list_utils');
|
||||
|
||||
function generateLevelListEntry(outputPath, levelHeader) {
|
||||
const levelName = util.generateModelName(levelHeader);
|
||||
return ` {
|
||||
&${util.generateRelativeModelName(outputPath, levelHeader, '_level')},
|
||||
_${levelName}_geoSegmentRomStart,
|
||||
_${levelName}_geoSegmentRomEnd,
|
||||
_${levelName}_geoSegmentStart,
|
||||
},`;
|
||||
}
|
||||
|
||||
function generateHeader(outputPath, config) {
|
||||
const { modelHeaders, modelGroup } = config;
|
||||
|
||||
return util.wrapWithIncludeGuard(outputPath,
|
||||
`#include "levels/level_metadata.h"
|
||||
|
||||
${util.generateIncludes(outputPath, modelHeaders)}
|
||||
|
||||
${util.generateCount(modelGroup, modelHeaders)}
|
||||
|
||||
${util.generateExterns(modelHeaders)}
|
||||
|
||||
${util.generateModelList(outputPath, config)}`
|
||||
);
|
||||
}
|
||||
|
||||
const [outputHeaderFile, ...modelHeaders] = process.argv.slice(2);
|
||||
|
||||
const config = {
|
||||
modelHeaders,
|
||||
modelGroup: "level",
|
||||
modelType: "LevelMetadata",
|
||||
listEntryGenerator: generateLevelListEntry
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
outputHeaderFile,
|
||||
generateHeader(outputHeaderFile, config)
|
||||
);
|
132
tools/models/model_list_utils.js
Normal file
132
tools/models/model_list_utils.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
const path = require('path');
|
||||
|
||||
const INVALID_TOKEN_CHARACTER = /[^A-Za-z0-9_]/gim;
|
||||
|
||||
// Common
|
||||
|
||||
function sanitize(s) {
|
||||
return s.replace(INVALID_TOKEN_CHARACTER, '_');
|
||||
}
|
||||
|
||||
function wrapWithIncludeGuard(outputPath, content) {
|
||||
const outputName = path.basename(outputPath);
|
||||
const includeGuardName = `__${sanitize(outputName).toUpperCase()}__`;
|
||||
return `#ifndef ${includeGuardName}
|
||||
#define ${includeGuardName}
|
||||
|
||||
${content}
|
||||
|
||||
#endif
|
||||
`;
|
||||
}
|
||||
|
||||
function generateRelativeModelName(outputPath, modelHeader, suffix='') {
|
||||
const outputDirName = path.dirname(outputPath);
|
||||
const { dir: headerDirName, name: headerName } = path.parse(modelHeader);
|
||||
|
||||
const relative = path.join(
|
||||
path.relative(outputDirName, headerDirName),
|
||||
headerName
|
||||
);
|
||||
|
||||
return sanitize(relative + suffix);
|
||||
}
|
||||
|
||||
function generateModelName(modelHeader) {
|
||||
return generateRelativeModelName(modelHeader, modelHeader);
|
||||
}
|
||||
|
||||
function generateListDefinition(modelGroup, modelType) {
|
||||
const groupPascalCase = modelGroup
|
||||
.split('_')
|
||||
.map(s => s && s.replace(/^(\w)/g, m => m.toUpperCase()))
|
||||
.join('');
|
||||
|
||||
const listName = `g${groupPascalCase}s`;
|
||||
return `struct ${modelType} ${listName}[]`;
|
||||
}
|
||||
|
||||
// Header generation
|
||||
|
||||
function generateCount(modelGroup, modelHeaders) {
|
||||
return `#define ${modelGroup.toUpperCase()}_COUNT ${modelHeaders.length}`;
|
||||
}
|
||||
|
||||
function generateModelIndices(outputPath, modelHeaders, modelGroup) {
|
||||
return modelHeaders.map((modelHeader, index) => {
|
||||
const modelName = generateRelativeModelName(outputPath, modelHeader, `_${modelGroup}`);
|
||||
return `#define ${modelName.toUpperCase()} ${index}`;
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
function generateListExtern(modelGroup, modelType) {
|
||||
return `extern ${generateListDefinition(modelGroup, modelType)};`;
|
||||
}
|
||||
|
||||
function generateHeader(outputPath, config) {
|
||||
const { modelHeaders, modelGroup, modelType } = config;
|
||||
|
||||
return wrapWithIncludeGuard(outputPath,
|
||||
`#include "util/dynamic_asset_model.h"
|
||||
|
||||
${generateCount(modelGroup, modelHeaders)}
|
||||
|
||||
${generateModelIndices(outputPath, modelHeaders, modelGroup)}
|
||||
|
||||
${generateListExtern(modelGroup, modelType)}`
|
||||
);
|
||||
}
|
||||
|
||||
// Data generation
|
||||
|
||||
function generateIncludes(outputPath, modelHeaders) {
|
||||
return modelHeaders.map(modelHeader => {
|
||||
const relativePath = path.relative(path.dirname(outputPath), modelHeader);
|
||||
return `#include "${relativePath}"`;
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
function generateExterns(modelHeaders) {
|
||||
return modelHeaders.map(modelHeader => {
|
||||
const modelName = generateModelName(modelHeader);
|
||||
return `extern char _${modelName}_geoSegmentRomStart[];
|
||||
extern char _${modelName}_geoSegmentRomEnd[];
|
||||
extern char _${modelName}_geoSegmentStart[];`;
|
||||
}).join('\n\n');
|
||||
}
|
||||
|
||||
function generateModelList(outputPath, config) {
|
||||
const { modelHeaders, modelGroup, modelType, listEntryGenerator } = config;
|
||||
|
||||
return `${generateListDefinition(modelGroup, modelType)} = {
|
||||
${modelHeaders.map(modelHeader => listEntryGenerator(outputPath, modelHeader)).join('\n')}
|
||||
};`
|
||||
}
|
||||
|
||||
function generateData(outputPath, config) {
|
||||
const { name } = path.parse(outputPath);
|
||||
const { modelHeaders } = config;
|
||||
|
||||
return `#include "${name}.h"
|
||||
|
||||
${generateIncludes(outputPath, modelHeaders)}
|
||||
|
||||
${generateExterns(modelHeaders)}
|
||||
|
||||
${generateModelList(outputPath, config)}
|
||||
`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
wrapWithIncludeGuard,
|
||||
generateRelativeModelName,
|
||||
generateModelName,
|
||||
|
||||
generateCount,
|
||||
generateHeader,
|
||||
|
||||
generateIncludes,
|
||||
generateExterns,
|
||||
generateModelList,
|
||||
generateData
|
||||
};
|
Loading…
Reference in a new issue