Lunar Porter moves into a directory of its own
The first application with things of its own, and the first customer for all three rungs before it at once. /Apps/Lander a launcher /Packages/app.Lander/Lander.sbx the program /Packages/app.Lander/splash.tune its tune Typing "Lander" starts the launcher, which needs no new rule: the shell runs what it reads, so a launcher beginning "#!" and Say.sbx beginning "SBEX" go down the same road and neither the shell nor the person has to know which kind of thing they started. It passes on what it was told with $args, and says #quiet, because a launcher is machinery and not narration. The game then asks where it came from and joins its tune's name to that, so nothing anywhere names /splash.tune. Every recorded Lander test still types just "Lander" and knows nothing about any of this, which is exactly the claim. ---- Why the directory is not in /Apps ---- A launcher and a directory of the same name cannot both be there; SBFS refuses the second. And /Apps is the directory the shell walks for every word it does not know and Tab walks for every first word, so doubling what is in it is a cost on the path that runs most. The "app." goes in FRONT rather than behind because Tab matches the start of a name: a prefix is a namespace and a suffix is a collision. Copy.app beside Copy.sbx makes "Copy" and Tab complete to the shared "Copy." and hand you a broken word. The launcher names drive 0, so a game started from a disk of your own is looked for where the game is rather than where you are - its lines run on your disk, which is what makes everything else in a script work. /lander.state stays at the root. A saved position belongs to whoever saved it and is found where they are standing; a tune belongs to the program and is found beside it. That pair is the whole distinction. ---- And what it cost ---- Two hundred thousand cycles, about twelve frames, between the machine starting and the game drawing: a script opened, a deeper path walked. Six video captures moved out by that much. The drift bar needed something else - its pad is counted from the MACHINE starting rather than the game, so the burn is now twelve frames shorter from the game's point of view, and the recording holds the button longer instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
2defbb49e2
commit
94bdf71356
@@ -186,6 +186,21 @@ PROG_DEPS = $(BINARIES:.bin=.d)
|
||||
COSMOS = $(PROG_BUILD)/CosmOS/Source/cosmos.bin
|
||||
APPS = $(patsubst $(PROG_DIR)/CosmOS/Apps/%.asm,$(PROG_BUILD)/CosmOS/Apps/%.sbx,\
|
||||
$(wildcard $(PROG_DIR)/CosmOS/Apps/*.asm))
|
||||
|
||||
# ---- Applications that have things of their own ----
|
||||
#
|
||||
# A simple program is one file and lives in /Apps. One with ASSETS gets a directory of its
|
||||
# own - /Packages/app.<name> - and a launcher in /Apps under its bare name, which is what
|
||||
# somebody actually types. The launcher is indirection: where the thing lives stops being
|
||||
# part of its name, so an installer can put it elsewhere and change one line.
|
||||
#
|
||||
# Named here rather than found, because being packaged is a decision somebody makes and not
|
||||
# something a directory listing can say. Both halves of the placing below are driven from
|
||||
# this one list, so a name added here cannot end up half moved.
|
||||
PACKAGED = Lander
|
||||
# And what each of them owns beyond its own program. A tune named here is put in its
|
||||
# package instead of at the root, where the tunes that belong to nobody in particular go.
|
||||
LANDER_TUNES = splash
|
||||
COSMOS_DISK = $(PROG_BUILD)/cosmos.img
|
||||
|
||||
# ---- A disk that is yours ----
|
||||
@@ -585,7 +600,7 @@ $(COSMOS_DISK): makefile
|
||||
#
|
||||
# Found rather than wildcarded, because the tree the mirror walks is a tree and $(wildcard)
|
||||
# does not recurse. build is left out for the reason the mirror leaves it out.
|
||||
MIRRORED := $(shell find $(PROG_DIR) \( -name '*.asm' -o -name '*.score' \) -not -path '$(PROG_BUILD)/*' 2>/dev/null)
|
||||
MIRRORED := $(shell find $(PROG_DIR) \( -name '*.asm' -o -name '*.score' -o -path '*/Launchers/*' \) -not -path '$(PROG_BUILD)/*' 2>/dev/null)
|
||||
$(COSMOS_DISK): $(MIRRORED)
|
||||
$(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) \
|
||||
$(PROG_DIR)/testPrograms/stringKeyword.asm \
|
||||
@@ -624,6 +639,22 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) \
|
||||
$(DISKTOOL) mkdir $@ /Lib
|
||||
$(DISKTOOL) mkdir $@ /System
|
||||
$(DISKTOOL) mkdir $@ /System/Boot
|
||||
@# ---- And what applications own ----
|
||||
@#
|
||||
@# One directory per packaged application, so its files can be found together and
|
||||
@# removed together - which is the question install and remove are both made of. NOT in
|
||||
@# /Apps, for two reasons: a launcher and a directory of the same name cannot both be
|
||||
@# there, and /Apps is the directory the shell walks for every word it does not know and
|
||||
@# Tab walks for every first word, so doubling what is in it is a cost on the path that
|
||||
@# runs most.
|
||||
@#
|
||||
@# The "app." in front rather than behind is what keeps them out of the way. Tab matches
|
||||
@# the START of a name, so a prefix is a namespace and a suffix is a collision: with
|
||||
@# Copy.app beside Copy.sbx, typing Copy and pressing Tab completes to the shared "Copy."
|
||||
@# and hands you a broken word.
|
||||
$(DISKTOOL) mkdir $@ /Packages
|
||||
@for app in $(PACKAGED); do \
|
||||
$(DISKTOOL) mkdir $@ /Packages/app.$$app >/dev/null || exit 1; done
|
||||
@# The system itself, as a file, which is the whole of what boot.cfg chooses between.
|
||||
@# No boot.cfg is written: stage two falls back to this name when there is none, and a
|
||||
@# clean install having nothing to configure is the right default.
|
||||
@@ -631,8 +662,17 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) \
|
||||
@# What you run. /Apps is the second place the shell looks when a word it does not know
|
||||
@# turns out to be a program, so anything in here starts by name from anywhere.
|
||||
@for app in $(APPS); do \
|
||||
$(DISKTOOL) put $@ $$app /Apps/`basename $$app` >/dev/null || exit 1; done
|
||||
name=`basename $$app .sbx`; \
|
||||
case " $(PACKAGED) " in \
|
||||
*" $$name "*) where=/Packages/app.$$name/$$name.sbx ;; \
|
||||
*) where=/Apps/$$name.sbx ;; \
|
||||
esac; \
|
||||
$(DISKTOOL) put $@ $$app $$where >/dev/null || exit 1; done
|
||||
$(DISKTOOL) put $@ $(NATIVE_ASM) /Apps/Asm.sbx
|
||||
@# The launcher goes where the program used to be, under the bare name that is typed.
|
||||
@for app in $(PACKAGED); do \
|
||||
$(DISKTOOL) put $@ $(PROG_DIR)/CosmOS/Launchers/$$app /Apps/$$app >/dev/null \
|
||||
|| exit 1; done
|
||||
@# ---- And the music, compiled ----
|
||||
@#
|
||||
@# A .score is written and a .tune is what the machine reads, the same way a .asm is
|
||||
@@ -656,7 +696,11 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) \
|
||||
name=`basename $$score .score`; \
|
||||
$(TUNE_RUN) -I $(PROG_BUILD)/tunes $$score $(PROG_BUILD)/tunes/$$name.tune \
|
||||
>/dev/null || exit 1; \
|
||||
$(DISKTOOL) put $@ $(PROG_BUILD)/tunes/$$name.tune $$name.tune >/dev/null \
|
||||
case " $(LANDER_TUNES) " in \
|
||||
*" $$name "*) where=/Packages/app.Lander/$$name.tune ;; \
|
||||
*) where=$$name.tune ;; \
|
||||
esac; \
|
||||
$(DISKTOOL) put $@ $(PROG_BUILD)/tunes/$$name.tune $$where >/dev/null \
|
||||
|| exit 1; done
|
||||
@# ---- What you assemble: all of it ----
|
||||
@#
|
||||
|
||||
Reference in New Issue
Block a user