Outlines of 'intimate mode'

This commit is contained in:
Martin Haye 2016-11-07 07:58:46 -08:00
parent 99606c623c
commit e6bcc747bd
7 changed files with 231 additions and 26 deletions

View File

@ -128,6 +128,7 @@
<block type="interaction_get_flag"></block>
<block type="interaction_set_flag"></block>
<block type="interaction_clr_flag"></block>
<block type="interaction_pause"></block>
</category>
<category id="customTypes" name="Custom Types">
</category>
@ -138,6 +139,7 @@
<block type="graphics_clr_fullscreen"></block>
<block type="graphics_set_avatar"></block>
<block type="graphics_swap_tile"></block>
<block type="graphics_intimate_mode"></block>
</category>
<category name="Sound">
</category>

View File

@ -781,6 +781,20 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Clear a game flag');
}
};
Blockly.Blocks['interaction_pause'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField("Pause for")
.appendField(new Blockly.FieldTextInput("0.5"), "NUM")
.appendField("second(s)");
this.setOutput(false);
this.setTooltip('Pause for a specified time');
}
};
Blockly.Blocks['graphics_set_portrait'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
@ -861,6 +875,19 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Stop displaying a full screen image, return to map display');
}
};
Blockly.Blocks['graphics_intimate_mode'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField("Intimate mode")
.appendField(new Blockly.FieldDropdown([["begin", "1"], ["end", "0"]]), "FLAG");
this.setOutput(false);
this.setTooltip('Begin or end intimate mode');
}
};
}
};
}

View File

