From 69b5666afce96ca5ad257f68c89e053ef6126a62 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 25 Dec 2014 19:54:48 -0800 Subject: [PATCH] Fix some compiler bugs for Rogue combat updates --- src/makefile | 7 +- src/samplesrc/rogue.combat.pla | 208 +++++++++++++++++++++++++++++++++ src/samplesrc/rogue.map.pla | 31 +++-- src/samplesrc/rogue.pla | 207 +++++++++----------------------- src/toolsrc/codegen.c | 10 +- src/toolsrc/lex.c | 7 +- 6 files changed, 300 insertions(+), 170 deletions(-) create mode 100644 src/samplesrc/rogue.combat.pla diff --git a/src/makefile b/src/makefile index d4fce1d..e2906ad 100644 --- a/src/makefile +++ b/src/makefile @@ -11,6 +11,7 @@ ROD = ROD\#FE1000 SIEVE = SIEVE\#FE1000 ROGUE = ROGUE\#FE1000 ROGUEMAP= ROGUEMAP\#FE1000 +ROGUECOMBAT= ROGUECOMBAT\#FE1000 HELLO = HELLO\#FE1000 HGR1 = HGR1\#FE1000 HGR1TEST= HGR1TEST\#FE1000 @@ -36,7 +37,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ED) $(SB) $(ROD) $(SIEVE) $(ROGUE) $(ROGUEMAP) $(HGR1) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ED) $(SB) $(ROD) $(SIEVE) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(HGR1) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -105,6 +106,10 @@ $(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < samplesrc/rogue.pla > samplesrc/rogue.a acme --setpc 4094 -o $(ROGUE) samplesrc/rogue.a +$(ROGUECOMBAT): samplesrc/rogue.combat.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AM < samplesrc/rogue.combat.pla > samplesrc/rogue.combat.a + acme --setpc 4094 -o $(ROGUECOMBAT) samplesrc/rogue.combat.a + $(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < samplesrc/rogue.map.pla > samplesrc/rogue.map.a acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a diff --git a/src/samplesrc/rogue.combat.pla b/src/samplesrc/rogue.combat.pla new file mode 100644 index 0000000..533928f --- /dev/null +++ b/src/samplesrc/rogue.combat.pla @@ -0,0 +1,208 @@ +import STDLIB + predef syscall, call, memset, getc, putc, puts, putln + predef memset, memcpy + predef heapmark, heapallocallign, heapalloc, heaprelease, heapavail + byte MACHID +end + +import ROGUEMAP + predef puti, toupper, moveplayer + word rnd, getkb, home, gotoxy, tone +end + +struc t_pos + byte xpos + byte ypos +end + +// +// Player +// + +struc t_player + byte[t_pos] + byte angle + byte lamp + byte fov + byte skill + byte health + byte energy + word oil + byte gold + byte key + byte[32] name[32] +end + +// +// Other monsters +// + +struc t_other + byte[t_pos] + byte kind + byte tileid + byte life + byte power + word prev_other + word next_other +end + +// +// ASCII Enemy Art +// +byte[] ascii_thief +byte = " " +byte = " " +byte = " ____ " +byte = " /o_o\\\\ " +byte = "| \\ = // " +byte = "T /###|\\\\ " +byte = "@==###||| " +byte = " xxx@// " +byte = " #|#|\\\\ " +byte = " #|#| \\\\" + +byte[] ascii_ogre +byte = " :^; " +byte = " @ }\"{ " +byte = " # /'\\ " +byte = " ##=<#>=##" +byte = " ===== #" +byte = " \\===/ ?" +byte = " ===== :" +byte = " ()^() :" +byte = " () () *" +byte = " {{} {}} " + +byte[] ascii_zombie +byte = " \\\\/ " +byte = " {o|0} " +byte = " { ^ } " +byte = " ### " +byte = " /:\\ " +byte = " /%%%%%\\ " +byte = "|%%%//%%|\\" +byte = "|%%%\\%%%||" +byte = "|%%//%%%/|" +byte = "<===|@___/" + +byte[] ascii_rogue +byte = " | " +byte = " T " +byte = " \\ () " +byte = " \\^ " +byte = " #\\_] " +byte = " # ] " +byte = " /\\ " +byte = " / \\ " +byte = " / / " +byte = " = = " + +word ascii_entity = @ascii_thief, @ascii_ogre, @ascii_zombie, @ascii_rogue +// +// Monster types +// + +byte thief = "Thief", 5 +byte ogre = "Ogre", 15 +byte zombie = "Zombie", 25 +byte rogue = "Rogue", 50 +export word entity = @thief, @ogre, @zombie, @rogue +export word entities = 0 + +// +// Combat status strings +// + +byte skillstr = "Skill :" +byte healthstr = "Health :" +byte energystr = "Energy :" +byte powerstr = "Power :" +byte lifestr = "Life :" +byte fightstr = "F)ight or R)un?" + +// +// Combat Return 1 if running away, 0 if end of fight +// + +def win + tone(30, 15) + tone(5, 15) + tone(5, 15) + tone(30, 5) +end + +export def fight(player, enemy) + word p_atck, e_atck + + repeat + home() + gotoxy(0, 0) + puts(player+name) + gotoxy(1, 2) + puts(@skillstr); puti(player->skill) + gotoxy(1, 3) + puts(@healthstr); puti(player->health) + gotoxy(1, 4) + puts(@energystr); puti(player->energy) + gotoxy(20, 0) + puts(entity[enemy->kind]) + gotoxy(21, 2) + puts(@powerstr); puti(enemy->power) + gotoxy(21, 3) + puts(@lifestr); puti(enemy->life) + for e_atck = 0 to 9 + gotoxy(20, 10 + e_atck) + puts(ascii_entity[enemy->kind] + e_atck * 11) + next + gotoxy(12, 8); puts(@fightstr) + if toupper(getkb()) == 'R' + return 1 + else + // + // Turn player in random direction + // + player->angle = rnd() & 7 + // + // Calculate attack (with a little random variation) + // + p_atck = player->skill + player->energy / 10 - enemy->power / 25 + (rnd() & 7) + e_atck = enemy->power - player->skill / 5 - player->energy / 20 + (rnd() & 7) + if enemy->life > p_atck + enemy->life = enemy->life - p_atck + else + win + enemy->life = 0 + p_atck = player->skill + enemy->power / 3 + if p_atck > 100 // Limit skill + p_atck = 100 + fin + player->skill = p_atck + // + // Unlink dead enemy from entities list + // + if enemy == entities + entities = enemy=>next_other + fin + if enemy=>next_other + enemy=>next_other=>prev_other = enemy=>prev_other + fin + if enemy=>prev_other + enemy=>prev_other=>next_other = enemy=>next_other + fin + fin + if player->health > e_atck + player->health = player->health - e_atck + else + player->energy = 0 + player->health = 0 + fin + if player->energy >= 4 + player->energy = player->energy - 4 + fin + fin + until player->health == 0 or enemy->life == 0 + return 0 +end + +done \ No newline at end of file diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index 37d0300..18dccab 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -216,7 +216,7 @@ end def a2tone(duration, delay) byte i - + while duration ^SPEAKER for i = 0 to delay @@ -227,8 +227,8 @@ end def a3tone(duration, pitch) byte env - - env = ^ENV_REG + + env = ^ENV_REG ^ENV_REG = env | $C0 a2tone(duration, pitch) ^ENV_REG = env @@ -240,7 +240,7 @@ end def dev_status(devnum, code, list) byte params[5] - + params.0 = 3 params.1 = devnum params.2 = code @@ -284,6 +284,23 @@ def a2gotoxy(x, y) return call($FB5B, y + ^$22, 0, 0, 0) end +export def puti(i) + if i < 0; putc('-'); i = -i; fin + if i < 10 + putc(i + '0') + else + puti(i / 10) + putc(i % 10 + '0') + fin +end + +export def toupper(c) + if c >= 'a' and c <= 'z' + c = c - $20 + fin + return c +end + // // Load map // @@ -308,7 +325,7 @@ end export def setmaptile(xmap, ymap, tile) word imap - + imap = (ymap << 5) + xmap + 1 map[imap] = tile if ^(viewmap + imap) <> $A0 @@ -332,7 +349,7 @@ end export def lighttorches word imap, tmap byte xmap, ymap, xt, yt - + for ymap = 1 to maprows - 2 for xmap = 2 to mapcols - 2 imap = (ymap << 5) + xmap @@ -345,7 +362,7 @@ export def lighttorches next fin next - next + next end // diff --git a/src/samplesrc/rogue.pla b/src/samplesrc/rogue.pla index 28710f6..69353d9 100755 --- a/src/samplesrc/rogue.pla +++ b/src/samplesrc/rogue.pla @@ -32,10 +32,16 @@ import ROGUEMAP const INV_TILE = $3F const MAP_TILE = $7F + predef puti, toupper predef loadmap, getmaptile, setmaptile, updtmaptile, lighttorches, drawmap, drawvisentity word rnd, getkb, home, gotoxy, tone end +import ROGUECOMBAT + predef fight + word entity, entities +end + const FALSE = 0 const TRUE = not FALSE @@ -46,6 +52,7 @@ word xdir = 0, 1, 1, 1, 0, -1, -1, -1 word ydir = -1, -1, 0, 1, 1, 1, 0, -1 byte vplayer = '^', '\\', '>', '/', 'v', '\\', '<', '/' byte totaldarkness = 0 + // // Power-ups // @@ -53,6 +60,7 @@ byte totaldarkness = 0 const TORCH_OIL = 250 const MANA = 50 const RUN_ENERGY = 4 + struc t_pos byte xpos byte ypos @@ -105,17 +113,6 @@ struc t_other word next_other end -// -// Monster types -// - -byte thief = "Thief", 5 -byte ogre = "Ogre", 15 -byte zombie = "Zombie", 25 -byte rogue = "Rogue", 50 -word entity = @thief, @ogre, @zombie, @rogue -word entities = 0 - // // One line status strings // @@ -128,17 +125,6 @@ byte oilstr = "Oil:" byte goldstr = "Gold:" byte keystr = "Key" -// -// Combat status strings -// - -byte skillstr = "Skill :" -byte healthstr = "Health :" -byte energystr = "Energy :" -byte powerstr = "Power :" -byte lifestr = "Life :" -byte fightstr = "F)ight or R)un?" - // // Messages // @@ -152,13 +138,6 @@ byte youdiedstr = "You perished inside the catacombs :-(" // Utility functions // -def toupper(c) - if c >= 'a' and c <= 'z' - c = c - $20 - fin - return c -end - def abs(i) if i < 0 i = -i @@ -177,7 +156,7 @@ end def fall byte i - + for i = 0 to 10 tone(50, i) next @@ -185,29 +164,12 @@ end def groan byte i - + for i = 0 to 5 tone(5, 40 + i) next end -def win - tone(30, 15) - tone(5, 15) - tone(5, 15) - tone(30, 5) -end - -def puti(i) - if i < 0; putc('-'); i = -i; fin - if i < 10 - putc(i + '0') - else - puti(i / 10) - putc(i % 10 + '0') - fin -end - // // Update status line // @@ -234,79 +196,36 @@ end def clearstatus return memset($07D0, 40, $A0A0) end + // -// Combat +// Move player, check for obstacles // -def fight(enemy) - word p_atck, e_atck - - repeat - home() - gotoxy(0, 0) - puts(@player.name) - gotoxy(1, 2) - puts(@skillstr); puti(player.skill) - gotoxy(1, 3) - puts(@healthstr); puti(player.health) - gotoxy(1, 4) - puts(@energystr); puti(player.energy) - gotoxy(20, 0) - puts(entity[enemy->kind]) - gotoxy(21, 2) - puts(@powerstr); puti(enemy->power) - gotoxy(21, 3) - puts(@lifestr); puti(enemy->life) - gotoxy(12, 8); puts(@fightstr) - if toupper(getkb()) == 'R' - if player.energy > RUN_ENERGY - moveplayer(1) +def moveplayer(dir) + player.xpos = player.xpos + dir * xdir[player.angle] + player.ypos = player.ypos + dir * ydir[player.angle] + when getmaptile(player.xpos, player.ypos) & MAP_TILE + is PIT_TILE + fall + player.energy = 0 + player.health = 0 + is FLOOR_TILE + is TORCH_TILE + is KEY_TILE + is GOLD_TILE + is FOOD_TILE + if player.energy < 10 + player.fov = 0 fin - return moveplayer(1) - else - // - // Turn player in random direction - // - player.angle = rnd() & 7 - // - // Calculate attack (with a little random variation) - // - p_atck = player.skill + player.energy / 10 - enemy->power / 25 + (rnd() & 7) - e_atck = enemy->power - player.skill / 5 - player.energy / 20 + (rnd() & 7) - if enemy->life > p_atck - enemy->life = enemy->life - p_atck - else - win - enemy->life = 0 - p_atck = player.skill + enemy->power / 3 - if p_atck > 100 // Limit skill - p_atck = 100 - fin - player.skill = p_atck - // - // Unlink dead enemy from entities list - // - if enemy == entities - entities = enemy=>next_other - fin - if enemy=>next_other - enemy=>next_other=>prev_other = enemy=>prev_other - fin - if enemy=>prev_other - enemy=>prev_other=>next_other = enemy=>next_other - fin + if player.energy + player.energy = player.energy - 1 fin - if player.health > e_atck - player.health = player.health - e_atck - else - player.energy = 0 - player.health = 0 - fin - if player.energy >= 4 - player.energy = player.energy - 4 - fin - fin - until player.health == 0 or enemy->life == 0 + break + otherwise + player.xpos = player.xpos - dir * xdir[player.angle] + player.ypos = player.ypos - dir * ydir[player.angle] + ouch + wend end // @@ -316,7 +235,7 @@ end def findentities word newother byte xmap, ymap, what - + for ymap = 1 to maprows - 2 for xmap = 2 to mapcols - 2 what = 0 @@ -350,7 +269,7 @@ def findentities setmaptile(xmap, ymap, FLOOR_TILE) wend next - next + next end // @@ -359,7 +278,7 @@ end def drawentities word other, xofst, yofst - + other = entities while other xofst = other->xpos - player.xpos @@ -434,7 +353,7 @@ end def moveentities(playerisvis) byte xmove, ymove word other - + other = entities while other if playerisvis @@ -464,43 +383,21 @@ def moveentities(playerisvis) fin fin if other->xpos == player.xpos and other->ypos == player.ypos - return fight(other) + if fight(@player, other) + // + // Player trying to run away + // + if player.energy > RUN_ENERGY + moveplayer(1) + fin + return moveplayer(1) + fin + return fin other = other=>next_other loop end -// -// Move player, check for obstacles -// - -def moveplayer(dir) - player.xpos = player.xpos + dir * xdir[player.angle] - player.ypos = player.ypos + dir * ydir[player.angle] - when getmaptile(player.xpos, player.ypos) & MAP_TILE - is PIT_TILE - fall - player.energy = 0 - player.health = 0 - is FLOOR_TILE - is TORCH_TILE - is KEY_TILE - is GOLD_TILE - is FOOD_TILE - if player.energy < 10 - player.fov = 0 - fin - if player.energy - player.energy = player.energy - 1 - fin - break - otherwise - player.xpos = player.xpos - dir * xdir[player.angle] - player.ypos = player.ypos - dir * ydir[player.angle] - ouch - wend -end - // // Read player input and do something // @@ -573,7 +470,7 @@ def play ouch break fin - is DOOR_TILE + is DOOR_TILE updtmaptile(player.xpos + xdir[player.angle], player.ypos + ydir[player.angle], FLOOR_TILE) break is ENTER_TILE @@ -588,12 +485,12 @@ def play player.key = 1 updtmaptile(player.xpos, player.ypos, FLOOR_TILE) gotit - break + break is GOLD_TILE player.gold = player.gold + 1 updtmaptile(player.xpos, player.ypos, FLOOR_TILE) gotit - break + break is TORCH_TILE player:oil = player:oil + TORCH_OIL if player:oil > 1000 diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index ba041a4..17e9fb0 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -104,7 +104,7 @@ int idlocal_add(char *name, int len, int type, int size) { parse_error("local label already defined\n"); return (0); - } + } name[len] = '\0'; emit_idlocal(name, localsize); name[len] = c; @@ -135,7 +135,7 @@ int idglobal_add(char *name, int len, int type, int size) { parse_error("global label already defined\n"); return (0); - } + } name[len] = '\0'; name[len] = c; idglobal_name[globals][0] = len; @@ -274,7 +274,7 @@ char *tag_string(int tag, int type) { static char str[16]; char t; - + if (type & EXTERN_TYPE) t = 'X'; else if (type & DEF_TYPE) @@ -371,7 +371,7 @@ void emit_rld(void) void emit_esd(void) { int i; - + printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n"); for (i = 0; i < globals; i++) { @@ -632,7 +632,7 @@ void emit_globaladdr(int tag, int offset, int type) int fixup = fixup_new(tag, type, FIXUP_WORD); char *taglbl = tag_string(tag, type); printf("\t%s\t$26\t\t\t; LA\t%s+%d\n", DB, taglbl, offset); - printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "" : taglbl, offset); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); } void emit_indexbyte(void) { diff --git a/src/toolsrc/lex.c b/src/toolsrc/lex.c index c11ace7..fe2e8b4 100755 --- a/src/toolsrc/lex.c +++ b/src/toolsrc/lex.c @@ -51,7 +51,7 @@ t_token keywords[] = { void parse_error(char *errormsg) { char *error_carrot = statement; - + fprintf(stderr, "\n%4d: %s\n ", lineno, statement); for (error_carrot = statement; error_carrot != tokenstr; error_carrot++) putc(*error_carrot == '\t' ? '\t' : ' ', stderr); @@ -220,6 +220,9 @@ t_token scan(void) case '\'': *scanpos = '\''; break; + case '\"': + *scanpos = '\"'; + break; case '\\': *scanpos = '\\'; break; @@ -233,7 +236,7 @@ t_token scan(void) for (scanshift = scanpos + 1; *scanshift; scanshift++) scanshift[0] = scanshift[1]; } - else +// else scanpos++; } if (!*scanpos++)