diff --git a/Makefile b/Makefile index 0761aa2..4b90dea 100644 --- a/Makefile +++ b/Makefile @@ -19,26 +19,46 @@ ACME=acme # version 1.4.0 or later CADIUS=cadius -BUILDDISK=build/million +EXOMIZER=exomizer mem -lnone -P23 -f -q -asm: - mkdir -p build - $(ACME) -r build/million.lst src/million.a 2>build/log - cp res/work.po "$(BUILDDISK)".po >>build/log - cp res/_FileInformation.txt build/ >>build/log - $(CADIUS) ADDFILE "${BUILDDISK}".po "/MILLION/" "res/PROGRESS" >>build/log - $(CADIUS) ADDFILE "${BUILDDISK}".po "/MILLION/" "res/PREFS" >>build/log - $(CADIUS) ADDFILE "${BUILDDISK}".po "/MILLION/" "build/MILLION.SYSTEM" >>build/log - for f in res/levels/*; do $(CADIUS) ADDFILE "${BUILDDISK}".po "/MILLION/" "$$f" >>build/log; done - bin/po2do.py build/ build/ - rm "$(BUILDDISK)".po +BUILDDISK=build/million.po +DISKVOLUME=MILLION + +asm: dirs + $(ACME) -r build/million.lst src/million.a + +compress: dirs + for f in res/levels/*; do \ + $(EXOMIZER) "$$f"@0x9000 -o build/LEVEL."$$(basename $$f)"; \ + done + rm -f src/data.index.a + rm -f res/DATA + touch res/DATA + for f in build/LEVEL.*; do \ + echo "!word $$(wc -c < res/DATA)" >> src/data.index.a ;\ + echo "!word $$(wc -c < $$f)" >> src/data.index.a; \ + cat "$$f" >> res/DATA; \ + done + +dsk: asm + $(CADIUS) CREATEVOLUME "$(BUILDDISK)" "$(DISKVOLUME)" 140KB -C + cp res/_FileInformation.txt build/ + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "res/PROGRESS" + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "res/PREFS" + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "res/DATA" + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "res/CLOCK.SYSTEM#FF0000" + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "build/MILLION.SYSTEM" + $(CADIUS) ADDFILE "${BUILDDISK}" "/$(DISKVOLUME)/" "res/PRODOS#FF0000" clean: rm -rf build/ -mount: - open "$(BUILDDISK)".dsk +dirs: + mkdir -p build -all: clean asm mount +mount: + open "$(BUILDDISK)" + +all: clean dsk mount al: all diff --git a/res/CLOCK.SYSTEM#FF0000 b/res/CLOCK.SYSTEM#FF0000 new file mode 100644 index 0000000..90f0b26 Binary files /dev/null and b/res/CLOCK.SYSTEM#FF0000 differ diff --git a/res/DATA b/res/DATA new file mode 100644 index 0000000..78ee0dd Binary files /dev/null and b/res/DATA differ diff --git a/res/PRODOS#FF0000 b/res/PRODOS#FF0000 new file mode 100644 index 0000000..7760a27 Binary files /dev/null and b/res/PRODOS#FF0000 differ diff --git a/res/_FileInformation.txt b/res/_FileInformation.txt index 3178573..6b1b0f1 100644 --- a/res/_FileInformation.txt +++ b/res/_FileInformation.txt @@ -1,3 +1,4 @@ MILLION.SYSTEM=Type(FF),AuxType(2000),Access(C3) PROGRESS=Type(06),AuxType(8E10),Access(C3) PREFS=Type(04),AuxType(0000),Access(C3) +DATA=Type(06),AuxType(0000),Access(C3) diff --git a/res/levels/_FileInformation.txt b/res/levels/_FileInformation.txt deleted file mode 100644 index 99cf70c..0000000 --- a/res/levels/_FileInformation.txt +++ /dev/null @@ -1,12 +0,0 @@ -A=Type(04),AuxType(0000),Access(C3) -B=Type(04),AuxType(0000),Access(C3) -C=Type(04),AuxType(0000),Access(C3) -D=Type(04),AuxType(0000),Access(C3) -E=Type(04),AuxType(0000),Access(C3) -F=Type(04),AuxType(0000),Access(C3) -G=Type(04),AuxType(0000),Access(C3) -H=Type(04),AuxType(0000),Access(C3) -I=Type(04),AuxType(0000),Access(C3) -J=Type(04),AuxType(0000),Access(C3) -K=Type(04),AuxType(0000),Access(C3) -L=Type(04),AuxType(0000),Access(C3) diff --git a/res/work.po b/res/work.po index 1b2d2ef..53a646d 100644 Binary files a/res/work.po and b/res/work.po differ diff --git a/src/constants.a b/src/constants.a index c4d425a..36b2d7a 100644 --- a/src/constants.a +++ b/src/constants.a @@ -10,11 +10,10 @@ ; 0400..07FF - text page (kept black for switching) ; 0800..19FF - scroll routines (generated at startup) ; 1A00..1BFF - HGR lookup tables -; 1C00..1FFF - ProDOS file buffer for puzzle files +; 1C00..1FFF - ProDOS file buffer ; 2000..3FFF - hi-res page ; 4000+ - program code (relocated to here at startup) ; ...unused... -; 8A00..8DFF - ProDOS file buffer for PROGRESS file ; 8E10..8F37 - progress of puzzles in current world ; 8F38..8FFF - address lookup table for puzzles within following world data ; 9000..BEB3 - world data (read from disk) @@ -68,9 +67,8 @@ GENSCROLLUP = $1100 ; 0x0900 bytes HGRLO = $1A00 ; 0x00C0 bytes HGRHI = $1B00 ; 0x00C0 bytes WORLDFILEBUFFER = $1C00 ; 0x0400 bytes -PREFSFILEBUFFER = $1C00 ; 0x0400 bytes (note: same as WORLDFILEBUFFER) - -PROGRESSFILEBUFFER = $8A00; 0x0400 bytes +PREFSFILEBUFFER = WORLDFILEBUFFER +PROGRESSFILEBUFFER = PREFSFILEBUFFER PACKEDPROGRESS = $8E10 ; 0x00C0 bytes PROGRESS = $8ED0 ; 0x0068 bytes PUZZLELO = $8F38 ; 0x0064 bytes diff --git a/src/data.index.a b/src/data.index.a new file mode 100644 index 0000000..22b34c8 --- /dev/null +++ b/src/data.index.a @@ -0,0 +1,24 @@ +!word 0 +!word 2514 +!word 2514 +!word 2947 +!word 5461 +!word 3431 +!word 8892 +!word 3965 +!word 12857 +!word 3299 +!word 16156 +!word 3683 +!word 19839 +!word 3990 +!word 23829 +!word 4704 +!word 28533 +!word 3822 +!word 32355 +!word 4363 +!word 36718 +!word 5108 +!word 41826 +!word 5779 diff --git a/src/exodecrunch.a b/src/exodecrunch.a new file mode 100644 index 0000000..eaca8ed --- /dev/null +++ b/src/exodecrunch.a @@ -0,0 +1,487 @@ +; This source code is altered and is not the original version found on +; the Exomizer homepage. +; It contains modifications made by qkumba to depack a packed file +; optionally crunched forward, and additional modifications by 4am +; for an optional progress UI. +; +; Original copyright statement follows: +; +; Copyright (c) 2002 - 2018 Magnus Lind. +; +; This software is provided 'as-is', without any express or implied warranty. +; In no event will the authors be held liable for any damages arising from +; the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software in a +; product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; +; 2. Altered source versions must be plainly marked as such, and must not +; be misrepresented as being the original software. +; +; 3. This notice may not be removed or altered from any distribution. +; +; 4. The names of this software and/or it's copyright holders may not be +; used to endorse or promote products derived from this software without +; specific prior written permission. +; +; ------------------------------------------------------------------- +; The decruncher jsr:s to the get_crunched_byte address when it wants to +; read a crunched byte into A. This subroutine has to preserve X and Y +; register and must not modify the state of the carry nor the overflow flag. +; ------------------------------------------------------------------- +;.import get_crunched_byte +; ------------------------------------------------------------------- +; this function is the heart of the decruncher. +; It initializes the decruncher zeropage locations and precalculates the +; decrunch tables and decrunches the data +; This function will not change the interrupt status bit and it will not +; modify the memory configuration. +; ------------------------------------------------------------------- +;.export decrunch + +; ------------------------------------------------------------------- +; Controls if the shared get_bits routines should be inlined or not. +;INLINE_GET_BITS=1 +; ------------------------------------------------------------------- +; if literal sequences is not used (the data was crunched with the -c +; flag) then the following line can be uncommented for shorter and. +; slightly faster code. +;LITERAL_SEQUENCES_NOT_USED = 1 +; ------------------------------------------------------------------- +; if the sequence length is limited to 256 (the data was crunched with +; the -M256 flag) then the following line can be uncommented for +; shorter and slightly faster code. +;MAX_SEQUENCE_LENGTH_256 = 1 +; ------------------------------------------------------------------- +; if the sequence length 3 has its own offset table then the following +; line can be uncommented for in some situations slightly better +; compression at the cost of a larger decrunch table. +EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 1 +; ------------------------------------------------------------------- +; optional progress UI +!IFNDEF SHOW_PROGRESS_DURING_DECRUNCH { + !set SHOW_PROGRESS_DURING_DECRUNCH = 0 +} +; ------------------------------------------------------------------- +; zero page addresses used +; ------------------------------------------------------------------- +zp_len_lo = $a7 +zp_len_hi = $a8 + +zp_src_lo = $ae +zp_src_hi = zp_src_lo + 1 + +zp_bits_hi = $fc + +zp_bitbuf = $fd +zp_dest_lo = zp_bitbuf + 1 ; dest addr lo +zp_dest_hi = zp_bitbuf + 2 ; dest addr hi + +!IFDEF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE { +encoded_entries = 68 +} ELSE { +encoded_entries = 52 +} + +tabl_bi = decrunch_table +tabl_lo = decrunch_table + encoded_entries +tabl_hi = decrunch_table + encoded_entries * 2 + + ;; refill bits is always inlined +!MACRO mac_refill_bits { + pha + jsr get_crunched_byte + rol + sta zp_bitbuf + pla +} + +!IFDEF INLINE_GET_BITS { +!MACRO mac_get_bits { + adc #$80 ; needs c=0, affects v + asl + bpl gb_skip +gb_next: + asl zp_bitbuf + bne gb_ok + mac_refill_bits +gb_ok: + rol + bmi gb_next +gb_skip: + bvc skip +gb_get_hi: + sec + sta zp_bits_hi + jsr get_crunched_byte +skip: +} +} ELSE { +!MACRO mac_get_bits { + jsr get_bits +} +get_bits: + adc #$80 ; needs c=0, affects v + asl + bpl gb_skip +gb_next: + asl zp_bitbuf + bne gb_ok + +mac_refill_bits +gb_ok: + rol + bmi gb_next +gb_skip: + bvs gb_get_hi + rts +gb_get_hi: + sec + sta zp_bits_hi + jmp get_crunched_byte +} +; ------------------------------------------------------------------- +; no code below this comment has to be modified in order to generate +; a working decruncher of this source file. +; However, you may want to relocate the tables last in the file to a +; more suitable address. +; ------------------------------------------------------------------- + +; ------------------------------------------------------------------- +; jsr this label to decrunch, it will in turn init the tables and +; call the decruncher +; no constraints on register content, however the +; decimal flag has to be #0 (it almost always is, otherwise do a cld) +decrunch: + +!IF SHOW_PROGRESS_DURING_DECRUNCH = 1 { + ldx #(kExoProgressWidth+2) + lda #$DF +- sta $0528+(20-(kExoProgressWidth/2))-1, x + sta $05A8+(20-(kExoProgressWidth/2))-1, x + dex + bpl - + lda #$20 + sta $05A8+(20-(kExoProgressWidth/2))-1 + sta $05A8+(20-(kExoProgressWidth/2))+kExoProgressWidth+1 + lda #$A8+(20-(kExoProgressWidth/2)) + sta ExoProgressPtr+1 +decrunch_no_reset_progress: +} +; ------------------------------------------------------------------- +; init zeropage, x and y regs. (12 bytes) +; + ldy #0 + ldx #3 +init_zp: + jsr get_crunched_byte + sta zp_bitbuf - 1,x + dex + bne init_zp +; ------------------------------------------------------------------- +; calculate tables (62 bytes) + get_bits macro +; x and y must be #0 when entering +; + clc +table_gen: + tax + tya + and #$0f + sta tabl_lo,y + beq shortcut ; start a new sequence +; ------------------------------------------------------------------- + txa + adc tabl_lo - 1,y + sta tabl_lo,y + lda zp_len_hi + adc tabl_hi - 1,y +shortcut: + sta tabl_hi,y +; ------------------------------------------------------------------- + lda #$01 + sta compressed_data + sta get_crunched_byte+2 + jsr decrunch jsr PreParseWorldData cpx #100 beq @success -@failure lda #$FF +@failure lda WorldFileLoaded + jsr CloseFile ; ignore error, if any + lda #$FF sta WorldFileLoaded sec rts @filename - !byte 1 ; length + !text 4,"DATA" WorldFileLoaded !byte $FF ; no file @@ -124,25 +157,17 @@ PreParseWorldData ; see comments in MarkPuzzleCompleted for file format ; ; in: none -; out: C clear if file was read successfully, and -; progressRefNum contains ProDOS file reference number (file is left -; open) -; C set if error occurred, and -; progressRefNum = 0xFF +; out: C clear if file was read successfully +; C set if error occurred ;------------------------------------------------------------------------------ LoadProgressFromDisk - jsr OpenFile - !word @progressFile - !word PROGRESSFILEBUFFER - bcs + - sta @refnum - sta progressRefNum - jsr ReadFile -@refnum !byte $FD ; SMC + jsr LoadFile1Shot + !word progressFile !word PACKEDPROGRESS ; data address !word $00C0 ; data length -+ rts -@progressFile + !word PROGRESSFILEBUFFER + rts +progressFile !byte 8 !raw "PROGRESS" @@ -374,14 +399,13 @@ MarkPuzzleSkipped eor checksum iny sta ($FE), y - lda progressRefNum - jsr SetMarkTo0 - lda progressRefNum - jsr WriteFile + jsr SaveFile1Shot + !word progressFile + !byte 4 + !word 0 !word PACKEDPROGRESS !word $00C0 - lda progressRefNum - jsr FlushFile + !word PROGRESSFILEBUFFER pla tax pla @@ -412,3 +436,10 @@ FindPackedProgress bcc + inc $FF + rts + +get_crunched_byte + lda compressed_data + inc get_crunched_byte+1 + bne + + inc get_crunched_byte+2 ++ rts diff --git a/src/ui.strings.a b/src/ui.strings.a index cce3d4e..395e8f3 100644 --- a/src/ui.strings.a +++ b/src/ui.strings.a @@ -13,7 +13,7 @@ sTitleLine3 !raw "LETTERS" sVersion !byte 4 - !raw "V1.0" + !raw "V1.1" sOneSpace !byte 1 !raw " " @@ -89,8 +89,8 @@ sWorldHelp !byte 40 !raw "ARROWS TO SELECT, RETURN TO PLAY, OR ESC" sAboutWritten - !byte 21 - !raw "COPYRIGHT 2022 BY 4AM" + !byte 26 + !raw "COPYRIGHT 2022-2024 BY 4AM" sAboutTested !byte 21 !raw "PLAYTESTED BY OPTION8"