@ -2985,6 +2985,8 @@ end
packSetAvatar(blk); break
case 'graphics_swap_tile':
packSwapTile(blk); break
case 'graphics_intimate_mode':
packIntimateMode(blk); break
case 'variables_set':
packVarSet(blk); break
case 'interaction_give_item':
@ -3001,6 +3003,8 @@ end
case 'interaction_set_flag':
case 'interaction_clr_flag':
packChangeFlag(blk); break
case 'interaction_pause':
packPause(blk); break
default:
printWarning "don't know how to pack block of type '${blk.@type}'"
}
@ -3111,6 +3115,17 @@ end
outIndented("setStat($stat, getStat($stat) ${blk.@type == 'interaction_increase_stat' ? '+' : '-'} $amount)\n")
}
def packPause(blk)
{
def num = getSingle(blk.field, 'NUM').text()
assert num.toFloat() > 0
def factor = 500 // approx counts per second
def time = (int)(num.toFloat() * factor)
if (time > 32767)
time = 32767
outIndented("pause($time)\n")
}
def packGetStat(blk)
{
def name = getSingle(blk.field, 'NAME').text()
@ -3349,6 +3364,13 @@ end
outIndented("scriptSwapTile($fromX, $fromY, $toX, $toY)\n")
}
def packIntimateMode(blk)
{
def enableFlg = getSingle(blk.field, 'FLAG').text()
assert enableFlg == "0" || enableFlg == "1"
outIndented("setIntimateMode($enableFlg)\n")
}
def packSetSky(blk)
{
def color = getSingle(blk.field, 'COLOR').text().toInteger()

View File

@ -19,7 +19,7 @@ import gamelib
predef displayChar, rawDisplayStr, displayStr, rightJustifyStr, rightJustifyNum, puts
predef min, max, randomFromListFiltered, randomFromArray, scanForNamedObj
predef countList, countListFiltered, addToList, removeFromList
predef beep, showParty, mmgr, setWindow1, setWindow2, setWindow3, reboot, brk
predef beep, showParty, mmgr, setWindow, setWindow1, setWindow2, setWindow3, reboot, brk
predef encodeDice, rollDice, setPlural, getStringResponse
predef streqi, strncpy, fatal, pause, tossStrings, charToUpper
predef addEncounterZone, clearEncounterZones, showMapName, setMapWindow, getMapWindow
@ -27,8 +27,8 @@ import gamelib
predef calcPlayerArmor, rdkey, initHeap, scriptCombat, makeModifier
predef giveItemToPlayer, takeItemFromPlayer, playerHasItem, getStat, setStat
predef setGameFlag, getGameFlag, scriptSetAvatar, parseDecWithDefault, readStr
predef addPlayerToParty, removePlayerFromParty, partyHasPlayer, loadFrameImg
predef scriptSwapTile
predef addPlayerToParty, removePlayerFromParty, partyHasPlayer, loadFrameImg, loadMainFrameImg
predef scriptSwapTile, setIntimateMode, fontCmd, setIntimateMode
/////////// Shared string constants //////////////

View File

@ -37,6 +37,7 @@ include "gen_items.plh"
include "combat.plh"
include "party.plh"
include "diskops.plh"
include "intimate.plh"
// NOTE: GLIB goes here!
@ -79,6 +80,7 @@ byte frameLoaded = 0
byte heapLocked = FALSE
byte allowZoneInit = FALSE
word curEngine = NULL
word pIntimate = NULL
// Queue setMap / teleport / start_encounter, since otherwise script might be replaced while executing
byte q_mapIs3D = 0
@ -678,7 +680,7 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Use the font engine to clear the current text window.
// Parameters: top, bottom, left, right
asm setWindow
export asm setWindow
+asmPlasm_bank2 4
jmp SetWindow
end
@ -1102,18 +1104,24 @@ export def loadFrameImg(img)
fin
// Load the image data into aux mem
auxMmgr(START_LOAD, 1) // partition 1 is where full screen images live
curFullscreenImg = auxMmgr(QUEUE_LOAD, img<<8 | RES_TYPE_SCREEN)
auxMmgr(FINISH_LOAD, 0)
if img
auxMmgr(START_LOAD, 1) // partition 1 is where full screen images live
curFullscreenImg = auxMmgr(QUEUE_LOAD, img<<8 | RES_TYPE_SCREEN)
auxMmgr(FINISH_LOAD, 0)
anyAnims = TRUE // for now; might get cleared if we discover otherwise on advance
animDirCt = 1
animPauseCt = ANIM_PAUSE_MAX
// And show the first frame of the screen image
showAnimFrame()
else
curFullscreenImg = NULL
anyAnims = FALSE
fin
frameLoaded = img
anyAnims = TRUE // for now; might get cleared if we discover otherwise on advance
animDirCt = 1
animPauseCt = ANIM_PAUSE_MAX
// And show the first frame of the screen image
showAnimFrame()
// Do not render over the image
needRender = FALSE
end
@ -1147,6 +1155,7 @@ export def setMapWindow()
setWindow(24, 169, 14, 140) // Top, Bottom, Left, Right
fin
end
export def getMapWindow(width, height)
if frameLoaded == 3 // don't check mapIs3D, since we might be in an engine
*width = 140-14
@ -1156,16 +1165,20 @@ export def getMapWindow(width, height)
*height = 169-24
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def fontCmd(code, coord)
tabBuf[0] = 4 // length
tabBuf[1] = code
tabBuf[2] = (coord / 100) + '0'
tabBuf[3] = ((coord / 10) % 10) + '0'
tabBuf[4] = (coord % 10) + '0'
rawDisplayStr(@tabBuf)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def rightJustifyStr(str, rightX)
word x
x = rightX - calcWidth(str)
tabBuf[0] = 4 // length
tabBuf[1] = 20 // Ctrl-T
tabBuf[2] = (x / 100) + '0'
tabBuf[3] = ((x / 10) % 10) + '0'
tabBuf[4] = (x % 10) + '0'
rawDisplayStr(@tabBuf)
fontCmd(20, rightX - calcWidth(str)) // 20=Ctrl-T
rawDisplayStr(str)
end
@ -1286,7 +1299,7 @@ def scanScripts(x, y)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def loadMainFrameImg()
export def loadMainFrameImg()
mmgr(START_LOAD, 1) // partition 1 is where code lives
loadFrameImg(mapIs3D+2)
if curFullscreenImg
@ -1681,9 +1694,13 @@ end
// Called by scripts to display a string. We set the flag noting that something has been
// displayed, then use an assembly routine to do the work.
export def scriptDisplayStr(str)
textDrawn = TRUE
flipToPage1()
displayStr(str)
if pIntimate
pIntimate=>intimate_displayStr(str)
else
textDrawn = TRUE
flipToPage1()
displayStr(str)
fin
// No: tossString() // Doesn't work here, because we need to toss strings in the *parent's* frame
end
@ -2499,6 +2516,18 @@ export def getGameFlag(flagName)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def setIntimateMode(enable)
if enable
pIntimate = loadEngine(MODULE_PARTY)
pIntimate=>intimate_setMode(enable)
else
pIntimate=>intimate_setMode(enable)
returnFromEngine()
pIntimate = NULL
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def startGame(ask)
word p_module

View File

@ -0,0 +1,14 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
// (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language
// governing permissions and limitations under the License.
///////////////////////////////////////////////////////////////////////////////////////////////////
// Each module-exported function needs its own constant, 0..n
const intimate_setMode = 0
const intimate_displayStr = 2
const intimate_swipeImg = 4

View File

@ -0,0 +1,111 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
// (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language
// governing permissions and limitations under the License.
///////////////////////////////////////////////////////////////////////////////////////////////////
include "gamelib.plh"
include "globalDefs.plh"
include "playtype.plh"
// This pointer is the root of all heap-tracked (and garbage collected) objects.
// See playtype.plh for definitions of all the datastructures and how they interconnect.
word global
// 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.
predef _intimate_setMode, _intimate_displayStr, _intimate_swipeImg
word[] funcTbl = @_intimate_setMode, @_intimate_displayStr, @_intimate_swipeImg
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
asm __defs
; Use hi-bit ASCII for Apple II
!convtab "../../include/hiBitAscii.ct"
; Headers
!source "../../include/global.i"
!source "../../include/plasma.i"
!source "../../include/mem.i"
; General use
tmp = $2
pTmp = $4
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// swipe(onLines, offLines, iterations)
asm swipe
+asmPlasm 3
sta pTmp ; iterations
lda evalStkL+1,x
sta tmp+1 ; offLines
lda evalStkL+2,x
sta tmp ; onLines
clc ; doesn't change; for convenient branching
.lup1:
lda $C057 ; hi-res mode
ldy tmp ; onLines
.lup2:
ldx #10 ; 1 -> 6 cyc. 2 -> 11 cyc. n -> n*5+1 cyc. 10 -> 51 cyc
- dex
bne -
dey
beq +
pha
pla
bcc .lup2 ; always taken
+ lda $C056 ; lo-res mode
ldy tmp+1 ; offLines
nop
.lup3:
ldx #9 ; 1 -> 5 cyc. 2 -> 11 cyc. n -> n*5+1 cyc. 9 -> 46 cyc
- dex
bne -
dey
bne +
dec pTmp ; next iteration
bne .lup1
rts
+ pha
pla
nop
nop
bcc .lup3 ; always taken
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up (or clear) intimate mode
def _intimate_setMode(enable)
if enable
loadFrameImg(NULL) // flip to page 1, unload textures, etc.
displayChar('N'-$40) // Set normal mode - clear all special modes (like underline, etc.)
setWindow(0, 192, 0, 280) // Top, Bottom, Left, Right
clearWindow()
else
loadMainFrameImg()
fontCmd(18, 0) // 18 = ctrl-R = ticker rate. 0=fastest
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Display string on a blank screen, with blanking follow-up
def _intimate_displayStr(str)
fontCmd(20, 0) // 20 = ctrl-T = horizontal position
fontCmd(22, 50) // 22 = ctrl-V = vertical position
fontCmd(18, 20) // 18 = ctrl-R = ticker rate
displayStr(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Boilerplate module initialization code
global = getGlobals()
return @funcTbl
done