VWF-Dialoge v1.0

geschrieben am 13.11.2010 8:29:00
zuletzt bearbeitet von RPG Hacker am 20.04.2011 22:21:04.
( Link )
VWF-Dialoge v1.0





Dieser Patch erlaubt es euch in eurem Spiel VWF-Dialoge in Text-Boxen zu verwenden, wie es in einigen RPGs auf dem SNES der Fall war. Bisher ist der Einsatz leider noch ziemlich kompliziert und die Readme habe ich auch noch nicht ins Deutsche übersetzt. Die englische Readme ist dafür aber umso detailierter.

Download:
http://www.rpg-hacker.de/SMW/Downloads/Patches/VWFPatch/VWFPatchLatest.rar
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 9:17:25
( Link )
Von den Bildern her,sieht's genial aus,ich werd' es später "testen"...
´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 9:28:48
( Link )
Sag dann einfach hier Bescheid, falls du irgendetwas nicht verstehst oder etwas nicht funktioniert. Unter Umständen kann die Readme nämlich hier und da vielleicht doch schwer zu verstehen sein, insbesondere weil sie ja nur auf Englisch ist.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 10:29:53
( Link )
Na ja,das Readme ist super geschrieben,ich verstehe alles,aber was ist das:

Zitat von Readme:
I really recommend you get YY-CHR v0.99, though. Nope, YY-CHR v0.98 won't do in this case. YY-CHR v0.99 has a very special and useful feature which YY-CHR v0.98 doesn't have and which is needed for editing fonts. I'll use YY-CHR v0.99 for all tile editor references in this Readme.


Wo kriegt man YY-CHR v0.99?

Und hier ist ein Bild :

´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 10:39:33
( Link )
Da, wo man auch alle anderen Tools herkriegt...
http://www.smwcentral.net/download.php?id=209&type=tools
geschrieben am 13.11.2010 10:43:52
( Link )
Zitat von TheSuperDomy™:
Wo kriegt man YY-CHR v0.99?


Hier:
SMW Central Download

Zitat von TheSuperDomy™:
Und hier ist ein Bild :



Hehe!
Wegen des Rahmens wahrscheinlich wohl eine zu hohe Nummer bei "!defframe" eingegeben?
Weshalb der Text zustande kommt, weiß ich noch nicht. Vielleicht die Message Pointers bearbeitet? Oder vwftable.txt? Oder den Dialog selbst?
Könntest mir ja einfach mal alle Veränderungen zeigen, die du vorgenommen hast, dann könnte ich das untersuchen.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 11:05:32
( Link )
Hier bitte,vwfdialogues.asm:

Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;VWF Dialogues Patch by RPG Hacker;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


header
lorom

print ""
print ""
print "VWF Dialogues Patch v1.0 - (c) 2010 RPG Hacker"



!freespace = $248000 ; Main code freespace
!textfreespace = $258000 ; Text freespace





;;;;;;;;;;;;;;;;
;Adress Defines;
;;;;;;;;;;;;;;;;


; These have to be 24-Bit addresses!

!varram = $727E00 ; 200 bytes
!backupram = $730000 ; 16 kb to backup L3 graphics and tilemap
!tileram = $734000 ; 16 kb for VWF graphics and tilemap





;;;;;;;;;;;;;;;;;;
;Default Settings;
;;;;;;;;;;;;;;;;;;


; These are the default values to use if not changed ingame.

!defbg = #$08
!bgcolor = #$44C4
!defframe = #$07
!framepalette = #$03

!bitmode = 0
!hijackbox = 1





;;;;;;;;
;Labels;
;;;;;;;;



; DO NOT EDIT THOSE!!!



!vwfmode = !varram ; 1 byte
!message = !varram+1 ; 2 bytes
!counter = !varram+3 ; 1 byte

!width = !varram+4 ; 1 byte
!height = !varram+5 ; 1 byte
!xpos = !varram+6 ; 1 byte
!ypos = !varram+7 ; 1 byte
!boxbg = !varram+8 ; 1 byte
!boxcolor = !varram+9 ; 6 bytes
!boxframe = !varram+15 ; 1 byte
!boxcreate = !varram+16 ; 1 byte
!boxpalette = !varram+17 ; 1 byte
!freezesprites = !varram+18 ; 1 byte
!beep = !varram+19 ; 1 byte
!beepbank = !varram+20 ; 2 bytes
!beepend = !varram+22 ; 1 byte
!beependbank = !varram+23 ; 2 bytes
!beepcursor = !varram+25 ; 1 byte
!beepcursorbank = !varram+26 ; 2 bytes
!beepchoice = !varram+28 ; 1 byte
!beepchoicebank = !varram+29 ; 2 bytes
!font = !varram+31 ; 1 byte
!edge = !varram+32 ; 1 byte
!space = !varram+33 ; 1 byte
!frames = !varram+34 ; 1 byte
!layout = !varram+35 ; 1 byte
!soundoff = !varram+36 ; 1 byte
!speedup = !varram+37 ; 1 byte
!autowait = !varram+38 ; 1 byte

!vrampointer = !varram+39 ; 2 bytes
!currentwidth = !varram+41 ; 1 byte
!currentheight = !varram+42 ; 1 byte
!currentx = !varram+43 ; 1 byte
!currenty = !varram+44 ; 1 byte

!vwftextsource = !varram+45 ; 3 bytes
!vwfbytes = !varram+48 ; 2 bytes
!vwfgfxdest = !varram+50 ; 3 bytes
!vwftilemapdest = !varram+53 ; 3 bytes
!vwfpixel = !varram+56 ; 2 bytes
!vwfmaxwidth = !varram+58 ; 1 byte
!vwfmaxheight = !varram+59 ; 1 byte
!vwfchar = !varram+60 ; 2 bytes
!vwfwidth = !varram+62 ; 1 byte
!vwfroutine = !varram+63 ; 15 bytes
!vwftileram = !varram+78 ; 96 bytes
!tile = !varram+174 ; 1 byte
!property = !varram+175 ; 1 byte
!currentpixel = !varram+176 ; 1 byte
!firsttile = !varram+177 ; 1 byte
!clearbox = !varram+178 ; 1 byte
!wait = !varram+179 ; 1 byte
!timer = !varram+180 ; 1 byte
!teleport = !varram+181 ; 1 byte
!telepdest = !varram+182 ; 2 bytes
!telepprop = !varram+184 ; 1 byte
!forcesfx = !varram+185 ; 1 byte
!widthcarry = !varram+186 ; 1 byte
!choices = !varram+187 ; 1 byte
!cursor = !varram+188 ; 2 bytes
!currentchoice = !varram+190 ; 1 byte
!choicetable = !varram+191 ; 3 bytes
!choicespace = !varram+194 ; 1 byte
!choicewidth = !varram+195 ; 1 byte
!cursormove = !varram+196 ; 1 byte
!nochoicelb = !varram+197 ; 1 byte
!cursorupload = !varram+198 ; 1 byte
!cursorend = !varram+199 ; 1 byte

!8bit = "rep 0-!bitmode :"
!16bit = "rep !bitmode-1 :"
!hijack = "rep !hijackbox-1 :"





;;;;;;;;
;Macros;
;;;;;;;;

; A simple macro to prepare VRAM operations

macro vramprepare(vramsettings, vramaddress, readword, readbyte)
lda
sta $2115
rep #$20
lda
sta $2116
; "lda $2139" for word VRAM reads
sep #$20
; "lda $2139/$213A" for byte VRAM reads
endmacro





; A simple Macro for DMA transfers

macro dmatransfer(channel, dmasettings, destination, sourcebank, sourcehigh, sourcelow, bytes)
lda
sta $4340
lda
sta $4341
lda ; I put the label close to the opcode
sta $4342 ; to allow length definitions
lda
sta $4343
lda
sta $4344
rep #$20
lda
sta $4345
sep #$20
lda
sta $420B
endmacro





; A macro for MVN transfers

macro mvntransfer(bytes, start, source, destination)
phb
lda.b # ; Calculate starting index
sta $211B
lda.b #>>16
sta $211B
lda #$00
sta $211C
lda
sta $211C
rep #$30
lda $2134 ; Add source address
clc ; to get new source address
adc.w #
tax
ldy.w # ; Destination address
lda.w #-1 ; Number of bytes
db $54 ; MVN opcode in Hex
db >>16
db >>16
sep #$30
plb
endmacro





; Macros for new banks

macro newbank(identifier, freespace)
!currentfreespace =
!currentbank = ""
org !currentfreespace|$800000
reset bytes

Bank:

cleartable

db "STAR"
dw BankEnd-.Begin
dw BankEnd-.Begin^#$FFFF

.Begin
endmacro


macro endbank()
!banklabel = Bank!currentbank
!endlabel = End
!banklabel!endlabel:

org !currentfreespace

print bytes," bytes written at address $",pc,"."
endmacro


macro binary(identifier, data)
!banklabel = Bank!currentbank
!datalabel = Data
!banklabel!datalabel:
incbin
endmacro


macro source(identifier, data)
!banklabel = Bank!currentbank
!datalabel = Data
!banklabel!datalabel:
incsrc
endmacro





; Macros for text files

macro textstart()
cleartable
table vwftable.txt
endmacro

macro textend()
!8bit db $00
db %00001000,%01111000,%11010001,%11000000,$01,%00100000
dw $7FFF,$0000
db %11110100
db %00001111,$13,$13,$23,$29

!8bit db $FA
!8bit db $FF
!16bit dw $FFFA
!16bit dw $FFFF
endmacro





;;;;;;;;;
;Hijacks;
;;;;;;;;;


org $008055|$800000 ; Initialize RAM to prevent glitches
jml InitCall|$800000 ; or game crashes
nop #2

org $0081F2|$800000 ; V-Blank code goes here
jml VBlank|$800000
nop

org $008297|$800000 ; Hijack NMI for various things
jml NMIHijack|$800000
nop #$2

org $0086E2|$800000 ; Call RAM Init Routine on Title
jml InitMode|$800000 ; Screen

org $00A1DF|$800000 ; Hijack message box to call VWF dialogue
!hijack jsl MessageBox|$800000

org $00A2A9|$800000 ; Buffer data before loading up to VRAM
jml Buffer|$800000 ; in V-Blank
nop #2

org $00FFD8|$800000 ; SRAM expansion ($07 => 2^7 kb)
db $07





;;;;;;;;;;;;;;;;;
;MAIN CODE START;
;;;;;;;;;;;;;;;;;


org !freespace|$800000

reset bytes

db "STAR" ; Protect patch data
dw Codeend-Codestart
dw Codeend-Codestart^#$FFFF


Codestart:





;;;;;;;;;;;;;;;;;;;;
;RAM Initialization;
;;;;;;;;;;;;;;;;;;;;


