diff --git a/README.md b/README.md index 058d626..19cb999 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a collection of my own ports of the [Scoundrel](http://stfj.net/art/2011 ## Ports included in this repo -* [ANSI C89 port](scoundrel.c) +* [ANSI C89 port](c/scoundrel.c) - also compatible with CC65 (use the provided Makefile to build Scoundrel for Commodore 16/64/128/Plus-4/PET; Apple II/IIe support is being debugged, JRE installation on the host system is required to build disk images) ## Ports NOT included in this repo for various reasons @@ -18,8 +18,6 @@ This is a collection of my own ports of the [Scoundrel](http://stfj.net/art/2011 * POSIX AWK * TI-74 BASIC * VTL-2 -* Apple IIe (CC65, text mode) -* Commodore 64 (CC65, text mode) * Free Pascal (CLI) ### Some asset design required diff --git a/c/Makefile b/c/Makefile new file mode 100644 index 0000000..efea962 --- /dev/null +++ b/c/Makefile @@ -0,0 +1,45 @@ +# Scoundrel65 reference implementation makefile + +PROJNAME=scoundrel +CFILES=scoundrel.c +PBTDIR=platform-build-tools +CCBUILD=cl65 --standard c89 -O -Os + +$(PROJNAME): + $(CC) -std=c89 -O2 -o scoundrel $(CFILES) + +a2-build: + $(CCBUILD) -t apple2 -C apple2-system.cfg -o $(PROJNAME).apple2 $(CFILES) + +a2: a2-build + cp $(PBTDIR)/apple2/tpl.dsk $(PROJNAME).dsk + java -jar $(PBTDIR)/apple2/ac.jar -p $(PROJNAME).dsk $(PROJNAME).system sys < $$(cl65 --print-target-path)/apple2/util/loader.system + java -jar $(PBTDIR)/apple2/ac.jar -as $(PROJNAME).dsk $(PROJNAME) bin < $(PROJNAME).apple2 + +a2e-build: + $(CCBUILD) -t apple2enh -C apple2enh-system.cfg -o $(PROJNAME).a2enh $(CFILES) + +a2e: a2e-build + cp $(PBTDIR)/apple2/tpl.dsk $(PROJNAME)-enh.dsk + java -jar $(PBTDIR)/apple2/ac.jar -p $(PROJNAME)-enh.dsk $(PROJNAME).system sys < $$(cl65 --print-target-path)/apple2enh/util/loader.system + java -jar $(PBTDIR)/apple2/ac.jar -as $(PROJNAME)-enh.dsk $(PROJNAME) bin < $(PROJNAME).a2enh + +c64: + $(CCBUILD) -t c64 -o $(PROJNAME).c64 $(CFILES) + +c16: + $(CCBUILD) -t c16 -o $(PROJNAME).c16 $(CFILES) + +c128: + $(CCBUILD) -t c128 -o $(PROJNAME).c128 $(CFILES) + +pet: + $(CCBUILD) -t pet -o $(PROJNAME).pet $(CFILES) + +plus4: + $(CCBUILD) -t plus4 -o $(PROJNAME).plus4 $(CFILES) + +all: $(PROJNAME) a2 a2e c64 c16 c128 pet plus4 + +clean: + rm -f ./$(PROJNAME) *.dsk *.o *.apple2 *.a2enh *.c64 *.c128 *.c16 *.pet *.plus4 diff --git a/c/platform-build-tools/PERS.DAT b/c/platform-build-tools/PERS.DAT new file mode 100644 index 0000000..f7c8c15 Binary files /dev/null and b/c/platform-build-tools/PERS.DAT differ diff --git a/c/platform-build-tools/apple2/ac.jar b/c/platform-build-tools/apple2/ac.jar new file mode 100644 index 0000000..f523583 Binary files /dev/null and b/c/platform-build-tools/apple2/ac.jar differ diff --git a/c/platform-build-tools/apple2/tpl.dsk b/c/platform-build-tools/apple2/tpl.dsk new file mode 100644 index 0000000..6b8239c Binary files /dev/null and b/c/platform-build-tools/apple2/tpl.dsk differ diff --git a/scoundrel.c b/c/scoundrel.c similarity index 88% rename from scoundrel.c rename to c/scoundrel.c index ff4799e..3626e4f 100644 --- a/scoundrel.c +++ b/c/scoundrel.c @@ -1,17 +1,25 @@ /** - Scoundrel.C: a C89 port of the Scoundrel roguelike card game + scoundrel.c: a C89 port of the Scoundrel roguelike card game using the official ruleset only - Build: cc -std=c89 -O2 scoundrel.c -o scoundrel + See the README.md file for platform-specific build instructions Created by Luxferre in 2026, released into public domain */ #include #include #include +#ifndef __CC65__ #include +#endif /* UI choices */ -typedef enum choices { CH1=0, CH2, CH3, CH4, CH_R, CH_Q, CH_INVAL } choice; +#define CH1 0 +#define CH2 1 +#define CH3 2 +#define CH4 3 +#define CH_R 4 +#define CH_Q 5 +#define CH_INVAL 6 /** Deck/room representation: @@ -32,9 +40,10 @@ static char deck[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, /* monster pack 2 (spades) */ 14, 15, 16, 17, 18, 19, 20, 21, 22, /* weapon pack (diamonds) */ 23, 24, 25, 26, 27, 28, 29, 30, 31 /* potion pack (hearts) */ - }, - room[] = {0, 0, 0, 0}, deck_idx = 0, - hp = 20, weapon = 0, durability = 0, can_run = 1, + }, room[] = {0, 0, 0, 0}; + +static short deck_idx = 0, hp = 20, + weapon = 0, durability = 0, can_run = 1, engaged = 0, potion_drank = 0, last_potion_val = 0; /* Output method */ @@ -43,9 +52,8 @@ void print_msg(char *s) { } /* Input method */ -choice get_choice() { - char c; - choice res; +char get_choice() { + char c, res; printf("Your choice: "); scanf(" %c", &c); switch(c) { @@ -132,8 +140,8 @@ void handle_monster(int val) { if(weapon > 0 && val <= durability) { int weapondiff = val - weapon; if(weapondiff < 0) weapondiff = 0; - printf("You'll lose %d HP if fighting with bare hands.\n", val); - printf("You'll lose %d HP if using your weapon.\n", weapondiff); + printf("Without weapon: lose %d HP.\n", val); + printf("With weapon: lose %d HP.\n", weapondiff); if(confirm("Use weapon? (y/n) ")) { healthlost = weapondiff; durability = val - 1; @@ -170,18 +178,20 @@ void handle_potion(int val) { /* Main gameplay */ int game() { - unsigned int i, j; + unsigned int i; + int score = 0; /* score storage */ + int item, room_sum; /* true item value */ + int last_room = 0, last_room_clr = 0; /* last room markers */ + char ch; + deck_idx = 0; /* reset the deck index */ /* Shuffle the deck */ shuffle(deck, sizeof(deck)); - deck_idx = 0; /* reset the deck index */ /* prepare all other parameters */ hp = 20; can_run = 1; weapon = durability = engaged = 0; potion_drank = last_potion_val = 0; - choice ch; - int item, room_sum; /* true item value */ - int last_room = 0, last_room_clr = 0; /* last room markers */ + for(i=0;i 0 && !last_room_clr) { /* fill in the new room unless engaged */ @@ -294,7 +304,6 @@ int game() { } } /* Score the result */ - int score = 0; if(hp > 0) { /* win */ score = hp; if(hp == 20) score += last_potion_val; @@ -311,13 +320,21 @@ int game() { /* Entry point */ int main() { - print_msg("===============\nScoundrel--2026\n by Luxferre\n===============\n Good luck!"); + int score; +#ifdef __CC65__ + _randomize(); +#else srand(time(NULL)); - int score = game(); - if(score > 0) { - printf("You win! Your score: %d\n", score); - } else { - printf("You lose! Your score: %d\n", score); +#endif + while(1) { + print_msg("===============\nScoundrel--2026\n by Luxferre\n===============\n Good luck!"); + score = game(); + if(score > 0) { + printf("You win! Your score: %d\n", score); + } else { + printf("You lose! Your score: %d\n", score); + } + if(!confirm("Play again? (y/n) ")) break; } return 0; }