CONST True
= -1, False
= 0 CONST LeftJustify
= -1, CenterJustify
= -2, RightJustify
= -3, NoJustify
= 0 CONST OnLine
= 0, CenterLine
= -1, TopLine
= 1, BottomLine
= -2 CONST NoUpdate
= 0, DoUpdate
= 1, NewLine
= 2 '********************************************************
'* Text Frames before this line
'********************************************************
_CONSOLE ON 'for debugging purposes while making/testing things
Left
AS _UNSIGNED _BYTE 'life left on the weapon, AKA "durability", but easier and cheaper to spell
Left
AS _UNSIGNED _BYTE 'life left on the weapon, AKA "durability", but easier and cheaper to spell
Detection
AS INTEGER 'in case it has some sort of magic "sixth sense" to detect characters, not related to sight nor sound.
DIM SHARED XL
, XH
, YL
, YH
'the map X/Y low/high array limits. DIM SHARED PrintArea
AS LONG 'the handle to our text frame print area for game results.
'1 map is illuminated
'2 map is uncovered
'4 map is a wall
'8 map is a pathway
'16 map is a stairway
'32 map is simply blocked (perhaps with a monster?)
'64 map is secret (can not be uncovered)
Init
CreateMap 99, 74, 10
DrawMap
DisplayCharacter
GetInput
MonstersTurn
CheckForHeroGrowth
Hero.
Name = "Steve The Tester!" Hero.Life.Low = 10: Hero.Life.High = 10: Hero.Level = 1
Hero.EXP_Earned = 0: Hero.EXP_Needed = 2
Hero.Light.
Name = "Magic Candle" Hero.Light.Reach = 2: Hero.Light.Left = -1 'infinite
Hero.Weapon1.
Name = "Bare Fist" Hero.Weapon1.Reach = 1: Hero.Weapon1.Damage.Low = 1: Hero.Weapon1.Damage.High = 2
Hero.Weapon1.HitBonus = 0: Hero.Weapon1.DamageBonus = 0
Hero.Weapon1.Left = -1 'your fist is indestructible!
Hero.Weapon2.
Name = "Magic Candle" Hero.Weapon2.Reach = 0: Hero.Weapon2.Damage.Low = 0: Hero.Weapon2.Damage.High = 0
Hero.Weapon2.HitBonus = 0: Hero.Weapon2.DamageBonus = 0
Hero.Weapon2.Left = 0 'you can't attack with a candle
Hero.Armor.
Name = "Naked" Hero.Armor.PD = 0: Hero.Armor.DR = 0: Hero.Armor.Left = -1 'you might be naked, but at least you can't break your armor!
PrintArea = NewTextArea(230, 601, 799, 699, False)
ColorTextArea PrintArea
, _RGB32(255, 255, 255), _RGB32(0, 0, 128) DrawTextArea PrintArea
SetPrintPositionX PrintArea, CenterJustify
SetPrintUpdate PrintArea, NewLine
PrintOut PrintArea, "WELCOME TO (almost) ROGUE"
PrintOut PrintArea, "created by STEVE!"
PrintOut PrintArea, ""
SetPrintPositionX PrintArea, LeftJustify
IF Hero.Life.Low
< 1 THEN 'first, let's check to see if we died... PRINT "YOU DIED! HAHAHAHA!! (Better ending coming later...)"
LINE (0, 601)-(229, 799), &HFF000000, BF
CASE 18432:
IF Hero.Y
> YL
THEN MoveHero
0, -1 'if we can move up CASE 19200:
IF Hero.X
> XL
THEN MoveHero
-1, 0 'if we can move left CASE 20480:
IF Hero.Y
< YH
THEN MoveHero
0, 1 'if we can move down CASE 19712:
IF Hero.X
< XH
THEN MoveHero
1, 0 'if we can move right CASE 32 'space to just wait and skip a turn Level = Level + 1
CreateMap 99, 74, 10
PathFind
IF Hero.Light.Reach
< 25 THEN Hero.Light.Reach
= Hero.Light.Reach
+ 1 IF Hero.Light.Reach
> 1 THEN Hero.Light.Reach
= Hero.Light.Reach
- 1 valid = 0 'it's a key press which we don't recognize. Ignore it
SUB MoveHero
(MoveX
, MoveY
) TestX = Hero.X + MoveX: TestY = Hero.Y + MoveY
IF MapArray
(TestX
, TestY
) AND (4 OR 8) THEN 'and it's a room or passageway IF (MapArray
(TestX
, TestY
) AND 32) = 0 THEN 'and it's not blocked for some reason MapArray
(Hero.X
, Hero.Y
) = MapArray
(Hero.X
, Hero.Y
) AND NOT 32 'unblock where the hero is IF MoveX
THEN Hero.X
= Hero.X
+ MoveX
IF MoveY
THEN Hero.Y
= Hero.Y
+ MoveY
MapArray
(Hero.X
, Hero.Y
) = MapArray
(Hero.X
, Hero.Y
) OR 32 'and block where the hero is now that he moved PathFind
'chances are it's blocked by a monster. Since we're one step away from it, let's see which monster it is and attack it!
FOR i
= 1 TO EncounterLimit
IF Encounter
(i
).Active
THEN 'Check for active/alive monsters only MX = Encounter(i).X: MY = Encounter(i).Y 'monster x, monster y position
IF MX
= TestX
AND MY
= TestY
THEN 'yep, we found our monster! Swing 0, i, 1 'swing with the right hand
SUB Swing
(Who
, AtWhom
, HandUsed
) M = Encounter(AtWhom).M
BaseChancetohit = 10 'base 10 chance to hit
IF Who
= 0 THEN 'it's the hero attacking, add his attack bonuses IF Hero.Weapon1.Reach
> 0 THEN 'it's a weapon and not an utility object being held. Chancetohit = BaseChancetohit + Hero.Weapon1.HitBonus 'add in the weapon's hit bonus
Chancetohit = Chancetohit - Monster(AtWhom).Armor.PD 'subtract the monster's armor/ natural dodge
totalroll = 0
IF roll
= 1 THEN totalroll
= totalroll
- 20 'critical failure IF roll
= 20 THEN totalroll
= totalroll
+ 20 totalroll = totalroll + roll
damage
= INT(RND * (Hero.Weapon1.Damage.High
- Hero.Weapon1.Damage.Low
+ 1)) + Hero.Weapon1.Damage.Low
'random damage for the hit damage = damage + Hero.Weapon1.DamageBonus 'add in the weapon's damage bonus
IF totalroll
< Chancetohit
- 20 THEN 'you critically failed! SetTextColor PrintArea, &HFFF000F0, 0
out$
= out$
+ " CRITICALLY FAILED attacking. They hit themselves for" Hero.Life.Low = Hero.Life.Low - damage
SetTextColor PrintArea, &HFFF0F000, 0
SetTextColor PrintArea, &HFF00FF00, 0
damage = damage * (totalroll \ 20 + 1)
Encounter(AtWhom).Life = Encounter(AtWhom).Life - damage
SetTextColor PrintArea, &HFF00FF00, 0
Encounter(AtWhom).Life = Encounter(AtWhom).Life - damage
IF Hero.Weapon2.Reach
> 0 THEN 'it's a weapon and not an utility object being held. Chancetohit = BaseChancetohit + Hero.Weapon2.HitBonus 'add in the weapon's hit bonus
Chancetohit = Chancetohit - Monster(AtWhom).Armor.PD 'subtract the monster's armor/ natural dodge
totalroll = 0
IF roll
= 1 THEN totalroll
= totalroll
- 20 'critical failure IF roll
= 20 THEN totalroll
= totalroll
+ 20 totalroll = totalroll + roll
damage
= INT(RND * (Hero.Weapon2.Damage.High
- Hero.Weapon2.Damage.Low
+ 1)) + Hero.Weapon2.Damage.Low
'random damage for the hit damage = damage + Hero.Weapon2.DamageBonus 'add in the weapon's damage bonus
IF totalroll
< Chancetohit
- 20 THEN 'you critically failed! SetTextColor PrintArea, &HFFF000F0, 0
out$
= out$
+ " CRITICALLY FAILED attacking. They hit themselves for" damage
= damage
- Hero.Armor.PD:
IF damage
< 0 THEN damage
= 0 'armor absorbs some damage for us Hero.Life.Low = Hero.Life.Low - damage
SetTextColor PrintArea, &HFFF0F000, 0
SetTextColor PrintArea, &HFF00FF00, 0
damage = damage * (totalroll \ 20 + 1)
damage
= damage
- Monster
(M
).Armor.PD:
IF damage
< 0 THEN damage
= 0 'armor absorbs some damage for us" Encounter(AtWhom).Life = Encounter(AtWhom).Life - damage
SetTextColor PrintArea, &HFF00FF00, 0
damage
= damage
- Monster
(M
).Armor.PD:
IF damage
< 0 THEN damage
= 0 'armor absorbs some damage for us" Encounter(AtWhom).Life = Encounter(AtWhom).Life - damage
IF Encounter
(AtWhom
).Life
<= 0 THEN 'the monster died! SetTextColor PrintArea, &HFFFF0000, 0
Encounter(AtWhom).Active = 0
Hero.EXP_Earned = Hero.EXP_Earned + Monster(M).Level + Monster(M).ExpBonus
MapArray
(Encounter
(AtWhom
).X
, Encounter
(AtWhom
).Y
) = MapArray
(Encounter
(AtWhom
).X
, Encounter
(AtWhom
).Y
) AND NOT 32 'the way is no longer blocked once we kill the monster! ELSE 'it's a monster attacking
FUNCTION MoveMonster
(Monster
, MoveX
, MoveY
) MX = Encounter(Monster).X: MY = Encounter(Monster).Y 'monster x, monster y position
D = Distance(MX, MY) 'distance from monster to the hero
E = Encounter(i).M 'the actual monster in question
IF D
> Distance
(MX
+ MoveX
, MY
+ MoveY
) THEN IF (MapArray
(MX
+ MoveX
, MY
+ MoveY
) AND 32) = 0 THEN 'where we're trying to move isn't blocked MapArray
(MX
, MY
) = MapArray
(MX
, MY
) AND NOT 32 'unblock where the monster is Encounter(Monster).X = Encounter(Monster).X + MoveX
Encounter(Monster).Y = Encounter(Monster).Y + MoveY
MapArray
(MX
+ MoveX
, MY
+ MoveY
) = MapArray
(MX
+ MoveX
, MY
+ MoveY
) OR 32 'block where the monster moved to MoveMonster = -1
FOR i
= 1 TO EncounterLimit
IF Encounter
(i
).Active
THEN 'Only if the monster is still alive and active do we need to actually do anything else. MX = Encounter(i).X: MY = Encounter(i).Y 'monster x, monster y position
D = Distance(MX, MY) 'distance from monster to the hero
E = Encounter(i).M 'the actual monster in question
IF D
< Monster
(E
).Sight
OR D
<= Monster
(E
).Hearing
OR D
<= Monster
(E
).Detection
THEN
attack = 0
IF D
<= Monster
(E
).Weapon1.Reach
THEN 'we're in reach for the monster to attack with their main hand. 'insert attack code here
IF D
<= Monster
(E
).Weapon2.Reach
THEN 'we're in reach for the monster to attack with their off hand. 'insert attack code here
IF attack
= 0 THEN 'if the monster didn't attack, it can now move towards the hero. IF MX
> 0 THEN 'check to see if moving left moves us towards the hero. IF D
> Distance
(MX
- 1, MY
) THEN IF MY
> 0 THEN 'check to see if moving up moves us towards the hero. IF D
> Distance
(MX
, MY
- 1) THEN IF MX
< XH
THEN 'check to see if moving right moves us towards the hero. IF D
> Distance
(MX
+ 1, MY
) THEN IF MY
< YH
THEN 'check to see if moving down moves us towards the hero. IF D
> Distance
(MX
, MY
+ 1) THEN
LINE (0, 0)-(800, 600), &HFF0000FF, BF
'clear the map IF Distance
(X
, Y
) <= Hero.Light.Reach
THEN 'It's close enough to check for illumination IF MapArray
(X
, Y
) <> 0 THEN MapArray
(X
, Y
) = MapArray
(X
, Y
) OR 1 OR 2 IF MapArray
(X
, Y
) AND 2 THEN 'It's an uncovered part of the map, draw it IF MapArray
(X
, Y
) AND 4 THEN 'it's a visible room IF MapArray
(X
, Y
) AND 8 THEN 'it's a visible path COLOR &HFF000000, &HFF777777 IF MapArray
(X
, Y
) AND 16 THEN 'it's the stairs to the next level COLOR &HFF00FF00, &HFFFFFF00 'note: highlighting for the light should come AFTER the map is drawn
IF MapArray
(X
, Y
) AND 1 THEN 'it's currently illuminated by the lightsource MapArray(X, Y) = MapArray(X, Y) - 1
FOR i
= 1 TO EncounterLimit
IF X
= Encounter
(i
).X
AND Y
= Encounter
(i
).Y
AND Encounter
(i
).Active
= -1 THEN E = Encounter(i).M
COLOR &HFFFFFF00, 0 'Yellow Hero
SUB CreateMap
(XLimit
, YLimit
, Rooms
) ERASE MapArray
'clear the old map and reset everything to 0 XL = 0: XH = XLimit: YL = 0: YH = YLimit 'global values to pass along our map ultimate dimensions
RoomX
= INT(RND * (XLimit
- RoomSize
)) RoomY
= INT(RND * (YLimit
- RoomSize
)) 'test for positioning
good = -1 'it's good starting out
IF MapArray
(RoomX
+ X
, RoomY
+ Y
) = 4 THEN good
= 0:
EXIT FOR 'don't draw a room on a room MapArray(RoomX + X, RoomY + Y) = 4 'go ahead and draw a room
RoomCenterX(i) = RoomX + .5 * RoomSize
RoomCenterY(i) = RoomY + .5 * RoomSize
StartX = RoomCenterX(i): StartY = RoomCenterY(i)
EndX = RoomCenterX(i + 1): EndY = RoomCenterY(i + 1)
CoinToss
= INT(RND * 100) 'Coin toss to move left/right or up/down, to go towards room, or wander a bit. Meander = 10
IF CoinToss
MOD 2 THEN 'even or odd, so we only walk vertical or hortizontal and not diagional IF CoinToss
< 100 - Meander
THEN 'Lower values meander less and go directly to the target. XChange
= SGN(EndX
- StartX
) '-1,0,1, drawn always towards the mouse Ychange = 0
XChange
= INT(RND * 3) - 1 '-1, 0, or 1, drawn in a random direction to let the lightning wander Ychange = 0
IF CoinToss
< 100 - Meander
THEN 'Lower values meander less and go directly to the target. Ychange
= SGN(EndY
- StartY
) XChange = 0
XChange = 0
StartX = StartX + XChange
StartY = StartY + Ychange
IF MapArray
(StartX
, StartY
) = 0 THEN MapArray
(StartX
, StartY
) = 8 Hero.X
= INT(RND * XLimit
+ 1) Hero.Y
= INT(RND * YLimit
+ 1) LOOP UNTIL MapArray
(Hero.X
, Hero.Y
) AND 4 'place the hero randomly, until they're in a room somewhere MapArray
(Hero.X
, Hero.Y
) = MapArray
(Hero.X
, Hero.Y
) OR 32 'block the map where the hero stands LOOP UNTIL MapArray
(X
, Y
) AND 4 'get a random spot in a room, for the stairs to the next level MapArray
(X
, Y
) = MapArray
(X
, Y
) OR 16 PathFind
EncounterLimit
= INT(RND * 6) + 5 FOR i
= 1 TO EncounterLimit
Encounter(i).M = RandomMonster
Encounter(i).Active = -1
Encounter
(i
).Life
= INT(RND * Monster
(Encounter
(i
).M
).Life.High
- Monster
(Encounter
(i
).M
).Life.Low
+ 1) + Monster
(Encounter
(i
).M
).Life.Low
valid = -1
Encounter
(i
).X
= INT(RND * XLimit
+ 1) Encounter
(i
).Y
= INT(RND * YLimit
+ 1) IF MapArray
(Encounter
(i
).X
, Encounter
(i
).Y
) AND 32 THEN valid
= 0 'the spot where we're wanting to place our monster is invalid. (Another monster or the hero is probably there.) LOOP UNTIL MapArray
(Encounter
(i
).X
, Encounter
(i
).Y
) AND 4 AND valid
'monsters only spawn in rooms to begin with. MapArray
(Encounter
(i
).X
, Encounter
(i
).Y
) = MapArray
(Encounter
(i
).X
, Encounter
(i
).Y
) OR 32
STATIC m
AS _MEM, m1
AS _MEM 'no need to keep initializing and freeing these blocks over and over. Just reuse them... _MEMFILL m1
, m1.OFFSET
, m1.SIZE
, 255 AS _UNSIGNED _BYTE 'flush distance with 255 values until we see how far things actually are from the hero Temp(Hero.X, Hero.Y) = 0
pass = 0
changed = 0
y = 0
x = 0
IF Distance
(x
, y
) = 255 AND MapArray
(x
, y
) <> 0 THEN IF Temp
(x
+ 1, y
) = pass
THEN Distance
(x
, y
) = pass
+ 1: changed
= -1 IF Temp
(x
- 1, y
) = pass
THEN Distance
(x
, y
) = pass
+ 1: changed
= -1 IF Temp
(x
, y
+ 1) = pass
THEN Distance
(x
, y
) = pass
+ 1: changed
= -1 IF Temp
(x
, y
- 1) = pass
THEN Distance
(x
, y
) = pass
+ 1: changed
= -1 x = x + 1
y = y + 1
pass = pass + 1
LOOP UNTIL changed
= 0 OR pass
= 255 'if we're more than 255 steps from the hero, we don't need to know where the hell we're at. We're off the map as far as the hero is concerned! Distance(Hero.X, Hero.Y) = 0
'Shared variable level tells us what level of the dungeon we're on.
STATIC MC
, DS
'monster count and data set DS = -1
Monster
(1).
Name = "Bat": Monster
(1).Life.Low
= 1: Monster
(1).Life.High
= 4: Monster
(1).Level
= 1: Monster
(1).ExpBonus
= 0 Monster(1).Sight = 2: Monster(1).Hearing = 4: Monster(1).Detection = 0
Monster
(1).Weapon1.
Name = "Bite": Monster
(1).Weapon1.Reach
= 1 Monster(1).Weapon1.Damage.Low = 1: Monster(1).Weapon1.Damage.High = 2
'Monster(1).Weapon1.HitBonus = 0: Monster(1).Weapon1.DamageBonus = 0: Monster(1).Weapon1.Left = 0
'Monster(1).Weapon2.Name = "": Monster(1).Weapon2.Reach = 0
'Monster(1).Weapon2.Damage.Low = 0: Monster(1).Weapon2.Damage.High = 0
'Monster(1).Weapon2.HitBonus = 0: Monster(1).Weapon2.DamageBonus = 0: Monster(1).Weapon2.Left = 0
'Monster(1).Armor.Name = ""
'Monster(1).Armor.PD = 0: Monster(1).Armor.DR = 0: Monster(1).Armor.Left = 0
Monster
(2).
Name = "Rat": Monster
(2).Life.Low
= 1: Monster
(2).Life.High
= 4 Monster(2).Level = 1: Monster(2).ExpBonus = 0
Monster(2).Sight = 2: Monster(2).Hearing = 4: Monster(2).Detection = 0
Monster
(2).Weapon1.
Name = "Bite": Monster
(2).Weapon1.Reach
= 1 Monster(2).Weapon1.Damage.Low = 1: Monster(2).Weapon1.Damage.High = 2
Monster
(3).
Name = "Snake": Monster
(3).Life.Low
= 1: Monster
(3).Life.High
= 4 Monster(3).Level = 1: Monster(3).ExpBonus = 0
Monster(3).Sight = 2: Monster(3).Hearing = 4: Monster(3).Detection = 0
Monster
(3).Weapon1.
Name = "Bite": Monster
(3).Weapon1.Reach
= 1 Monster(3).Weapon1.Damage.Low = 1: Monster(3).Weapon1.Damage.High = 2
FOR i
= 1 TO UBOUND(Monster
) 'All monsters first appear as a red question mark on the screen, until battled. Monster
(i
).ID.Symbol
= 63: Monster
(i
).ID.
Color = &HFFFF0000 CASE 1: MC
= 3 'the monster count which we can randomly run into and battle from on the current floor RandomMonster
= INT(RND * MC
) + 1
' ----------------------------------------------------------------------------------------------------------------------------------------------------------- '
'# SUBroutines and FUNCTIONs below #'
' ----------------------------------------------------------------------------------------------------------------------------------------------------------- '
Handle = WhichHandle
Where = TextHandles(Handle).VerticalAlignment
How = TextHandles(Handle).Justification
UpdatePrintPosition = TextHandles(Handle).UpdateMethod
PlaceText Handle, Where, How, What, UpdatePrintPosition
'WhichHandle is the handle which designates which text area we want to use
'Where is where we want it to go in that text area
' -- Online prints the text to the current print position line in that text area.
' -- CenterLine centers the text to the center of that text area.
' -- any other value will print to that line positon in that particular box.
'How tells us how we want to place that text (LeftJustified, RightJustified,CenterJustified, or NoJustify)
'What is the text that we want to print in our text area
'UpdatePrintPosition lets us know if we need to move to a newline or stay on the same line. (Think PRINT with a semicolon vs PRINT without a semicolon).
Handle = WhichHandle
IF TextHandles
(Handle
).HideFrame
THEN _DEST TextHandles
(Handle
).SavedBackground
_SOURCE TextHandles
(Handle
).SavedBackground
h = TextHandles(Handle).h - 4
w = TextHandles(Handle).w - 4
y = h \ fh
y = TextHandles(Handle).Ypos
linesused = 0
tpw = pw: tw = w: tWhat$ = What
linesused = linesused + 1
tWhat$
= MID$(tWhat$
, textallowed
+ 1) linesused = linesused + 1
py = (h - linesused * fh) \ 2
y = py \ fh + 1
y = Where
DO UNTIL y
* fh
< h
'We need to scroll the text area up, if someone is trying to print below it. 'first let's get a temp image handle for the existing area of the screen.
x1 = TextHandles(Handle).x1 + 2
y1 = TextHandles(Handle).y1 + 2
x2 = TextHandles(Handle).x1 + w
y2 = TextHandles(Handle).y1 + h
nh = y2 - y1 + 1 - fh
nw = x2 - x1 + 1
tempimage
= _NEWIMAGE(nw
, nh
, 32) 'Really, I should swap this to a routine to pick which screen mode the user is in, but I'll come back to that later. _PUTIMAGE , , tempimage
, (x1
, y1
+ fh
)-(x2
, y2
) DrawTextArea Handle
y = y - 1
COLOR TextHandles
(Handle
).TextColor
, TextHandles
(Handle
).TextBackgroundColor
x = 0
_PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), text$
PlaceText Handle
, y
+ 1, LeftJustify
, MID$(What
, textallowed
+ 1), 0 _PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), What
finished = -1
_PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), text$
PlaceText Handle
, y
+ 1, CenterJustify
, MID$(What
, textallowed
+ 1), NoUpdate
x = (w - pw) \ 2
_PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), What
finished = -1
_PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), text$
PlaceText Handle
, y
+ 1, RightJustify
, MID$(What
, textallowed
+ 1), 0 x = w - pw
_PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), What
finished = -1
x = TextHandles(Handle).Xpos
firstlinelimit
= (w
- x
) \
_FONTWIDTH 'the limit of characters on the first line textallowed
= WordBreak
(LEFT$(What
, firstlinelimit
)) _PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), text$
PlaceText Handle
, y
+ 1, LeftJustify
, MID$(What
, textallowed
+ 1), 0 'After the first line we start printing over on the left, after a line break _PRINTSTRING (x
+ 2 + TextHandles
(Handle
).x1
, (y
- 1) * fh
+ TextHandles
(Handle
).y1
+ 2), What
finished = -1
CASE NoUpdate
'We don't update the position at all. TextHandles(Handle).Xpos = x + pw
TextHandles(Handle).Ypos = y
TextHandles(Handle).Ypos = y + 1
TextHandles(Handle).Xpos = 1
TextHandles(Handle).TextColor = Foreground
TextHandles(Handle).TextBackgroundColor = Background
TextHandles(Handle).TextColor = Foreground
TextHandles(Handle).TextBackgroundColor = Background
TextHandles(Handle).UpdateMethod = Method
TextHandles(Handle).VerticalAlignment = -2
TextHandles(Handle).VerticalAlignment = -1
TextHandles(Handle).VerticalAlignment = 0
TextHandles(Handle).Justification = X
TextHandles(Handle).Xpos = X
TextHandles(Handle).Ypos = Y
TextHandles(Handle).Justification = X
TextHandles(Handle).Xpos = X
TextHandles(Handle).VerticalAlignment = -2
TextHandles(Handle).VerticalAlignment = -1
TextHandles(Handle).VerticalAlignment = 0
TextHandles(Handle).Ypos = Y
GetPrintPositionY = TextHandles(Handle).Ypos
GetPrintPositionX = TextHandles(Handle).Xpos
loopcount = loopcount + 1
WordBreak = i
IF TextHandles
(Handle
).SavedBackground
THEN w = TextHandles(Handle).w
h = TextHandles(Handle).h
x1 = TextHandles(Handle).ScreenX
y1 = TextHandles(Handle).ScreenY
x2 = x1 + w - 1
y2 = y1 + h - 1
_PUTIMAGE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).SavedBackground
DrawTextArea Handle
w = TextHandles(Handle).w
h = TextHandles(Handle).h
x1 = TextHandles(Handle).ScreenX
y1 = TextHandles(Handle).ScreenY
x2 = x1 + w - 1
y2 = y1 + h - 1
LINE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).BackColor
, BF
LINE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).FrameColor
, B
TextHandles(Handle).FrameColor = FrameColor
TextHandles(Handle).BackColor = BackColor
x1 = tx1: y1 = ty1 'We pass temp variables to the function so we can swap values if needed without altering user variables
x2 = tx2: y2 = ty2
w = x2 - x1 + 1
h = y2 - y1 + 1
'Error checking for if the user sends coordinates which are off the screen
FOR i
= 1 TO u
'First let's check to see if we have an open handle from where one was freed earlier IF Handle
= 0 THEN 'We didn't have an open spot, so we need to add one to our list Handle = u + 1
TextHandles(Handle).x1 = x1
TextHandles(Handle).y1 = y1
TextHandles(Handle).w = w: TextHandles(Handle).h = h
TextHandles(Handle).InUse = True
TextHandles(Handle).Xpos = 0
TextHandles(Handle).Ypos = 1
TextHandles(Handle).UpdateMethod = NewLine
TextHandles
(Handle
).TextColor
= _RGB32(255, 255, 255) 'White text TextHandles
(Handle
).TextBackgroundColor
= _RGB32(0, 0, 0) 'Black background
_PUTIMAGE , 0, imagehandle
, (x1
, y1
)-(x2
, y2
) TextHandles(Handle).SavedBackground = imagehandle
TextHandles(Handle).ScreenX = x1
TextHandles(Handle).ScreenY = y1
NewTextArea% = Handle
IF TextHandles
(Handle
).InUse
THEN TextHandles(Handle).InUse = False
IF TextHandles
(Handle
).SavedBackground
THEN IF TextHandles
(Handle
).HideFrame
= 0 THEN 'If the frame isn't hidden, then restore what's supposed to be beneath it w = TextHandles(Handle).w
h = TextHandles(Handle).h
x1 = TextHandles(Handle).ScreenX
y1 = TextHandles(Handle).ScreenY
x2 = x1 + w - 1
y2 = y1 + h - 1
_PUTIMAGE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).SavedBackground
'Even if it is hidden though, if we're going to free that frame, we need to free the stored image held with it to reduce memory usage.
ERROR 258 'Invalid handle if the user tries to free a handle which has already been freed. ERROR 5 'Illegal function call if the user tries to free a handle that doesn't exist at all.
IF TextHandles
(Handle
).HideFrame
= 0 THEN 'only if the frame isn't hidden, can we hide it. TextHandles(Handle).HideFrame = -1
w = TextHandles(Handle).w
h = TextHandles(Handle).h
x1 = TextHandles(Handle).ScreenX
y1 = TextHandles(Handle).ScreenY
x2 = x1 + w - 1
y2 = y1 + h - 1
imagehandle
= _NEWIMAGE(TextHandles
(Handle
).w
, TextHandles
(Handle
).h
, 32) _PUTIMAGE , 0, imagehandle
, (x1
, y1
)-(x2
, y2
) IF TextHandles
(Handle
).SavedBackground
THEN _PUTIMAGE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).SavedBackground
TextHandles(Handle).SavedBackground = imagehandle
TextHandles(Handle).x1 = 0 'When the frames are hidden, we calculate our print position based off the hidden image
TextHandles(Handle).y1 = 0 'So we'd start at point (0,0) as being top left
IF TextHandles
(Handle
).HideFrame
THEN 'only if we have a hidden frame do we have to worry about restoring it TextHandles(Handle).HideFrame = 0
w = TextHandles(Handle).w
h = TextHandles(Handle).h
x1 = TextHandles(Handle).ScreenX
y1 = TextHandles(Handle).ScreenY
x2 = x1 + w - 1
y2 = y1 + h - 1
imagehandle
= _NEWIMAGE(TextHandles
(Handle
).w
, TextHandles
(Handle
).h
, 32) _PUTIMAGE , 0, imagehandle
, (x1
, y1
)-(x2
, y2
) _PUTIMAGE (x1
, y1
)-(x2
, y2
), TextHandles
(Handle
).SavedBackground
', 0, (0, 0)-(w, h) TextHandles(Handle).SavedBackground = imagehandle
TextHandles(Handle).x1 = x1 'When the frames are frames are restored, we need to recalculate our print position
TextHandles(Handle).y1 = y1 'as we're no longer going over the image cooridinates, but the screen location of the top left corner instead.
'Only two coordinates here, so we'll be positioning our frames new movement by the top left corner.
HideFrame Handle
TextHandles(Handle).ScreenX = x1
TextHandles(Handle).ScreenY = y1
RestoreFrame Handle