; This section handles RAM initialization. It initializes the used
; RAM addresses at game startup, title screen and Game Over to
; prevent glitches and possible crahses.

InitCall:
jsr InitRAM ; RAM init on game start
stz $0100
stz $0109
jml $00805B|$800000



InitMode:
sty $00
pha
lda $0100
cmp #$03
bne .NoTitle
jsr InitRAM ; RAM init on Title Screen

.NoTitle
pla
rep #$30
jml $0086E6|$800000



InitRAM:
phx
rep #$30
ldx #$0000
lda #$0000

.InitVarRAM
sta !varram,x ; Initialize RAM
inx #2
cpx #$00C8 ; Number of bytes
bne .InitVarRAM
sep #$30

.SetDefaults
lda !defbg ; Set default values
sta !boxbg
lda !defframe
sta !boxframe

lda.b !bgcolor
sta !boxcolor
lda.b !bgcolor>>8
sta !boxcolor+1

.End
plx
rts





;;;;;;;;;;;;;;;;;;;;
;Message Box Hijack;
;;;;;;;;;;;;;;;;;;;;


; This hijacks SMW's original message routine to work with VWF
; dialogues.

MessageBox:
lda !vwfmode ; Already displaying a message?
beq .CallDialogue
stz $1426
rtl

.CallDialogue
lda $1426 ; Yoshi Special Message?
cmp #$03
bne .NoYoshi
lda #$01
sta !message
bra .SetMessage

.NoYoshi
lda $0109 ; Intro Level Message?
beq .NoIntro
lda #$00
sta !message
bra .SetMessage

.NoIntro
lda $03BB9B|$800000 ; Inside Yoshi's House? (LM hacked
cmp #$FF ; ROM only)
bne .HackedROM
lda #$28

.HackedROM
cmp $13BF
bne .NoYoshiHouse
lda $187A ; Currently riding Yoshi?
beq .NoYoshiHouse
lda #$02
sta $1426

.NoYoshiHouse
lda $13BF ; No special message, use regular message
asl ; formula
clc
adc $1426
dec
sta !message

.SetMessage
lda #$00
sta !message+1
stz $1426
lda #$01
sta !vwfmode

.End
rtl





;;;;;;;;;;;;
;NMI Hijack;
;;;;;;;;;;;;

; This changes the NMI Routine to move layer 3 and disable IRQ during
; dialogues.

NMIHijack:
phx
lda !vwfmode
tax
lda .NMITable,x
bne .SpecialNMI ; If NMITable = $00 load regular NMI
sty $4209
stz $420A
stz $11
lda #$A1
sta $4200
stz $2111
stz $2111
stz $2112
stz $2112
bra .End

.SpecialNMI
stz $11 ; Else load special NMI
lda #$81 ; Disable IRQ
sta $4200
lda #$00 ; Set layer 3 X scroll to $0100
sta $2111
lda #$01
sta $2111
lda #$1F ; Set layer 3 Y scroll to $011F
sta $2112
lda #$01
sta $2112

.End
plx
jml $0082B0|$800000

.NMITable
db $00,$00,$00,$01,$01
db $01,$01,$01,$01,$01
db $01,$01,$01,$00,$00





;;;;;;;;;;;;;
;Tile Buffer;
;;;;;;;;;;;;;

; This buffers code to save time in V-Blank.

Buffer:
phx
phy
pha
phb
php
phk
plb

lda $13D4
beq .NoPause
bra .End

.NoPause
lda !vwfmode ; Prepare jump to routine
beq .End
asl
tax
lda .Routinetable,x
sta $00
inx
lda .Routinetable,x
sta $01
phk
pla
sta $02

lda !freezesprites ; Freeze sprites if flag is set
beq .NoFreezeSprites
lda #$02
sta $13FB
sta $9D
sta $13D3
lda $15
and #$BF
sta $15
lda $16
and #$BF
sta $16
lda $17
and #$BF
sta $17
lda $18
and #$BF
sta $18

.NoFreezeSprites
jml [$0000]

.End
plp ; Return
plb
pla
ply
plx

lda $1C
pha
lda $1D
pha
jml $00A2AF|$800000

.Routinetable
dw .End,.End,VWFSetup,BufferGraphics,.End
dw .End,BufferWindow,VWFInit,TextCreation,CollapseWindow
dw .End,.End,.End,.End,.End





VWFSetup:
jsr GetMessage
jsr LoadHeader
jmp Buffer_End

LoadHeader:
lda !vwftextsource
sta $00
lda !vwftextsource+1
sta $01
lda !vwftextsource+2
sta $02

ldy #$00

!8bit lda [$00],y ; Font
!8bit sta !font
!8bit iny

lda [$00],y ; X position
lsr #3
sta !xpos

rep #$20 ; Y position
lda [$00],y
xba
and #$07C0
lsr #6
sep #$20
sta !ypos
iny

lda [$00],y ; Width
and #$3C
lsr #2
sta !width

rep #$20 ; Height
lda [$00],y
xba
and #$03C0
lsr #6
sep #$20
sta !height
iny

lda [$00],y ; Edge
and #$3C
lsr #2
sta !edge

rep #$20 ; Space
lda [$00],y
xba
and #$03C0
lsr #6
sep #$20
sta !space
iny

lda [$00],y ; Text speed
and #$3F
sta !frames
iny

lda [$00],y ; Auto wait
sta !autowait
iny

lda [$00],y ; Box creation style
lsr #4
sta !boxcreate
iny

lda [$00],y ; Letter color
sta !boxcolor+2
iny
lda [$00],y
sta !boxcolor+3
iny

lda [$00],y ; Shading color
sta !boxcolor+4
iny
lda [$00],y
sta !boxcolor+5
iny

lda [$00],y ; Freeze sprites?
lsr #7
sta !freezesprites
sta $13FB
sta $9D
sta $13D3

lda !freezesprites
beq .NoFreezeSprites
and #$BF
sta $15
lda $16
and #$BF
sta $16
lda $17
and #$BF
sta $17
lda $18
and #$BF
sta $18

.NoFreezeSprites
lda [$00],y ; Letter palette
and #$70
lsr #4
sta !boxpalette

lda [$00],y ; Layout
and #$08
lsr #3
sta !layout

lda [$00],y ; Speed up
and #$04
lsr #2
sta !speedup

lda [$00],y ; Disable sounds
and #$01
sta !soundoff
iny

lda !soundoff
bne .NoSounds
rep #$20 ; SFX banks
lda [$00],y
and #$00C0
lsr #6
clc
adc #$1DF9
sta !beepbank
lda [$00],y
and #$0030
lsr #4
clc
adc #$1DF9
sta !beependbank
lda [$00],y
and #$000C
lsr #2
clc
adc #$1DF9
sta !beepcursorbank
lda [$00],y
and #$0003
clc
adc #$1DF9
sta !beepchoicebank
sep #$20
iny

lda [$00],y ; SFX numbers
sta !beep
iny
lda [$00],y
sta !beepend
iny
lda [$00],y
sta !beepcursor
iny
lda [$00],y
sta !beepchoice
iny

rep #$20
lda $00
clc
adc #$0005
sta $00

.NoSounds
rep #$20
lda $00
clc
!8bit adc #$000C
!16bit adc #$000B
sta !vwftextsource
sep #$20


.ValidationChecks
lda !width ; Validate all inputs
cmp #$10
bcc .WidthCheck2
lda #$0F
sta !width
bra .WidthOK

.WidthCheck2
cmp #$00
bne .WidthOK
lda #$01
sta !width


.WidthOK
lda !height
cmp #$0E
bcc .HeightCheck2
lda #$0D
sta !height
bra .HeightOK

.HeightCheck2
cmp #$00
bne .HeightOK
lda #$01
sta !height


.HeightOK
lda !width
asl
inc #2
sta $0F
clc
adc !xpos
cmp #$21
bcc .XPosOK
lda #$20
sec
sbc $0F
sta !xpos


.XPosOK
lda !height
asl
inc #2
sta $0F
clc
adc !ypos
cmp #$1D
bcc .YPosOK
lda #$1C
sec
sbc $0F
sta !ypos

.YPosOK
lda !width
cmp #$03
bcs .EdgeOK
lda !edge
and #$07
sta !edge
lda !width
cmp #$02
bcs .EdgeOK
lda #$00
sta !edge


.EdgeOK
lda !boxcreate
cmp #$05
bcc .StyleOK
lda #$04
sta !boxcreate

.StyleOK
rts





BufferGraphics:
rep #$30
ldx #$0000
lda #$0000

.DrawEmpty
sta !tileram,x ; Draw empty tile
inx #2
cpx #$0010
bne .DrawEmpty
sep #$30

jsr ClearScreen

; Copy text box graphics over to RAM

%mvntransfer($0010,!boxbg,Patterns,!tileram+16)
%mvntransfer($0090,!boxframe,Frames,!tileram+32)

jmp Buffer_End


; This routine clears the screen by filling the tilemap with $00.

ClearScreen:
lda Emptytile
sta !tile
lda !boxpalette
asl #2
ora Emptytile+1
sta !property
rep #$30
ldx #$0000
lda !tile

.InitTilemap
sta !tileram+$3900,x
inx #2
cpx #$0700
bne .InitTilemap

sep #$30
rts




BufferWindow:
lda !counter ; Buffer text box tilemap
bne .SkipInit
lda #$00 ; Text box init
sta !currentwidth
sta !currentheight
lda !xpos
clc
adc !width
sta !currentx
lda !ypos
clc
adc !height
sta !currenty
lda #$01
sta !counter

.SkipInit
lda !boxcreate ; Prepare jump to routine
asl
tax
lda .Routinetable,x
sta $00
inx
lda .Routinetable,x
sta $01
phk
pla
sta $02

jml [$0000]

.Routinetable
dw .NoBox,.SoEBox,.SoMBox,.MMZBox,.InstBox

.End
jmp Buffer_End



.NoBox
lda #$02 ; No text box
sta !counter
jmp .End



.SoEBox
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !width
asl
sta !currentwidth
jsr DrawBox

lda !height
asl
cmp !currentheight
bne .SoEEnd
lda #$02
sta !counter

.SoEEnd
lda !currentheight
inc
sta !currentheight
jmp .End



.SoMBox
lda !width
asl
cmp !currentwidth
beq .ExpandVert
jsr SoMLine
lda !currentwidth
inc #2
sta !currentwidth
lda !currentx
dec
sta !currentx
jmp .End

.ExpandVert
lda !height
asl
cmp !currentheight
bcc .SoMEnd
jsr DrawBox
lda !currentheight
inc #2
sta !currentheight
lda !currenty
dec
sta !currenty
jmp .End

.SoMEnd
lda #$02
sta !counter
jmp .End



