From 05d96b12432b10c067b611165fd8071c5ea21070 Mon Sep 17 00:00:00 2001 From: Martin Haye Date: Tue, 12 Sep 2017 08:21:23 -0700 Subject: [PATCH] Expanded small-object heap to make more space for inventory. Started implementing pack size limits. --- .../src/org/badvision/A2PackPartitions.groovy | 18 ++- .../Apple/virtual/data/disks/base_140k.dsk.gz | Bin 727 -> 731 bytes .../Apple/virtual/data/disks/base_800k.2mg.gz | Bin 14673 -> 14673 bytes Platform/Apple/virtual/data/disks/util.2mg.gz | Bin 47773 -> 47769 bytes Platform/Apple/virtual/src/core/mem.s | 133 ++++++++++-------- Platform/Apple/virtual/src/plasma/diskops.pla | 2 +- Platform/Apple/virtual/src/plasma/gamelib.plh | 3 +- .../Apple/virtual/src/plasma/gameloop.pla | 37 +++-- .../Apple/virtual/src/plasma/globalDefs.plh | 4 +- Platform/Apple/virtual/src/plasma/party.pla | 8 +- .../Apple/virtual/src/plasma/playtype.plh | 3 +- Platform/Apple/virtual/src/plasma/store.pla | 7 - 12 files changed, 129 insertions(+), 86 deletions(-) diff --git a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy index 61602e7a..dc731f83 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy @@ -50,7 +50,7 @@ class A2PackPartitions static final int FLOPPY_SIZE = 35*8 // good old 140k floppy = 280 blks static final int AC_KLUDGE = 2 // minus 1 to work around last-block bug in AppleCommander static final int DOS_OVERHEAD = 3 // only 3 blks overhead! ProRWTS is so freaking amazing. - static final int SAVE_GAME_SIZE = 7 // 6 blocks data, 1 block index + static final int SAVE_GAME_SIZE = 10 // 9 blocks data, 1 block index static final int MAX_DISKS = 20 // for now this should be way more than enough def typeNumToName = [1: "Code", @@ -2817,7 +2817,8 @@ end "${parseByteAttr(row, "aiming")}, " + "${parseByteAttr(row, "hand-to-hand")}, " + "${parseByteAttr(row, "dodging")}, " + - "${parseGenderAttr(row, "gender")})") + "${parseGenderAttr(row, "gender")}, " + + "${parseByteAttr(row, "pack size")})") row.attributes().sort().eachWithIndex { name, val, idx -> if (name =~ /^skill-(.*)/) { out.println(" addToList(@p=>p_skills, " + @@ -3123,7 +3124,7 @@ def makePlayer_pt1(name, intelligence, strength, agility, stamina, charisma, spi return p end -def makePlayer_pt2(p, health, level, aiming, handToHand, dodging, gender)#1 +def makePlayer_pt2(p, health, level, aiming, handToHand, dodging, gender, packSize)#1 p=>w_health = health p->b_level = level p=>w_maxHealth = health @@ -3133,6 +3134,13 @@ def makePlayer_pt2(p, health, level, aiming, handToHand, dodging, gender)#1 p->b_handToHand = handToHand p->b_dodging = dodging p->c_gender = gender + if packSize + p->b_packSize = packSize + elsif global=>p_players + p->b_packSize = 15 + else + p->b_packSize = 30 + fin initPlayerXP(p) return p end @@ -3347,7 +3355,7 @@ end else { // Create empty save file newSave.withOutputStream { outStream -> - (0..3071).each { + (0..(18*256 - 1)).each { outStream.write( (byte) 0) } } @@ -4198,7 +4206,7 @@ end { def name = getSingle(blk.field, "NAME").text().trim() assert itemNameToFunc.containsKey(name.toLowerCase()) : "Can't locate item '$name'" - out << "playerHasItem(${escapeString(name)})" + out << "partyHasItem(${escapeString(name)})" } def packHasPlayer(blk) diff --git a/Platform/Apple/virtual/data/disks/base_140k.dsk.gz b/Platform/Apple/virtual/data/disks/base_140k.dsk.gz index 3ca018cde1455ef482b90aa4512c6226e35855b3..9a5aaa01d5c22c04017b8b0dfd3bebf72a19961e 100644 GIT binary patch delta 28 jcmcc4dYe^PzMF&NZS9!|2Ii#1;?#IU6NBuH{3n|T}tJ+KD3 delta 16 Xcmcaubg_tCzMF%?n7MKzyO$*ZG#>>r diff --git a/Platform/Apple/virtual/data/disks/util.2mg.gz b/Platform/Apple/virtual/data/disks/util.2mg.gz index 36b4a89911355c818aabf9879d043d3dd1d71690..e21ce0e547a48a1d1069cb1ac1146d92550444aa 100644 GIT binary patch delta 21 dcmbRHm1*WzCNBAI4vx3AXCfGwH}duG0svsT2!a3r delta 25 hcmbRFm1*u*CO-LY4vtwFWf2U_d8y^`8@c*-0RVgp32guX diff --git a/Platform/Apple/virtual/src/core/mem.s b/Platform/Apple/virtual/src/core/mem.s index 5ef339dc..fd79b660 100644 --- a/Platform/Apple/virtual/src/core/mem.s +++ b/Platform/Apple/virtual/src/core/mem.s @@ -212,7 +212,7 @@ init: !zone ; 5: main $2000 -> 6, active + locked ; 6: main $6000 -> 7, inactive ; 7: main $BFFD -> 8, active + locked -; 8: main $E000 -> 9, inactive +; 8: main $DA00 -> 9, inactive ; 9: main $FFFA -> 0, active + locked ; First, the flags ldy #$C0 ; flags for active + locked (with no resource) @@ -253,7 +253,7 @@ init: !zone sta tSegAdrHi+5 lda #$60 sta tSegAdrHi+6 - lda #$E0 + lda #$DA sta tSegAdrHi+8 lda #$FA sta tSegAdrLo+9 @@ -710,6 +710,25 @@ partFilename: ;------------------------------------------------------------------------------ ; Heap management routines +;------------------------------------------------------------------------------ +; Zero memory heapTop up to but not including $xx00 where XX is in A reg +heapClr: !zone + bit setLcRW+lcBank2 ; heap begins in bank 2 + sta .cmp+1 + lda #0 + sta targetAddr+1 ; clear target addr now that we're done with heap top + ldx heapTop + ldy heapTop+1 +.pg sty .st+2 +.st sta $1000,x ; self-modified above + inx + bne .st + iny +.cmp cpy #11 ; self-modified above + bcc .pg + bit setLcRW+lcBank1 ; back to mmgr's bank + rts + ; Check if blk pSrc is in GC hash; optionally add it if not. ; Input : pSrc = blk to check/add ; Carry set = add if not found, clear = check only, don't add @@ -770,6 +789,7 @@ memCheck: !zone heapCheck: !zone jsr startHeapScan .blklup bcc + ; if top-of-heap, we're done + bit setLcRW+lcBank1 ; back to mmgr's bank rts + bvs .isobj ; handle objects separately ; it's a string; check its characters @@ -812,6 +832,7 @@ heapCorrupt: ; Begin a heap scan by setting pTmp to start-of-heap, then returns ; everything as per nextHeapBlk below startHeapScan: !zone + bit setLcRW+lcBank2 ; heap is in bank 2 (bulk of mmgr is in bnk 1) lda #0 ldx heapStartPg sta pDst ; used in gc2 sweep init @@ -982,10 +1003,16 @@ heapCollect: !zone lda nSegsQueued bne .unfin jsr closePartFile + bit setLcRW+lcBank2 ; heap starts in bank 2 + lda heapTop+1 ; save old heap top for end of later clear + pha jsr gc1_mark ; mark reachable blocks jsr gc2_sweep ; sweep them into one place jsr gc3_fix ; adjust all pointers - jsr heapClr ; and clear newly freed space + pla ; old heap top + clc + adc #1 + jsr heapClr ; and clear newly freed space (switches back to bnk1 when done) ldx heapTop ; return new top-of-heap in x=lo/y=hi ldy heapTop+1 rts @@ -995,6 +1022,7 @@ heapCollect: !zone ; And yes, type $80 is valid (conventionally used for the Global Object). ; And yes, string length $00 is valid (it's an empty string). heapAlloc: !zone + bit setLcRW+lcBank2 ; heap starts in bank 2 lda heapTop sta pSrc lda heapTop+1 @@ -1014,6 +1042,7 @@ heapAlloc: !zone + sta heapTop sty heapTop+1 retPSrc: + bit setLcRW+lcBank1 ; back to mmgr's bank ldx pSrc ; return ptr in X=lo/Y=hi ldy pSrc+1 rts @@ -1046,7 +1075,8 @@ heapIntern: !zone .notfnd lda (pTmp),y ; get string length pha ; save it tax - jsr heapAlloc ; make space for it + jsr heapAlloc ; make space for it (switches to mmgr bank at end) + bit setLcRW+lcBank2 ; back to heap bank pla ; string length back tax inx ; add 1 to copy length byte also @@ -1058,6 +1088,44 @@ heapIntern: !zone bne .cplup beq .found ; always taken +;------------------------------------------------------------------------------ +; Variables +targetAddr: !word 0 +unusedSeg: !byte 0 +scanStart: !byte 0, 1 ; main, aux +segNum: !byte 0 +nextLdVec: jmp diskLoader +curPartition: !byte 0 +partFileOpen: !byte 0 +curMarkPos: !fill 4 ; really 3, but 1 extra to match ProRWTS needs +setMarkPos: !fill 3 +nSegsQueued: !byte 0 +bufferDigest: !fill 4 +diskActState: !byte 0 +floppyDrive: !byte 0 + +;------------------------------------------------------------------------------ +; Heap management variables +MAX_TYPES = 12 + +nTypes !byte 0 +typeTblL !fill MAX_TYPES +typeTblH !fill MAX_TYPES +typeLen !fill MAX_TYPES ; length does not include type byte + +heapStartPg !byte 0 +heapEndPg !byte 0 +heapTop !word 0 +gcHash_top !byte 0 + +lastLoMem = * +} ; end of !pseodupc $800 +loMemEnd = * + +;------------------------------------------------------------------------------ +; The remainder of the code gets relocated up into the Language Card, bank 1. +hiMemBegin: !pseudopc $D000 { + ;------------------------------------------------------------------------------ ; Show or hide the disk activity icon (at the top of hi-res page 1). The icon consists of a 4x4 ; block of blue pixels surrounded by a black border. @@ -1089,44 +1157,6 @@ showDiskActivity: !zone bne - .done rts -lastLoMem = * -} ; end of !pseodupc $800 -loMemEnd = * - -;------------------------------------------------------------------------------ -; The remainder of the code gets relocated up into the Language Card, bank 1. -hiMemBegin: !pseudopc $D000 { - -;------------------------------------------------------------------------------ -; Variables -targetAddr: !word 0 -unusedSeg: !byte 0 -scanStart: !byte 0, 1 ; main, aux -segNum: !byte 0 -nextLdVec: jmp diskLoader -curPartition: !byte 0 -partFileOpen: !byte 0 -curMarkPos: !fill 4 ; really 3, but 1 extra to match ProRWTS needs -setMarkPos: !fill 3 -nSegsQueued: !byte 0 -bufferDigest: !fill 4 -diskActState: !byte 0 -floppyDrive: !byte 0 - -;------------------------------------------------------------------------------ -; Heap management variables -MAX_TYPES = 16 - -nTypes !byte 0 -typeTblL !fill MAX_TYPES -typeTblH !fill MAX_TYPES -typeLen !fill MAX_TYPES ; length does not include type byte - -heapStartPg !byte 0 -heapEndPg !byte 0 -heapTop !word 0 -gcHash_top !byte 0 - ;------------------------------------------------------------------------------ grabSegment: !zone ; Input: None @@ -2557,7 +2587,7 @@ doAllFixups: !zone glibBase !word $1111 ;------------------------------------------------------------------------------ -; More heap management routines +; More heap management routines (that don't need to actually access LC bank 2) ;------------------------------------------------------------------------------ ; Establish a new heap @@ -2587,21 +2617,8 @@ heapSet: !zone ldy targetAddr + stx heapTop+1 ; set heap top sty heapTop - ; fall through to: -; Zero memory heapTop.heapEnd -heapClr: !zone - lda #0 - sta targetAddr+1 ; clear target addr now that we're done with heap top - ldx heapTop - ldy heapTop+1 -.pg sty .st+2 -.st sta $1000,x ; self-modified above - inx - bne .st - iny - cpy heapEndPg - bne .pg - rts + lda heapEndPg + jmp heapClr ; clear out the new heap space ;------------------------------------------------------------------------------ ; Set the table for the next type in order. Starts with type $80, then $81, etc. diff --git a/Platform/Apple/virtual/src/plasma/diskops.pla b/Platform/Apple/virtual/src/plasma/diskops.pla index 22c20d8c..093788a1 100644 --- a/Platform/Apple/virtual/src/plasma/diskops.pla +++ b/Platform/Apple/virtual/src/plasma/diskops.pla @@ -27,7 +27,7 @@ const RWTS_DRV2 = $80 const RWTS_RDWRPART = (0<<8) const RWTS_OPENDIR = (1<<8) -const LOAD_SAVE_BUF = $5000 +const LOAD_SAVE_BUF = $4E00 // Exported functions go here. First a predef for each one, then a table with function pointers // in the same order as the constants are defined in the the header. diff --git a/Platform/Apple/virtual/src/plasma/gamelib.plh b/Platform/Apple/virtual/src/plasma/gamelib.plh index 68ae8650..8d87a657 100644 --- a/Platform/Apple/virtual/src/plasma/gamelib.plh +++ b/Platform/Apple/virtual/src/plasma/gamelib.plh @@ -77,10 +77,10 @@ import gamelib predef numToPlayer(num)#1 predef parseDec(str)#1 predef partyHasPlayer(playerName)#1 + predef partyHasItem(itemName)#1 predef pause(count)#0 predef payGold(amount)#1 predef percentToRatio(pct)#1 - predef playerHasItem(itemName)#1 predef printf1(fmt, arg1)#0 predef printf2(fmt, arg1, arg2)#0 predef printf3(fmt, arg1, arg2, arg3)#0 @@ -103,6 +103,7 @@ import gamelib predef rollDice(encoded)#1 predef rollDiceWithLuck(encoded, luck)#1 predef rollPercentileWithLuck(luck)#1 + predef roomInPack(p_player)#1 predef scanForNamedObj(p_obj, name)#1 predef scriptCombat(mapCode)#1 predef scriptDisplayStr(str)#0 diff --git a/Platform/Apple/virtual/src/plasma/gameloop.pla b/Platform/Apple/virtual/src/plasma/gameloop.pla index 15b0d0b4..8cf65c9c 100644 --- a/Platform/Apple/virtual/src/plasma/gameloop.pla +++ b/Platform/Apple/virtual/src/plasma/gameloop.pla @@ -141,6 +141,7 @@ export byte[] S_DODGING = "Dodging" export byte[] S_GOLD = "Gold" export byte[] S_XP = "XP" export byte[] S_SP = "SP" +export byte[] S_PACK_SIZE = "Pack size" export byte[] S_ENTER = "Enter" export byte[] S_LEAVE = "Leave" export byte[] S_USE = "Use" @@ -1431,7 +1432,7 @@ export def heapCollect()#0 word pct mmgr(CHECK_MEM, 0) global=>w_heapSize = mmgr(HEAP_COLLECT, 0) - HEAP_BOTTOM - pct = min(99, max(0, ((global=>w_heapSize / 10) * 100) / 307)) + pct = min(99, max(0, ((global=>w_heapSize / 10) * 100) / (HEAP_SIZE / 10))) if pct <> curHeapPct curHeapPct = pct printHeapPct() @@ -1518,10 +1519,12 @@ end /////////////////////////////////////////////////////////////////////////////////////////////////// def clearTextWindow()#0 - setWindow2(); clearWindow() - if mapIs3D and texturesLoaded; copyWindow(); fin - textDrawn = FALSE - textClearCountdown = 0 + if textDrawn or textClearCountdown + setWindow2(); clearWindow() + if mapIs3D and texturesLoaded; copyWindow(); fin + textDrawn = FALSE + textClearCountdown = 0 + fin end /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2073,8 +2076,8 @@ def kbdLoop()#0 func = cmdTbl[key] if func if textClearCountdown + if textClearCountdown == 1; clearTextWindow(); fin textClearCountdown-- - if !textClearCountdown; clearTextWindow(); fin fin func() fin @@ -2608,6 +2611,7 @@ def toggleGodMode()#1 flipToPage1() clearTextWindow() displayf1("gm:%d\n", global->b_godmode & 1) + textDrawn = TRUE beep; beep clearTextWindow() saveMapPos(); restoreMapPos() // reload everything, including god module @@ -2892,6 +2896,11 @@ export def createAndAddUnique(moduleID, creationFuncNum, pList)#1 return p_thing end +/////////////////////////////////////////////////////////////////////////////////////////////////// +export def roomInPack(p_player)#1 + return countList(p_player=>p_items) < p_player->b_packSize +end + /////////////////////////////////////////////////////////////////////////////////////////////////// export def giveItemToPlayer(p_player, itemFuncNum)#0 createAndAddUnique(MOD_GEN_ITEMS, itemFuncNum, @p_player=>p_items) @@ -2968,8 +2977,8 @@ export def addPlayerToParty(playerFuncNum)#0 beep return fin + // Create the player (NPC flag will be established inside the creation func) p = createAndAddUnique(MOD_GEN_PLAYERS, playerFuncNum, @global=>p_players) - p->b_playerFlags = p->b_playerFlags | PLAYER_FLAG_NPC addXP(0) // to set initial skill pts needShowParty = TRUE end @@ -3010,8 +3019,14 @@ export def removePlayerFromParty(playerName)#0 end /////////////////////////////////////////////////////////////////////////////////////////////////// -export def playerHasItem(itemName)#1 - return scanForNamedObj(global=>p_players=>p_items, itemName) <> NULL +export def partyHasItem(itemName)#1 + word p_player + p_player = global=>p_players + while p_player + if scanForNamedObj(global=>p_players=>p_items, itemName) <> NULL; return TRUE; fin + p_player = p_player=>p_nextObj + loop + return FALSE end /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3038,6 +3053,7 @@ export def getStat(player, statName)#1 is streqi(statName, @S_GOLD); return global=>w_gold is streqi(statName, @S_XP); return player=>w_curXP is streqi(statName, @S_SP); return player->b_skillPoints + is streqi(statName, @S_PACK_SIZE); return player->b_packSize wend pSkill = player=>p_skills while pSkill @@ -3078,7 +3094,8 @@ export def setStat(player, statName, val)#0 is streqi(statName, @S_DODGING); player->b_dodging = clampByte(val); break is streqi(statName, @S_GOLD); global=>w_gold = max(0, val); needShowParty = TRUE; break is streqi(statName, @S_XP); player=>w_curXP = max(player=>w_curXP, val); needShowParty = TRUE; break - is streqi(statName, @S_SP); player->b_skillPoints = max(0, val); needShowParty = TRUE; break + is streqi(statName, @S_SP); player->b_skillPoints = clampByte(max(0, val)); needShowParty = TRUE; break + is streqi(statName, @S_PACK_SIZE); player->b_packSize = clampByte(max(player->b_packSize, val)); break otherwise pSkill = player=>p_skills while pSkill diff --git a/Platform/Apple/virtual/src/plasma/globalDefs.plh b/Platform/Apple/virtual/src/plasma/globalDefs.plh index b947ecbe..3ff38306 100644 --- a/Platform/Apple/virtual/src/plasma/globalDefs.plh +++ b/Platform/Apple/virtual/src/plasma/globalDefs.plh @@ -69,8 +69,8 @@ const HEAP_INTERN = $23 const HEAP_COLLECT = $24 // Heap location in memory -const HEAP_BOTTOM = $E000 -const HEAP_SIZE = $C00 +const HEAP_BOTTOM = $DA00 +const HEAP_SIZE = $1200 // Event code const EVENT_ENTER = 1 diff --git a/Platform/Apple/virtual/src/plasma/party.pla b/Platform/Apple/virtual/src/plasma/party.pla index 26d574f6..d2ee0ff5 100644 --- a/Platform/Apple/virtual/src/plasma/party.pla +++ b/Platform/Apple/virtual/src/plasma/party.pla @@ -168,6 +168,7 @@ def showDerived(player)#0 rawDisplayf2("\n^T%D%s\n", STAT_X-5, "^I LEVEL UP ^N") rawDisplayf2("^T%D%s\n", STAT_X-5+8, "in S)kills\n") fin + vspace() rightJustifyNum(player=>w_curXP, STAT_X) rawDisplayf2("^T%D%s\n", STATLBL_X, "Current XP") rightJustifyNum(player=>w_nextXP, STAT_X) @@ -202,9 +203,14 @@ def showDerived(player)#0 displayDice(dmg) rawDisplayf1("^T%DMelee\n", STATLBL_X) + vspace() + rightJustifyStr(sprintf2("%d/%d", countList(player=>p_items), player->b_packSize), STAT_X) + rawDisplayf1("^T%DPack size\n", STATLBL_X) + vspace() rightJustifyNum(global=>w_gold, STAT_X) - rawDisplayf1("^T%DParty gold", STATLBL_X) + rawDisplayf1("^T%DParty gold\n", STATLBL_X) + end def clearLittleArea(x, y)#0 diff --git a/Platform/Apple/virtual/src/plasma/playtype.plh b/Platform/Apple/virtual/src/plasma/playtype.plh index c0048d00..c87e33fb 100644 --- a/Platform/Apple/virtual/src/plasma/playtype.plh +++ b/Platform/Apple/virtual/src/plasma/playtype.plh @@ -80,7 +80,8 @@ struc Player byte b_level word w_curXP word w_nextXP - word b_skillPoints + byte b_skillPoints + byte b_packSize // Lists word p_skills // list:Modifier diff --git a/Platform/Apple/virtual/src/plasma/store.pla b/Platform/Apple/virtual/src/plasma/store.pla index 014505fb..15ab2314 100644 --- a/Platform/Apple/virtual/src/plasma/store.pla +++ b/Platform/Apple/virtual/src/plasma/store.pla @@ -254,13 +254,6 @@ def _buyFromStore(storeCode, profitPercent)#1 while TRUE if redisplay nItemsOnPage = displayBuyPage(pItemTbl, ratio, pageNum, nPages) - flipToPage1 // FOO - ^$c051 - mmgr(DEBUG_MEM, 0) - rdkey - auxMmgr(DEBUG_MEM, 0) - rdkey - ^$c050 fin choice = getUpperKey() redisplay = TRUE