.MMZBox
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !height
asl
sta !currentheight
jsr DrawBox

lda !width
asl
cmp !currentwidth
bne .MMZEnd
lda #$02
sta !counter

.MMZEnd
lda !currentwidth
inc
sta !currentwidth
jmp .End



.InstBox
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !width
asl
sta !currentwidth
lda !height
asl
sta !currentheight
jsr DrawBox

.InstEnd
lda #$02
sta !counter
jmp .End



SoMLine:
lda !currentx
sta $00
lda !currenty
sta $01
lda #$01
sta $02
jsr GetTilemapPos
rep #$20
lda.w #!tileram+$3900
clc
adc $03
sta $03
sep #$20
lda.b #!tileram+$3900>>16
sta $05

ldy #$00
lda.b #!framepalette<<2|$20
xba
jsr LineLoop

ldy #$40
lda.b #!framepalette<<2|$A0
xba
jsr LineLoop
rts


LineLoop:
lda !currentwidth
lsr
inc
tax
phx
lda #$08
rep #$20
and #$BFFF
sta [$03],y
dex
iny #2
inc

.Loop1
cpx #$00
beq .Prepare2
sta [$03],y
dex
iny #2
bra .Loop1

.Prepare2
ora #$4000
plx

.Loop2
cpx #$01
beq .End
sta [$03],y
dex
iny #2
bra .Loop2

.End
dec
sta [$03],y
sep #$20
rts


; This routine takes the variables !currentx, !currenty,
; !currentwidth and !currentheight to create a complete text box
; in RAM, utilizing all of the the subroutines below.

DrawBox:
lda !currentx ; Create background
sta $00
lda !currenty
sta $01
lda.b #!tileram+$3900
sta $03
lda.b #!tileram+$3900>>8
sta $04
lda.b #!tileram+$3900>>16
sta $05
lda !currentwidth
sta $06
lda !currentheight
sta $07
jsr DrawBG

lda !currentx ; Create frame
sta $00
lda !currenty
sta $01
lda.b #!tileram+$3900
sta $03
lda.b #!tileram+$3900>>8
sta $04
lda !currentwidth
sta $06
lda !currentheight
sta $07
jsr AddFrame
rts


; This subroutine calculates the correct position of a tilemap with
; $7E0000 as X coordinate and $7E0001 as Y coordinate.
; If $7E0002 = $01 then the tilemap consists of two bytes per tile.
; The result is returned at $7E0003-$7E0004 to be added to the
; tilemap starting address after this routine is done.

GetTilemapPos:
lda $02 ; Tilemap consists of double bytes?
beq .NoDouble
lda $00
asl
sta $00
lda #$20
asl
bra .Store

.NoDouble
lda #$20

.Store
sta $211B ; Multiply Y coordinate by $20/$40
lda #$00
sta $211B
sta $211C
lda $01
sta $211C
lda #$00
xba
lda $00
rep #$20
clc
adc $2134
sta $03
sep #$20
lda $02
beq .End
lda $00 ; Half $7E0000 again if previously doubled
lsr
sta $00

.End
rts


; This draws the background of a text box. $7E0001-$7E0004 are the
; same as in GetTilemapPos, but $7E0002 gets set automatically.
; $7E0006 contains the width and $7E0007 the height of the text box.
; $7E0008-$7E000A are used as temporary variables.

DrawBG:
lda $06 ; Skip if width or height equal $00
beq .End

lda $07
beq .End

lda $01
sta $0A
lda $07 ; Load text box height and add y position
clc ; for a backwards loop
adc $01
sta $01
lda #$01
sta $02
lda $03
sta $08
lda $04
sta $09

.InstLoopY
jsr GetTilemapPos ; Get tilemap position
rep #$20
lda $08
clc
adc $03
sta $03
sep #$20
lda $06
asl
tay

lda !boxpalette
asl #2
ora #$20
xba
lda #$01
rep #$20

.InstLoopX
sta [$03],y ; Create row
dey #2
bne .InstLoopX
sep #$20

dec $01
lda $01
cmp $0A
bne .InstLoopY ; Loop to create multiple rows

.End
rts


; A routine which creates a text box frame in RAM. $7E0000-$7E0004
; are used the same way as in GetTilemapPos, except for $7E0002,
; which is used as a temporary variable here. $7E0005 contains the
; tilemap bank, $7E0006 the text box width and $7E0007 the text box
; height. $7E0008-$7E000D are used as temporary variables. At the
; same time $7E000A is the tile number and $7E000B the "flip
; vertically" flag for the DrawTile subroutine.

AddFrame:
lda $03 ; Preserve tilemap address
sta $08
lda $04
sta $09
jsr SetPos

lda $07 ; Draw central tiles (vertical)
inc #2
sta $0C
lda #$07
sta $0A
stz $0B

.VerticalLoop
jsr DrawTile
rep #$20
lda $03
clc
adc #$0040
sta $03
sep #$20
dec $0C
lda $0C
bne .VerticalLoop

jsr DrawLine ; Draw top and bottom of text box
lda #$01
sta $02
lda $01
sta $0D
inc $01
jsr SetPos
lda #$06
sta $0A
jsr DrawTile

lda $0D
clc
adc $07
sta $01
jsr SetPos
lda #$80
sta $0B
jsr DrawTile
inc $01
jsr DrawLine
lda $0D
sta $01
rts


; Draw horizontal lines of the text box frame

DrawLine:
lda #$04 ; Prepare filling
sta $0A
jsr SetPos
lda $06
beq .ZeroWidth
inc
lsr
sta $0C
and #$01 ; If uneven width skip first tile
beq .HorizontalLoop
bra .SkipDraw

.HorizontalLoop
jsr DrawTile ; Fill lines horizontally

.SkipDraw
rep #$20
inc $03
inc $03
dey #4
sep #$20
dec $0C
lda $0C
bne .HorizontalLoop
lda #$05 ; Draw central part
sta $0A
jsr DrawTile

jsr SetPos
rep #$20
inc $03
inc $03
dey #4
sep #$20
lda #$03 ; Draw second and second last tile
sta $0A
jsr DrawTile

jsr SetPos

.ZeroWidth
lda #$02 ; Draw outer parts
sta $0A
jsr DrawTile
rts


; A short routine to easier get the position for drawing tiles

SetPos:
jsr GetTilemapPos
rep #$20
lda $08
clc
adc $03
sta $03
sep #$20
lda $06 ; Use Y register for right half of text box
asl
inc #2
tay
rts


; Draw one or two tiles in a line

DrawTile:
lda.b #!framepalette<<2|$20
ora $0B ; Vertical flip?
xba
lda $0A ; Tile number
rep #$20
sta [$03]
cpy #$00
beq .End
ora #$4000
sta [$03],y

.End
sep #$20
rts





CollapseWindow:
lda !counter ; Collapse text box
bne .SkipInit
lda !width
asl
sta !currentwidth
lda !height
asl
sta !currentheight
lda !xpos ; Text box init
sta !currentx
lda !ypos
sta !currenty
lda #$01
sta !counter

.SkipInit
lda !boxcreate ; Prepare jump to routine
asl
tax
lda .Routinetable,x
sta $00
inx
lda .Routinetable,x
sta $01
phk
pla
sta $02

jml [$0000]

.Routinetable
dw .NoBox,.SoEBox,.SoMBox,.MMZBox,.InstBox

.End
jmp Buffer_End



.NoBox
jsr ClearScreen
lda #$02
sta !counter
jmp .End



.SoEBox
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !width
asl
sta !currentwidth
jsr DrawBox

lda !ypos
clc
adc !currentheight
inc #2
sta $01
jsr ClearHoriz

lda !currentheight
bne .SoEEnd
lda #$02
sta !counter

.SoEEnd
lda !currentheight
dec
sta !currentheight
jmp .End



.SoMBox
lda !currentheight
beq .CollapseHorz

lda !currenty
sta $01
jsr ClearHoriz

lda !currenty
clc
adc !currentheight
inc #1
sta $01
jsr ClearHoriz

lda !currentheight
dec #2
sta !currentheight
lda !currenty
inc
sta !currenty

jsr DrawBox
jmp .End

.CollapseHorz
lda !currentwidth
cmp #$00
beq .SoMEnd

lda !currentx
sta $00
jsr ClearVert

lda !currentx
clc
adc !currentwidth
inc #1
sta $00
jsr ClearVert

lda !currentwidth
dec #2
sta !currentwidth
lda !currentx
inc
sta !currentx

jsr SoMLine
jmp .End

.SoMEnd
lda #$02
sta !counter
jmp .End



.MMZBox
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !height
asl
sta !currentheight
jsr DrawBox

lda !xpos
clc
adc !currentwidth
inc #2
sta $00
jsr ClearVert

lda !currentwidth
bne .MMZEnd
lda #$02
sta !counter

.MMZEnd
lda !currentwidth
dec
sta !currentwidth
jmp .End




.InstBox
jsr ClearScreen
lda #$02
sta !counter
jmp .End



; Clears a vertical line at X position $7E0000.

ClearVert:
lda Emptytile
sta !tile
lda !boxpalette
asl #2
ora Emptytile+1
sta !property
stz $01
lda #$01
sta $02
jsr GetTilemapPos
lda.b #!tileram+$3900>>16
sta $05
rep #$20
lda.w #!tileram+$3900
clc
adc $03
sta $03
ldy #$00

.FillLoop
lda !tile
sta [$03]
lda $03
clc
adc #$0040
sta $03
iny
cpy #$1C
bne .FillLoop
sep #$20
rts


; Clears a horizontal line at Y position $7E0001.

ClearHoriz:
lda Emptytile
sta !tile
lda !boxpalette
asl #2
ora Emptytile+1
sta !property
stz $00
lda #$01
sta $02
jsr GetTilemapPos
lda.b #!tileram+$3900>>16
sta $05
rep #$20
lda.w #!tileram+$3900
clc
adc $03
sta $03
ldy #$00
lda !tile

.FillLoop
sta [$03],y
iny #2
cpy #$40
bne .FillLoop
sep #$20
rts





VWFInit:
jsr GetMessage
jsr LoadHeader
jsr ClearBox

.End
jmp Buffer_End


InitLine:
lda #$01
sta !firsttile
lda !edge ; Reset pixel count
sta !currentpixel
lda #$00
sta !widthcarry

lda !width ; Reset available width
asl #4
sec
sbc !currentpixel
sec
sbc !currentpixel
sta !vwfmaxwidth

lda !currentchoice
beq .NoChoicePixels
lda !currentpixel
clc
adc !choicewidth
sta !currentpixel
lda !vwfmaxwidth
sec
sbc !choicewidth
sta !vwfmaxwidth
jmp .RegularLayout

.NoChoicePixels
lda !layout ; Centered layout?
bne .Centered
jmp .RegularLayout

.Centered
lda #$00
sta !vwfwidth
sta !currentwidth
lda !vwftextsource
pha
lda !vwftextsource+1
pha
lda !vwftextsource+2
pha
lda !font
pha

.WidthBegin
jsr WordWidth

lda !widthcarry
beq .NoCarry
lda #$00
sta !widthcarry
lda !currentwidth
bne .WidthEnd
lda !vwfwidth
sta !currentwidth
bra .WidthEnd

.NoCarry
lda !vwfwidth
sta !currentwidth
!16bit rep #$20
lda !vwfchar
!8bit cmp #$FE
!16bit cmp #$FFFE
!16bit sep #$20
bne .WidthEnd

lda !vwfwidth
clc
adc !space
bcs .WidthEnd
cmp !vwfmaxwidth
bcs .WidthEnd
sta !vwfwidth
bra .WidthBegin

.WidthEnd
lda !vwfmaxwidth
sec
sbc !currentwidth
lsr
clc
adc !currentpixel
sta !currentpixel

pla
sta !font
pla
sta !vwftextsource+2
pla
sta !vwftextsource+1
pla
sta !vwftextsource
!16bit rep #$20
!16bit lda #$0000
!8bit lda #$00
sta !vwfchar
!16bit sep #$20

.RegularLayout
lda #$00
sta !currentx
lda !currenty
inc #2
sta !currenty
cmp !vwfmaxheight
bcc .NoClearBox
lda !choices
beq .NoChoicesClear
lda #$01
sta !cursormove
bra .NoClearBox

.NoChoicesClear
lda #$01
sta !clearbox

lda !autowait
beq .NoClearBox
cmp #$01
beq .ButtonWait
lda !autowait
sta !wait
bra .NoClearBox

.ButtonWait
jsr EndBeep
!8bit lda #$FA
!16bit rep #$20
!16bit lda #$FFFA
sta !vwfchar
!16bit sep #$20

.NoClearBox
rep #$20
lda !tile ; Increment tile counter
inc #2
sta !tile
and #$03FF
asl #4
clc
adc.w #!tileram ; Add starting address
sta $09
sep #$20
lda.b #!tileram>>16
sta $0B

lda !currentpixel
sta $4204

.NoNewTile
lda #$00
sta $4205
lda #$08
sta $4206
nop #8
lda $4216
sta !currentpixel
rep #$20
lda $4214
asl
clc
adc !tile
sta !tile
sep #$20
lda $4214
clc
adc !currentx
sta !currentx

lda !currentchoice
beq .End
dec
sta !currentchoice
bne .End
lda #$01
sta !cursormove

.End
rts


ClearBox:
jsr ClearScreen
lda !boxcreate
beq .Init
lda !xpos
sta !currentx
lda !ypos
sta !currenty
lda !width
asl
sta !currentwidth
lda !height
asl
sta !currentheight
jsr DrawBox
bra .Init

.Init
lda #$FE
sta !currenty
lda #$09
sta !tile
lda !boxpalette
asl #2
ora Emptytile+1
sta !property
lda !height
asl
sta !vwfmaxheight
jsr InitLine
rts


GetMessage:
lda !message
sta $211B
lda !message+1
sta $211B
lda #$00
sta $211C
lda #$03
sta $211C
rep #$20
lda $2134
clc
adc.w #Pointers
sta $00
sep #$20
lda.b #Pointers>>16
sta $02
ldy #$00
lda [$00],y
sta !vwftextsource
iny
lda [$00],y
sta !vwftextsource+1
iny
lda [$00],y
sta !vwftextsource+2
rts





TextCreation:
lda !wait
beq .NoWait
jmp .End

.NoWait
lda !cursormove
bne .Cursor
jmp .NoCursor


.Cursor
lda !currentchoice
bne .NotZeroCursor
lda #$01
sta !currentchoice
lda #$00
sta $0F
jsr BackupTilemap
jmp .DisplayCursor

.NotZeroCursor
lda $16
and #$0C
bne .CursorMove
lda $18
and #$80
cmp #$80
beq .ChoicePressed
jmp .End

.ChoicePressed
jsr ButtonBeep
jmp .CursorEnd

.CursorMove
lda #$01
sta $0F
jsr BackupTilemap
lda $16
and #$0C
cmp #$08
bcs .CursorUp
lda !currentchoice
inc
sta !currentchoice
bra .CursorSFX

.CursorUp
lda !currentchoice
dec
sta !currentchoice

.CursorSFX
jsr CursorBeep
lda !currentchoice
beq .ZeroCursor
lda !choices
cmp !currentchoice
bcs .DisplayCursor
lda #$01
sta !currentchoice
bra .DisplayCursor

.ZeroCursor
lda !choices
sta !currentchoice

.DisplayCursor
lda #$01
sta !cursorupload
lda #$00
sta $0F
jsr BackupTilemap
%mvntransfer($0060, #$00, !tileram+$38A0, !vwftileram)
lda !choicespace
cmp #$08
bcs .NoChoiceCombine
lda !choicewidth
clc
adc !edge
lsr #3
asl
tax
rep #$20
lda !tileram+$3894,x
and #$03FF
asl #4
clc
adc.w #!tileram
sta $03
sep #$20
lda.b #!tileram>>16
sta $05

lda !choicewidth
clc
adc !edge
lsr #3
asl #5
tax
ldy #$00

.CombineLoop
lda !vwftileram,x
inx
ora !vwftileram,x
dex
eor #$FF
and [$03],y
ora !vwftileram,x
sta !vwftileram,x
inx
iny
cpy #$20
bne .CombineLoop

.NoChoiceCombine
jmp .End

.CursorEnd
lda #$01
sta !cursorend
jmp .End


.NoCursor
!16bit rep #$20
lda !vwfchar
!8bit cmp #$FA
!16bit cmp #$FFFA
!16bit sep #$20
bne .NoButton
jmp .End

.NoButton
lda !clearbox
beq .NoClearBox
jsr ClearBox
jmp .End

.NoClearBox
jsr ReadPointer
!16bit rep #$20
lda [$00]
sta !vwfchar
!16bit inc $00
!8bit cmp #$EC
!16bit cmp #$FFEC
bcs .Jump
!16bit sep #$20
jmp .WriteLetter

.Jump
sec
!8bit sbc #$EC
!16bit sbc #$FFEC
!16bit sep #$20
asl
tax
lda .Routinetable,x
sta $0C
inx
lda .Routinetable,x
sta $0D
phk
pla
sta $0E
!16bit jsr IncPointer
jml [$000C]

.Routinetable
dw .EC_PlayBGM
dw .ED_ClearBox
dw .EE_ChangeColor
dw .EF_Teleport
dw .F0_Choices
dw .F1_Execute
dw .F2_ChangeFont
dw .F3_ChangePalette
dw .F4_Character
dw .F5_RAMCharacter
dw .F6_HexValue
dw .F7_DecValue
dw .F8_TextSpeed
dw .F9_WaitFrames
dw .FA_WaitButton
dw .FB_TextPointer
dw .FC_LoadMessage
dw .FD_LineBreak
dw .FE_Space
dw .FF_End

.EC_PlayBGM
ldy #$01
lda [$00],y
sta $1DFB
jsr IncPointer
jsr IncPointer
jmp .NoButton

.ED_ClearBox
lda !choices
beq .EDNoChoices
jmp .FD_LineBreak

.EDNoChoices
lda #$01
sta !clearbox
jsr IncPointer
jmp TextCreation

.EE_ChangeColor
ldy #$01
lda [$00],y
sta $2121
iny
lda [$00],y
sta $2122
iny
lda [$00],y
sta $2122
jsr IncPointer
jsr IncPointer
jsr IncPointer
jsr IncPointer
jmp .NoButton

.EF_Teleport
ldy #$01
lda [$00],y
sta !telepdest
iny
lda [$00],y
sta !telepdest+1
iny
lda [$00],y
sta !telepprop
lda #$01
sta !teleport
jsr IncPointer
jsr IncPointer
jsr IncPointer
jsr IncPointer
jmp .NoButton

.F0_Choices
jsr ReadPointer

lda !firsttile
eor #$01
sta !nochoicelb

ldy #$01
lda [$00],y
lsr #4
pha
cmp !height
bcc .ChoiceStore
beq .ChoiceStore
lda !height

.ChoiceStore
sta !choices
inc
sta !currentchoice
lda !vwfmaxheight
sec
sbc !currenty
beq .F0ClearForce
sec
sbc !nochoicelb
sec
sbc !nochoicelb
lsr
cmp !choices
bcs .CreateCursor

.F0ClearForce
pla
lda #$01
sta !clearbox
jmp .F0ClearOptions

.CreateCursor
lda [$00],y
and #$0F
sta !choicespace
iny
lda [$00],y
sta !cursor
!16bit iny
!16bit lda [$00],y
!16bit sta !cursor+1
!16bit jsr IncPointer
jsr IncPointer
jsr IncPointer
jsr IncPointer

lda !vwftextsource
sta !choicetable
lda !vwftextsource+1
sta !choicetable+1
lda !vwftextsource+2
sta !choicetable+2
lda !edge
and #$07
sta !currentpixel
lda !firsttile
sta !nochoicelb
lda #$01
sta !firsttile

!16bit lda !cursor+1
!16bit sta !font

jsr GetFont

rep #$20
lda #$0001
sta $0C
lda.w #!cursor
sta $00
lda.w #!tileram+$38A0
sta $09
sep #$20
lda.b #!cursor>>16
sta $02
lda.b #!tileram+$38A0>>16
sta $0B

lda !currentx
pha
lda !tile
pha
lda #$00
sta !currentx

lda !currentpixel
sta $0E
lda !firsttile
sta $0F

jsl GenerateVWF|$800000

lda !vwfwidth
clc
adc !choicespace
sta !choicewidth

lda !boxcreate
beq .F0NoBG

rep #$20
lda #$0006
sta $06
lda.w #!tileram+$10
sta $00
lda.w #!tileram+$38A0
sta $03
sep #$20
lda.b #!tileram+$10>>16
sta $02
lda.b #!tileram+$38A0>>16
sta $05

jsl AddPattern|$800000

.F0NoBG
rep #$20
lda.w #!tileram+$38A0
sta $09
sep #$20
lda.b #!tileram+$38A0>>16
sta $0B

lda !currentx
asl #5
clc
adc $09
sta $09

lda !currentpixel
clc
adc !choicespace
sta !choicespace
cmp #$08
bcs .NoChoiceWipe

jsr WipePixels

.NoChoiceWipe
pla
sta !tile
pla
sta !currentx

lda #$00
sta $0D
xba
pla
sta $0C
asl
clc
adc $0C
rep #$20
clc
adc !vwftextsource
sta !vwftextsource
sep #$20

jsr InitLine
lda !nochoicelb
beq .F0NotStart
lda !currenty
dec #2
sta !currenty

.F0NotStart
lda !clearbox
beq .F0Return
lda !currentchoice
inc
sta !currentchoice

.F0ClearOptions
lda !autowait
beq .F0NoAutowait
cmp #$01
beq .F0ButtonWait
lda !autowait
sta !wait
bra .F0NoAutowait

.F0ButtonWait
jsr EndBeep
!16bit rep #$20
!16bit lda #$FFFA
!8bit lda #$FA
sta !vwfchar
!16bit sep #$20

.F0NoAutowait
jmp TextCreation

.F0Return
jmp .NoButton

.F1_Execute
lda #$22
sta !vwfroutine
ldy #$01
lda [$00],y
sta !vwfroutine+1
iny
lda [$00],y
sta !vwfroutine+2
iny
lda [$00],y
sta !vwfroutine+3
lda #$6B
sta !vwfroutine+4
jsr IncPointer
jsr IncPointer
jsr IncPointer
jsr IncPointer
jsl !vwfroutine
jmp .NoButton

.F2_ChangeFont
ldy #$01
lda [$00],y
sta !font
jsr IncPointer
jsr IncPointer
jmp .NoButton

.F3_ChangePalette
lda !property
and #$E3
sta !property
ldy #$01
lda [$00],y
asl #2
inc
sta $2121
dec
ora !property
sta !property
lda !boxcolor
sta $2122
lda !boxcolor+1
sta $2122
jsr IncPointer
jsr IncPointer
jmp .NoButton

.F4_Character
jsr IncPointer
jsr ReadPointer
!16bit rep #$20
lda [$00]
sta !vwfchar
!16bit sep #$20
jmp .WriteLetter

.F5_RAMCharacter
ldy #$01
lda [$00],y
sta $0C
iny
lda [$00],y
sta $0D
iny
lda [$00],y
sta $0E
!16bit rep #$20
lda [$0C]
sta !vwfroutine
!16bit sep #$20
lda #$FB
sta !vwfroutine+1+!bitmode
!16bit lda #$FF
!16bit sta !vwfroutine+3
rep #$20
lda $00
inc #4
sta !vwfroutine+2+!bitmode+!bitmode
sep #$20
lda $02
sta !vwfroutine+4+!bitmode+!bitmode
lda.b #!vwfroutine
sta !vwftextsource
lda.b #!vwfroutine>>8
sta !vwftextsource+1
lda.b #!vwfroutine>>16
sta !vwftextsource+2
jmp .NoButton

.F6_HexValue
ldy #$01
lda [$00],y
sta $0C
iny
lda [$00],y
sta $0D
iny
lda [$00],y
sta $0E
lda [$0C]
lsr #4
sta !vwfroutine
!16bit lda #$00
!16bit sta !vwfroutine+1
lda [$0C]
and #$0F
sta !vwfroutine+1+!bitmode
!16bit lda #$00
!16bit sta !vwfroutine+3
lda #$FB
sta !vwfroutine+2+!bitmode+!bitmode
!16bit lda #$FF
!16bit sta !vwfroutine+5
rep #$20
lda $00
inc #4
sta !vwfroutine+3+!bitmode+!bitmode+!bitmode
sep #$20
lda $02
sta !vwfroutine+5+!bitmode+!bitmode+!bitmode
lda.b #!vwfroutine
sta !vwftextsource
lda.b #!vwfroutine>>8
sta !vwftextsource+1
lda.b #!vwfroutine>>16
sta !vwftextsource+2
jmp .NoButton

.F7_DecValue
lda #$FB
!8bit sta !vwfroutine+5
!16bit sta !vwfroutine+10
!16bit lda #$FF
!16bit sta !vwfroutine+11
rep #$20
lda $00
clc
adc #$0005
!8bit sta !vwfroutine+6
!16bit sta !vwfroutine+12
sep #$20
lda $02
!8bit sta !vwfroutine+8
!16bit sta !vwfroutine+14

ldy #$01
lda [$00],y
sta $07
iny
lda [$00],y
sta $08
iny
lda [$00],y
sta $09
iny
lda [$00],y
pha
and #$F0
sta $04
jsr HextoDec

stz $00
stz $01
lda $04
bne .16Bit
inc $00
inc $00
!16bit inc $00
!16bit inc $00

.16Bit
pla
and #$0F
beq .NoZeros
lda $05
!16bit asl
clc
adc $00
sta $00

.NoZeros
rep #$20
lda.w #!vwfroutine
clc
adc $00
sta !vwftextsource
sep #$20
lda.b #!vwfroutine>>16
sta !vwftextsource+2

jmp .NoButton

.F8_TextSpeed
ldy #$01
lda [$00],y
sta !frames
jsr IncPointer
jsr IncPointer
jmp .End

.F9_WaitFrames
ldy #$01
lda [$00],y
sta !wait
lda #$01
sta !forcesfx
jsr IncPointer
jsr IncPointer
jmp .End

.FA_WaitButton
jsr EndBeep
jsr IncPointer
jmp .End

.FB_TextPointer
ldy #$01
lda [$00],y
sta !vwftextsource
iny
lda [$00],y
sta !vwftextsource+1
iny
lda [$00],y
sta !vwftextsource+2
jmp .NoButton

.FC_LoadMessage
ldy #$01
lda [$00],y
sta !message
iny
lda [$00],y
sta !message+1
lda !vwfmode
dec
sta !vwfmode
lda #$01
sta !clearbox
jmp VWFInit

.FD_LineBreak
!16bit rep #$20
!16bit lda #$FFFD
!8bit lda #$FD
sta !vwfchar
!16bit sep #$20
jsr IncPointer
jsr InitLine
lda !clearbox
ora !cursormove
beq .FDReturn
jmp TextCreation

.FDReturn
jmp .NoButton

.FE_Space
jsr IncPointer
lda !vwfmaxwidth
cmp !space
bcs .PutSpace
jsr InitLine
lda !clearbox
ora !cursormove
bne .SpaceClearBox
jmp .FEReturn

.SpaceClearBox
jmp TextCreation

.PutSpace
lda !vwfmaxwidth
sec
sbc !space
sta !vwfmaxwidth

lda !currentpixel
clc
adc !space
sta $4204
cmp #$08
bcc .NoNewTile
lda #$01
sta !firsttile

.NoNewTile
lda #$00
sta $4205
lda #$08
sta $4206
nop #8
lda $4216
sta !currentpixel
rep #$20
lda $4214
asl
clc
adc !tile
sta !tile
sep #$20
lda $4214
clc
adc !currentx
sta !currentx

lda #$00 ; Preserve everything and get width
sta !vwfwidth ; of next word (for word wrap)
lda !vwftextsource
pha
lda !vwftextsource+1
pha
lda !vwftextsource+2
pha
lda !font
pha
lda !vwfchar
pha
!16bit lda !vwfchar+1
!16bit pha

jsr WordWidth

!16bit pla
!16bit sta !vwfchar+1
pla
sta !vwfchar
pla
sta !font
pla
sta !vwftextsource+2
pla
sta !vwftextsource+1
pla
sta !vwftextsource

lda !widthcarry
bne .FECarrySet
lda !vwfmaxwidth
cmp !vwfwidth
bcs .FEReturn

.FECarrySet
lda #$00
sta !widthcarry
jsr InitLine
lda !clearbox
ora !cursormove
beq .FEReturn
jmp TextCreation

.FEReturn
jmp .NoButton

.FF_End
lda !choices
beq .FFNoChoices
jmp .FD_LineBreak

.FFNoChoices
jsr IncPointer
jmp .End

.WriteLetter
!16bit lda !vwfchar+1
!16bit sta !font
jsr GetFont

rep #$20
lda #$0001
sta $0C
lda !vwftextsource
sta $00
sep #$20
lda !vwftextsource+2
sta $02

lda [$00] ; Check if enough width available
tay
lda !vwfmaxwidth
cmp [$06],y
bcs .Create
jsr InitLine
jsr GetFont
rep #$20
lda #$0001
sta $0C
lda !vwftextsource
sta $00
sep #$20
lda !vwftextsource+2
sta $02

lda !clearbox
ora !cursormove
beq .Create
jmp TextCreation

.Create
jsr IncPointer
!16bit jsr IncPointer
lda [$06],y
sta !vwfwidth
jsr WriteTilemap

jsr GetDestination

lda $09
sta !vwfgfxdest
lda $0A
sta !vwfgfxdest+1
lda $0B
sta !vwfgfxdest+2

lda !firsttile
bne .NoWipe
lda !boxcreate
beq .NoWipe

jsr WipePixels

.NoWipe
lda !currentpixel
sta $0E
lda !firsttile
sta $0F

jsl GenerateVWF|$800000

lda !boxcreate
beq .End
lda.b #!tileram+$10
sta $00
lda.b #!tileram+$10>>8
sta $01
lda.b #!tileram+$10>>16
sta $02

lda !vwfgfxdest
sta $03
lda !vwfgfxdest+1
sta $04
lda !vwfgfxdest+2
sta $05

lda #$06
sta $06

jsl AddPattern|$800000

.End
jmp Buffer_End



GetFont:
lda #$06 ; Multiply font number with 6
sta $211B
lda #$00
sta $211B
sta $211C
lda !font
sta $211C
rep #$20
lda $2134
clc
adc.w #Fonttable ; Add starting address
sta $00
sep #$20
lda.b #Fonttable>>16
sta $02
ldy #$00

.Loop
lda [$00],y ; Load addresses from table
sta $0003,y
iny
cpy #$06
bne .Loop
rts


GetDestination:
rep #$20
lda !tile
and #$03FF ; Multiply tile number with 16
asl #4
clc
adc.w #!tileram ; Add starting address
sta $09
sep #$20
lda.b #!tileram>>16
sta $0B
rts


IncPointer:
rep #$20
lda !vwftextsource
inc
sta !vwftextsource
sep #$20
rts


ReadPointer:
rep #$20
lda !vwftextsource
sta $00
sep #$20
lda !vwftextsource+2
sta $02
rts


Beep:
lda !soundoff
beq .Begin
rts

.Begin
lda !forcesfx
bne .Play
lda !frames
bne .Play
lda $13
and #$01
beq .Play
bra .Return

.Play
lda #$00
sta !forcesfx
rep #$20
lda !beepbank
sta $00
sep #$20
lda #$7E
sta $02
lda !beep
sta [$00]

.Return
rts

EndBeep:
lda !soundoff
beq .Begin
rts

.Begin
rep #$20
lda !beependbank
sta $00
sep #$20
lda #$7E
sta $02
lda !beepend
sta [$00]
rts

CursorBeep:
lda !soundoff
beq .Begin
rts

.Begin
rep #$20
lda !beepcursorbank
sta $00
sep #$20
lda #$7E
sta $02
lda !beepcursor
sta [$00]
rts

ButtonBeep:
lda !soundoff
beq .Begin
rts

.Begin
rep #$20
lda !beepchoicebank
sta $00
sep #$20
lda #$7E
sta $02
lda !beepchoice
sta [$00]
rts


WriteTilemap:
rep #$20
lda $00
pha
lda $02
pha
lda $04
pha
sep #$20
lda !currentx ; Get tilemap address
inc
clc
adc !xpos
sta $00
lda !currenty
inc
clc
adc !ypos
sta $01
lda #$01
sta $02
jsr GetTilemapPos
lda.b #!tileram+$3900>>16
sta $05
sta !vwftilemapdest+2
rep #$20
lda.w #!tileram+$3900
clc
adc $03
sta $03
sta !vwftilemapdest

lda !vwfwidth
clc
adc !currentpixel
tax
lda !tile
ldy #$02

sta [$03] ; Write to tilemap
cpx #$09
bcc .SecondLine
inc #2
sta [$03],y
cpx #$11
bcc .SecondLine
inc #2
iny #2
sta [$03],y

.SecondLine
lda !tile
inc
ldy #$40
sta [$03],y
cpx #$09
bcc .Return
inc #2
iny #2
sta [$03],y
cpx #$11
bcc .Return
inc #2
iny #2
sta [$03],y

.Return
pla
sta $04
pla
sta $02
pla
sta $00
sep #$20
rts


WipePixels:
lda !currentpixel ; Wipe pixels to prevent overlapping
tax ; graphics
ldy #$00

.Loop
lda [$09],y
and .Pixeltable,x
sta [$09],y

iny
cpy #$20
bne .Loop
rts

.Pixeltable
db $00,$80,$C0,$E0,$F0,$F8,$FC,$FE

;$07 : Address
;$04 : Bitmode
;$05 : Zeros

HextoDec:
jsr Convert8Bit
jsr GetZeros
!16bit lda #$00
!16bit sta !vwfroutine+1
!16bit sta !vwfroutine+3
!16bit sta !vwfroutine+5
!16bit sta !vwfroutine+7
!16bit sta !vwfroutine+9
rts

Convert8Bit:
stz $00
stz $01
stz $02
stz $03
lda [$07]
ldy $04
cpy #$00
beq .Hundreds
jsr Convert16Bit

.Hundreds
cmp #$64
bcc .Tens
inc $02
sec
sbc #$64
bra .Hundreds

.Tens
cmp #$0A
bcc .Ones
inc $03
sec
sbc #$0A
bra .Tens

.Ones
sta !vwfroutine+4+!bitmode+!bitmode+!bitmode+!bitmode
lda $03
sta !vwfroutine+3+!bitmode+!bitmode+!bitmode
lda $02
sta !vwfroutine+2+!bitmode+!bitmode

rts

Convert16Bit:
rep #$20
lda [$07]

.Tenthousands
cmp #$2710
bcc .Thousands
inc $00
sec
sbc #$2710
bra .Tenthousands

.Thousands
cmp #$03E8
bcc .Hundreds
inc $01
sec
sbc #$03E8
bra .Thousands

.Hundreds
cmp #$0064
bcc .End
inc $02
sec
sbc #$0064
bra .Hundreds

.End
pha
lda $00
sta !vwfroutine
pla
sep #$20
rts

GetZeros:
stz $05
dec $05
stz $06
ldy $04
beq .Hundreds

.Tenthousands
inc $05
lda !vwfroutine
beq .Thousands
bra .End

.Thousands
inc $05
lda !vwfroutine+1+!bitmode
beq .Hundreds
bra .End

.Hundreds
inc $05
lda !vwfroutine+2+!bitmode+!bitmode
beq .Tens
bra .End

.Tens
inc $05
lda !vwfroutine+3+!bitmode+!bitmode+!bitmode
beq .Ones
bra .End

.Ones
inc $05

.End
rts



WordWidth:
!8bit jsr GetFont

.Begin
jsr ReadPointer
!16bit rep #$20
lda [$00]
sta !vwfchar
!8bit cmp #$EC
!16bit cmp #$FFEC
bcs .Jump
!16bit sep #$20
!16bit jsr IncPointer
jsr IncPointer
jmp .Add

.Jump
sec
!8bit sbc #$EC
!16bit sbc #$FFEC
!16bit sep #$20
asl
tax
lda .Routinetable,x
sta $0C
inx
lda .Routinetable,x
sta $0D
phk
pla
sta $0E
!16bit jsr IncPointer
jsr IncPointer
jsr ReadPointer
jml [$000C]

.Routinetable
dw .EC_PlayBGM
dw .ED_ClearBox
dw .EE_ChangeColor
dw .EF_Teleport
dw .F0_Choices
dw .F1_Execute
dw .F2_ChangeFont
dw .F3_ChangePalette
dw .F4_Character
dw .F5_RAMCharacter
dw .F6_HexValue
dw .F7_DecValue
dw .F8_TextSpeed
dw .F9_WaitFrames
dw .FA_WaitButton
dw .FB_TextPointer
dw .FC_LoadMessage
dw .FD_LineBreak
dw .FE_Space
dw .FF_End

.EE_ChangeColor
.EF_Teleport
.F1_Execute
jsr IncPointer
jsr IncPointer
jsr IncPointer
jmp .Begin

.F2_ChangeFont
lda [$00]
sta !font
jsr IncPointer
jmp WordWidth

.F3_ChangePalette
jsr IncPointer
jmp .Begin

.F4_Character
!16bit rep #$20
lda [$00]
sta !vwfchar
!16bit sep #$20
!16bit jsr IncPointer
jsr IncPointer
jmp .Add

.F5_RAMCharacter
ldy #$01
lda [$00]
sta $0C
lda [$00],y
sta $0D
iny
lda [$00],y
sta $0E
jsr IncPointer
jsr IncPointer
jsr IncPointer
!16bit rep #$20
lda [$0C]
sta !vwfchar
!16bit sep #$20
jmp .Add

.F6_HexValue
ldy #$01
lda [$00]
sta $0C
lda [$00],y
sta $0D
iny
lda [$00],y
sta $0E
lda [$0C]
lsr #4
sta !vwfroutine
!16bit lda #$00
!16bit sta !vwfroutine+1
lda [$0C]
and #$0F
sta !vwfroutine+1+!bitmode
!16bit lda #$00
!16bit sta !vwfroutine+3
lda #$FB
sta !vwfroutine+2+!bitmode+!bitmode
!16bit lda #$FF
!16bit sta !vwfroutine+5
rep #$20
lda $00
inc #3
sta !vwfroutine+3+!bitmode+!bitmode+!bitmode
sep #$20
lda $02
sta !vwfroutine+5+!bitmode+!bitmode+!bitmode
lda.b #!vwfroutine
sta !vwftextsource
lda.b #!vwfroutine>>8
sta !vwftextsource+1
lda.b #!vwfroutine>>16
sta !vwftextsource+2
jmp .Begin

.F7_DecValue
lda #$FB
!8bit sta !vwfroutine+5
!16bit sta !vwfroutine+10
!16bit lda #$FF
!16bit sta !vwfroutine+11
rep #$20
lda $00
clc
adc #$0004
!8bit sta !vwfroutine+6
!16bit sta !vwfroutine+12
sep #$20
lda $02
!8bit sta !vwfroutine+8
!16bit sta !vwfroutine+14

ldy #$01
lda [$00]
sta $07
lda [$00],y
sta $08
iny
lda [$00],y
sta $09
iny
lda [$00],y
pha
and #$F0
sta $04
jsr HextoDec

stz $00
stz $01
lda $04
bne .16Bit
inc $00
inc $00
!16bit inc $00
!16bit inc $00

.16Bit
pla
and #$0F
beq .NoZeros
lda $05
!16bit asl
clc
adc $00
sta $00

.NoZeros
rep #$20
lda.w #!vwfroutine
clc
adc $00
sta !vwftextsource
sep #$20
lda.b #!vwfroutine>>16
sta !vwftextsource+2

jmp WordWidth

.EC_PlayBGM
.F8_TextSpeed
.F9_WaitFrames
jsr IncPointer
jmp .Begin

.FA_WaitButton
jmp .Begin

.FB_TextPointer
ldy #$01
lda [$00]
sta !vwftextsource
lda [$00],y
sta !vwftextsource+1
iny
lda [$00],y
sta !vwftextsource+2
jmp .Begin

.ED_ClearBox
.F0_Choices
.FC_LoadMessage
.FD_LineBreak
.FE_Space
.FF_End
jmp .Return

.Add
!16bit lda !vwfchar+1
!16bit sta !font
!16bit jsr GetFont
lda !vwfchar
tay
lda [$06],y
clc
adc !vwfwidth
bcs .End
cmp !vwfmaxwidth
bcc .Continue
beq .Continue
bra .End

.Continue
sta !vwfwidth
jmp .Begin

.End
lda #$01
sta !widthcarry

.Return
rts





;;;;;;;;;;;;;;
;V-Blank Code;
;;;;;;;;;;;;;;

; This loads up graphics and tilemaps to VRAM.

VBlank:
phx
phy
pha
phb
php
phk
plb

lda $13D4
beq .NoPause
bra .End

.NoPause
lda !vwfmode ; Prepare jump to routine
beq .End
asl
tax
lda .Routinetable,x
sta $00
inx
lda .Routinetable,x
sta $01
phk
pla
sta $02

lda #$F0 ; Hide Status Bar item
sta $02E1

jml [$0000]

.End
plp ; Return
plb
pla
ply
plx

lda !vwfmode ; Skip Status Bar in dialogues
bne .SkipStatusBar
lda $0D9B
lsr
bcs .SkipStatusBar
phk ; Display Status Bar
per $0006
pea $84CE
jml $008DAC|$800000

.SkipStatusBar
jml $0081F7|$800000

.Routinetable
dw .End,PrepareBackup,Backup,PrepareScreen,SetupColor
dw BackupEnd,CreateWindow,PrepareScreen,TextUpload,CreateWindow
dw PrepareBackup,Backup,SetupColor,BackupEnd,VBlankEnd






VBlankEnd:
lda $0109 ; Check if in the intro
beq .NotIntroLevel
jsl $05B15B|$800000
jmp .NotSwitchPallace

.NotIntroLevel
lda $13D2 ; Check if in a Switch Pallace
beq .NotSwitchPallace
ldx $191E
lda .SwitchTable,x
sta $13D2
inc $1DE9
lda #$01
sta $13CE
jsl $05B165|$800000

.NotSwitchPallace
lda !freezesprites
beq .NoFreezeSprites
lda #$00
sta $13FB
sta $9D
sta $13D3
sta !freezesprites

.NoFreezeSprites
lda !teleport ; Check if teleport set
beq .NoTeleport

lda #$00
sta !teleport

lda $5B
beq .Horizontal

ldx $97
bra .SetupTeleport

.Horizontal
ldx $95

.SetupTeleport
lda !telepdest
sta $19B8,x
lda !telepdest+1
ora #$04
ora !telepprop
sta $19D8,x

.Teleport
lda #$06
sta $71
stz $89
stz $88

.NoTeleport
lda #$00 ; VWF dialogue end
sta !vwfmode

jmp VBlank_End

.SwitchTable
db $04,$01,$02,$03




PrepareBackup:
lda #$08 ; Prepare backup of layer 3
sta !counter
rep #$20
lda #$0000
sta !vrampointer
sep #$20

lda #$04 ; Hide layer 3
trb $0D9D
lda $0D9D
sta $212C

.End
lda !vwfmode
inc
sta !vwfmode
jmp VBlank_End





Backup:
rep #$20

lda.w #!backupram ; Adjust destination address
clc
adc !vrampointer
clc
adc !vrampointer
sta $00

lda #$4000 ; Adjust VRAM address
clc
adc !vrampointer
sta $02

sep #$20

lda !vwfmode
cmp #$02
beq .Backup
jmp .Restore

.Backup
%vramprepare(#$80,$02,"lda $2139","")
%dmatransfer(#$10,#$81,#$39,".b #!backupram>>16",".b $01",".b $00",#$0800)
jmp .Continue

.Restore
%vramprepare(#$80,$02,"","")
%dmatransfer(#$10,#$01,#$18,".b #!backupram>>16",".b $01",".b $00",#$0800)

.Continue
rep #$20 ; Adjust pointer
lda !vrampointer
clc
adc #$0400
sta !vrampointer
sep #$20

lda !counter ; Reduce iteration counter
dec
sta !counter
bne .NotDone

.End
lda !vwfmode
inc
sta !vwfmode

.NotDone
jmp VBlank_End





BackupEnd:
lda #$04 ; Display layer 3
tsb $0D9D
lda $0D9D
sta $212C

.End
lda !vwfmode
inc
sta !vwfmode
jmp VBlank_End





SetupColor:
lda #$00 ; Backup or restore layer 3 colors
sta $2121
lda !vwfmode
cmp #$04
beq .Backup
%dmatransfer(#$10,#$02,#$22,".b #$7E",".b #$07",".b #$03",#$0040)
jmp .End

.Backup
%dmatransfer(#$10,#$82,#$3B,".b #$7E",".b #$07",".b #$03",#$0040)


lda !boxpalette ; Set BG and letter color
asl #2
inc
sta $2121
ldx #$00

.BoxColorLoop
lda !boxcolor,x
sta $2122
inx
cpx #$06
bne .BoxColorLoop


lda !framepalette ; Set frame color
asl #2
inc
sta $2121
phk
pla
sta $02
lda #$06
sta $211B
lda #$00
sta $211B
sta $211C
lda !boxframe
sta $211C
nop
rep #$20
lda $2134
clc
adc.w #Palettes
sta $00
sep #$20
ldy #$00

.FrameColorLoop
lda [$00],y
sta $2122
iny
cpy #$06
bne .FrameColorLoop

.End
lda !vwfmode
inc
sta !vwfmode
jmp VBlank_End





PrepareScreen: ; Upload graphics and tilemap to VRAM
%vramprepare(#$80,#$4000,"","")
%dmatransfer(#$10,#$01,#$18,".b #!tileram>>16",".b #!tileram>>8",".b #!tileram",#$00B0)

%vramprepare(#$80,#$5C80,"","")
%dmatransfer(#$10,#$01,#$18,".b #!tileram+$3900>>16",".b #!tileram+$3900>>8",".b #!tileram+$3900",#$0700)

.End
lda !vwfmode
inc
sta !vwfmode
jmp VBlank_End





CreateWindow:
%vramprepare(#$80,#$5C80,"","")
%dmatransfer(#$10,#$01,#$18,".b #!tileram+$3900>>16",".b #!tileram+$3900>>8",".b #!tileram+$3900",#$0700)

lda !counter
cmp #$02
bne .Return

.End
lda #$00
sta !counter
lda !vwfmode
inc
sta !vwfmode

.Return
jmp VBlank_End





TextUpload:
lda !wait ; Wait for frames?
beq .NoFrames
lda !wait
dec
sta !wait
jmp .Return

.NoFrames
lda !cursormove
bne .Cursor
jmp .NoCursor


.Cursor
lda !cursorupload
bne .UploadCursor
jmp .NoCursorUpload

.UploadCursor
lda #$00
sta !cursorupload

%vramprepare(#$80,#$5C50,"","")
%dmatransfer(#$10,#$01,#$18,".b #!vwftileram>>16",".b #!vwftileram>>8",".b #!vwftileram",#$0060)

lda !edge
lsr #3
sta !currentx
lda !currenty
pha
sec
sbc !choices
sec
sbc !choices
sta !currenty
lda !currentchoice
dec
asl
clc
adc !currenty
sta !currenty
lda #$00
sta !vwfwidth
lda !edge
and #$07
clc
adc !choicewidth
sta !currentpixel
rep #$20
lda !tile
and #$FC00
ora #$038A
sta !tile
sep #$20
jsr WriteTilemap
pla
sta !currenty

rep #$20
lda !vwftilemapdest
sec
sbc.w #!tileram+$3900
lsr
clc
adc #$5C80
sta $00
sep #$20
%vramprepare(#$80,$00,"","")
%dmatransfer(#$10,#$01,#$18," !vwftilemapdest+2"," !vwftilemapdest+1"," !vwftilemapdest",#$0046)

jmp .Return

.NoCursorUpload
lda !cursorend
bne .CursorEnd
jmp .Return

.CursorEnd
lda #$00
sta !cursorend
lda !currentchoice
dec
sta !currentchoice
asl
clc
adc !currentchoice
tay
lda !choicetable
sta $00
lda !choicetable+1
sta $01
lda !choicetable+2
sta $02
lda [$00],y
sta !vwftextsource
iny
lda [$00],y
sta !vwftextsource+1
iny
lda [$00],y
sta !vwftextsource+2
lda #$00
sta !cursormove
sta !choices
sta !currentchoice
sta !vwfchar
!16bit sta !vwfchar+1
lda #$01
sta !clearbox
jmp .Return


.NoCursor
!16bit rep #$20
lda !vwfchar ; Dialogue done?
!8bit cmp #$FF
!16bit cmp #$FFFF
bne .NoEnd
!16bit lda #$0000
!8bit lda #$00
sta !vwfchar
!16bit sep #$20
jmp .End

.NoEnd
!8bit cmp #$FA ; Waiting for A button?
!16bit cmp #$FFFA
!16bit sep #$20
beq .CheckButton
jmp .Upload

.CheckButton
lda $18
and #$80
cmp #$80
bne .NotPressed
jsr ButtonBeep
lda #$00
sta !vwfchar
!16bit sta !vwfchar+1
lda #$00
sta !timer

.NotPressed
lda !boxcreate
bne .CheckTimer
jmp .Return

.CheckTimer
lda !timer ; Display arrow if waiting for button
inc
sta !timer
cmp #$21
bcc .NoReset
lda #$00
sta !timer

.NoReset
lda !xpos
clc
adc !width
inc
sta $00
lda !height
asl
clc
adc !ypos
inc
sta $01
lda #$00
sta $02
jsr GetTilemapPos
rep #$20
lda #$5C80
clc
adc $03
sta $03
sep #$20

%vramprepare(#$00,$03,"","")

lda !timer
cmp #$11
bcs .Arrow
lda #$05
bra .Display

.Arrow
lda #$0A

.Display
sta $2118
jmp .Return

.Upload
lda !clearbox
beq .Begin
lda #$00
sta !clearbox
%vramprepare(#$80,#$5C80,"","")
%dmatransfer(#$10,#$01,#$18,".b #!tileram+$3900>>16",".b #!tileram+$3900>>8",".b #!tileram+$3900",#$0700)
jmp .Return

.Begin
rep #$20 ; Upload GFX
lda !vwfgfxdest
sec
sbc.w #!tileram
lsr
clc
adc #$4000
sta $00
sep #$20
%vramprepare(#$80,$00,"","")
%dmatransfer(#$10,#$01,#$18," !vwfgfxdest+2"," !vwfgfxdest+1"," !vwfgfxdest",#$0060)

rep #$20 ; Upload Tilemap
lda !vwftilemapdest
sec
sbc.w #!tileram+$3900
lsr
clc
adc #$5C80
sta $00
sep #$20
%vramprepare(#$80,$00,"","")
%dmatransfer(#$10,#$01,#$18," !vwftilemapdest+2"," !vwftilemapdest+1"," !vwftilemapdest",#$0046)

jsr Beep

lda !frames
sta !wait

lda !speedup
beq .Return
!16bit rep #$20
lda !vwfchar
!8bit cmp #$F9
!16bit cmp #$FFF9
!16bit sep #$20
beq .Return
lda $15
and #$80
cmp #$80
bne .Return
lda #$00
sta !wait
jmp .Return

.End
lda !vwfmode
inc
sta !vwfmode

.Return
jmp VBlank_End



BackupTilemap:
lda !edge
lsr #3
clc
adc !xpos
inc
sta $00

lda !currenty
sec
sbc !choices
sec
sbc !choices
sta $01
lda !currentchoice
dec
asl
clc
adc $01
clc
adc !ypos
inc
sta $01

lda #$01
sta $02

jsr GetTilemapPos

lda.b #!tileram+$3900>>16
sta $05
rep #$20
lda.w #!tileram+$3900
clc
adc $03
sta $03
sep #$20

lda $0F
beq .Backup
jmp .Restore

.Backup
rep #$20
ldy #$02
lda [$03]
sta !tileram+$3894
lda [$03],y
sta !tileram+$3896
iny #2
lda [$03],y
sta !tileram+$3898
ldy #$40
lda [$03],y
sta !tileram+$389A
iny #2
lda [$03],y
sta !tileram+$389C
iny #2
lda [$03],y
sta !tileram+$389E
sep #$20

rts

.Restore
rep #$20
ldy #$02
lda !tileram+$3894
sta [$03]
lda !tileram+$3896
sta [$03],y
iny #2
lda !tileram+$3898
sta [$03],y
ldy #$40
lda !tileram+$389A
sta [$03],y
iny #2
lda !tileram+$389C
sta [$03],y
iny #2
lda !tileram+$389E
sta [$03],y
sep #$20

rep #$20
lda $03
sec
sbc.w #!tileram+$3900
lsr
clc
adc #$5C80
sta $00
sep #$20
%vramprepare(#$80,$00,"","")
%dmatransfer(#$10,#$01,#$18," $05"," $04"," $03",#$0046)
rts





;;;;;;;;;;;;;;
;VWF Routines;
;;;;;;;;;;;;;;

; The actual VWF Creation routine.

print ""
print "VWF Creation Routine at address $",pc,"."

;$00 : Text
;$03 : GFX 1
;$06 : Width
;$09 : Destination
;$0C : Number of Bytes -> GFX 2
;$0E : Current Pixel
;$0F : First Tile?

GenerateVWF:
lda $0E
sta !currentpixel
lda $0F
sta !firsttile
rep #$20
lda $0C
sta !vwfbytes
sep #$20
lda $05 ; Get GFX 2 Offset
sta $0E
rep #$20
lda $03
clc
adc #$0020
sta $0C

.Read
lda [$00] ; Read character
inc $00
!16bit inc $00
!8bit sep #$20
sta !vwfchar
!16bit sep #$20
!16bit lda !vwfchar+1
!16bit sta !font
!16bit jsr GetFont
!16bit lda $05
!16bit sta $0E
!16bit rep #$20
!16bit lda $03
!16bit clc
!16bit adc #$0020
!16bit sta $0C
!16bit sep #$20
!16bit lda !vwfchar
tay
lda [$06],y ; Get width
sta !vwfwidth
lda !vwfmaxwidth
sec
sbc !vwfwidth
sta !vwfmaxwidth

.Begin
lda !vwfchar ; Get letter offset into Y
sta $211B
lda #$00
sta $211B
sta $211C
lda #$40
sta $211C
rep #$10
ldy $2134
ldx #$0000

.Draw
lda !currentpixel
sta $0F
lda [$03],y ; Load one pixelrow of letter
sta !vwftileram,x
lda [$0C],y
sta !vwftileram+32,x
lda #$00
sta !vwftileram+64,x

.Check
lda $0F
beq .Skip
lda !vwftileram,x ; Shift to the right
lsr
sta !vwftileram,x
lda !vwftileram+32,x
ror
sta !vwftileram+32,x
lda !vwftileram+64,x
ror
sta !vwftileram+64,x
dec $0F
bra .Check

.Skip
iny
inx
cpx #$0020
bne .Draw
sep #$10
ldx #$00
ldy #$00

lda !firsttile ; Skip one step if first tile in line
beq .Combine
lda #$00
sta !firsttile
bra .Copy

.Combine
lda !vwftileram,x ; Combine old graphic with new
ora [$09],y
sta [$09],y
inx
iny
cpx #$20
bne .Combine

.Copy
lda !vwftileram,x ; Copy remaining part of letter
sta [$09],y
inx
iny
cpx #$60
bne .Copy

lda !currentpixel ; Adjust destination address
clc
adc !vwfwidth
sta $4204
lda #$00
sta $4205
lda #$08
sta $4206
nop #8
lda $4216
sta !currentpixel
rep #$20
lda $4214
asl
clc
adc !tile
sta !tile
sep #$20
lda $4214
clc
adc !currentx
sta !currentx
lda $4214
sta $211B
lda #$00
sta $211B
sta $211C
lda #$20
sta $211C
rep #$20
lda $2134
clc
adc $09
sta $09

lda !vwfbytes ; Adjust number of bytes
dec
sta !vwfbytes
beq .End
jmp .Read

.End
sep #$20
rtl





; Adds the background pattern to letters.

print "Pattern Addition Routine at address $",pc,"."


;$00 : Graphic
;$03 : Destination
;$06 : Number of tiles

AddPattern:
ldy #$00

.Combine
iny
lda [$03],y
eor #$FF
dey
and [$00],y
ora [$03],y
sta [$03],y

iny #2
cpy #$10
bne .Combine

rep #$20
lda $03
clc
adc #$0010
sta $03
sep #$20
dec $06
lda $06
bne AddPattern

.End
rtl





Emptytile:
db $00,$20





;;;;;;;;;;;;;;;;
;[CUSTOMTABLES];
;;;;;;;;;;;;;;;;

Fonttable:
dl Font1,Font1_Width

Palettes:
dw $0000,$FFFF,$0000
dw $0A56,$04ED,$0044
dw $45ED,$24E6,$0C41
dw $477D,$2E55,$214D
dw $00C4,$1F7F,$15D1
dw $739C,$5250,$0000
dw $473F,$3EDC,$3258
dw $5235,$290A,$679F
dw $3250,$2D09,$0C63
dw $3250,$2D09,$0C63
dw $3250,$2D09,$0C63
dw $45ED,$24E6,$0C41
dw $0A56,$04ED,$0044
dw $19F0,$00CB,$0044
dw $3250,$2D09,$0C63
dw $3250,$2D09,$0C63





;;;;;;;;;;;;;;;;
;External Files;
;;;;;;;;;;;;;;;;

Frames:
incbin vwfframes.bin

Patterns:
incbin vwfpatterns.bin

Font1:
incbin vwffont1.bin
.Width
incsrc vwffont1.asm



Codeend:

print ""

org !vwfmode
print "VWF State register at address $",pc,"."

org !message
print "Message register at address $",pc,"."

org !boxbg
print "BG GFX register at address $",pc,"."

org !boxcolor
print "BG Color register at address $",pc,"."

org !boxframe
print "Frame GFX register at address $",pc,"."


org !freespace

print ""
print "See Readme for details!"
print ""
print bytes," bytes written at address $",pc,"."


org !textfreespace
reset bytes

db "STAR"
dw Textend-Textstart
dw Textend-Textstart^#$FFFF

Textstart:

Pointers:
incsrc vwfmessagepointers.asm

Text:
incsrc vwfmessages1.asm

Textend:

org !textfreespace

print bytes," bytes written at address $",pc,"."

;-------------------------------------------------------------
;INSERT DATA HERE!





;END
;-------------------------------------------------------------
print ""
print ""


Ich hab' nur den Text: "!textfreespace = !freespace+$010000 ; Text freespace" in "!textfreespace = $258000 ; Text freespace" geändert.
Alle anderen .txt,.bin und .asm Dateien sind unverändert.

EDIT:Wie muss ich den die Grafiken einfügen,damit richtige Buchstaben vorhanden sind???
´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 11:08:55
zuletzt bearbeitet von RPG Hacker am 13.11.2010 11:12:19.
( Link )
Seltsam. Hast du denn vorher auch überprüft, ob $248000 und $258000 tatsächlich Freespace sind und nicht vielleicht schon von einem anderen Patch oder Tool belegt werden?

EDIT:
Ach ja: Welche Version von Lunar Magic hast du denn genommen und hast du es an einer komplett neuen ROM probiert oder an einer bereits veränderten?
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 11:11:00
( Link )
Ja hab' ich,BTW. ich hab' auch eine unbearbeitete Rom benutzt,und sie auf 2 MB erweitert.Könnte da vielleicht ein Haken sein?
´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 11:13:20
( Link )
Nein, hab auch 2 MB benutzt. Welche Version von Lunar Magic benutzt du? Und hast du die ROM vorher einmal in Lunar Magic geöffnet und abgespeichert?
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 11:19:48
( Link )
Lunar Magic 1.71
Nein hab' ich nicht...
´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 11:24:42
( Link )
Lunar Magic 1.71 sollte funktionieren, damit habe ich's getestet. Habe auch 1.65, 1.81 und 1.82 getestet und haben alle funktioniert.

Das mit Lunar Magic solltest du aber machen. Also: Zuerst eine Clean ROM holen, dann in Lunar Magic öffnen, irgendetwas verändern und abspeichern. Dann noch auf 2MB erhöhen - wenn du willst - und dann patchen.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 11:43:06
( Link )
*YAY* Es funktioniert!!!

Hier ein paar Bilder:







Du hattest Recht Markus,ich musste nur was verändern,und abspeichern!
Diesen Patch müsst ihr euch downloaden!!!

Super Arbeit,Respekt!
´s gibt badische und unsymbadische


Was?! Die Signaturlänge wurde auf 1024 Zeichen beschränkt? #notmysignaturelength
geschrieben am 13.11.2010 11:45:34
( Link )
Schön, dass es nun doch noch funktioniert hat!
Konnte es bisher noch nicht auf SMC Central posten, da das C3 Forum noch nicht eröffnet wurde.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 12:23:48
( Link )
Zitat von RPG Hacker:
Schön, dass es nun doch noch funktioniert hat!
Konnte es bisher noch nicht auf SMC Central posten, da das C3 Forum noch nicht eröffnet wurde.



Haha auf SMWC werden die mit ellen langen Texten voll Idioten sein!^^ "I had the same idea!" oder so ne scheiße XD
aber!
VERDAMMT NOCHMAL YOU'RE AWESOME!! ich werde es mir anschauen...schade das du nicht einen Hack( oder Teamhack z.B.) dazu zeigen kannst, das wäre cool gewesen

RPG Hacker > all, is nun mal so Leute
Wie kritisch man doch gegenüber dem System wird, wenn man älter wird...
geschrieben am 13.11.2010 12:29:36
( Link )
Zitat von Shog:
schade das du nicht einen Hack( oder Teamhack z.B.) dazu zeigen kannst, das wäre cool gewesen


Stimmt schon, aber wann hätte ich den wohl machen sollen, wenn ich Tag ein Tag aus an meinem Patch saß?
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 12:43:23
( Link )
Hm, joa, gar nicht schlecht. Hätte ich nicht ganz viel besser hingekriegt.

...Scherz, das ist einfach perfekt und viel zu gut, als das ich's hätte machen können. Das Ding hat mir schon zwei Orgasmen gegeben, und ich hab's noch nicht mal runtergeladen.
geschrieben am 13.11.2010 12:49:26
( Link )
Schön, dann habe ich mein Ziel ja schon zweimal erreicht!
Na hoffentlich wird das auch nach dem Rutnerladen noch so ein Spaß bleiben.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 13.11.2010 12:50:39
( Link )
Geil!
Endlich ist es fertig!

Ich finde das richtig(!) gut das alles geklappt hat und nun Einsatzfähig ist.
Werde wohl später ein bisschen mit dem aus Fun rumtesten, falls ich es denn verstehen sollte :3

*Thumps up for RPG Hacker*

geschrieben am 13.11.2010 13:04:19
( Link )
Omg ich habn Orgasmus gekriegt, als du diese ganz vielen Auswahlmöglichkeiten hattest und diese orangen Texte beim Schlossturm da(wo auch der japanische Text kam)

Ich habe das Video vorher übersehen Aber jetzt...omg ich probiers sofort aus
Wie kritisch man doch gegenüber dem System wird, wenn man älter wird...