WeeGUI/painting.s
2018-03-07 14:38:22 -08:00

287 lines
6.0 KiB
ArmAsm

;
; painting.s
; General rendering routines for 80 column text elements
;
; Created by Quinn Dunki on 8/15/14.
; Copyright (c) 2014 One Girl, One Laptop Productions. All rights reserved.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGDesktop
; Paints the desktop pattern (assumes 80 cols)
;
WGDesktop:
pha
lda #'W'
sta WGClearScreen_charPage1+1
lda #'V'
bra WGClearScreen_common
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGClearScreen
; Clears the text screen (assumes 80 cols)
;
WGClearScreen:
pha
lda #' ' + $80
sta WGClearScreen_charPage1+1
WGClearScreen_common:
sta WGClearScreen_charPage2+1
SAVE_XY
SETSWITCH PAGE2OFF
ldx #23
WGClearScreen_lineLoop:
lda TEXTLINES_L,x ; Compute video memory address of line
sta WGClearScreen_charLoop1+1
sta WGClearScreen_charLoop2+1
lda TEXTLINES_H,x
sta WGClearScreen_charLoop1+2
sta WGClearScreen_charLoop2+2
ldy #39
WGClearScreen_charPage1:
lda #$FF ; Self-modifying code!
WGClearScreen_charLoop1:
sta $FFFF,y ; Self-modifying code!
dey
bpl WGClearScreen_charLoop1
SETSWITCH PAGE2ON
ldy #39
WGClearScreen_charPage2:
lda #$FF ; Self-modifying code!
WGClearScreen_charLoop2:
sta $FFFF,y ; Self-modifying code!
dey
bpl WGClearScreen_charLoop2
SETSWITCH PAGE2OFF
dex
bpl WGClearScreen_lineLoop
RESTORE_XY
pla
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGPlot
; Plots a character at global cursor position (assumes 80 cols)
; A: Character to plot (Apple format)
; Side effects: Clobbers BASL,BASH
;
WGPlot:
SAVE_XY
pha
ldx WG_CURSORY
lda TEXTLINES_L,x ; Compute video memory address of point
sta BASL
lda TEXTLINES_H,x
sta BASH
lda WG_CURSORX
lsr
clc
adc BASL
sta BASL
bcc WGPlot_SkipInc
inc BASH
WGPlot_SkipInc:
lda WG_CURSORX ; X even?
ror
bcs WGPlot_xOdd
SETSWITCH PAGE2ON ; Plot the character
pla
sta (BASL)
jmp WGPlot_done
WGPlot_xOdd:
SETSWITCH PAGE2OFF ; Plot the character
pla
sta (BASL)
WGPlot_done:
SETSWITCH PAGE2OFF
RESTORE_XY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGPrint
; Prints a null-terminated ASCII string at the current view's
; cursor position. Clips to current view.
; PARAM0: String pointer, LSB
; PARAM1: String pointer, MSB
; V: If set, characters are printed raw with no high bit alterations
; Side effects: Clobbers SA,BASL,BASH
;
WGPrint:
SAVE_AXY
SAVE_ZPS
lda #%10000000
ldx #%00111111
bvc WGPrint_setupMask
lda #0
ldx #$ff
clv
WGPrint_setupMask:
sta WGPrint_specialMask
stx WGPrint_setupMaskInverse
; Start checking clipping boundaries
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+3
bcs WGPrint_leapDone ; Entire string is below the clip box
jsr WGStrLen ; We'll need the length of the string
sta SCRATCH1
LDX_ACTIVEVIEW ; Cache view width for later
lda WG_VIEWRECORDS+7,x
sta WG_SCRATCHA
ldy #0
WGPrint_lineLoopFirst: ; Calculating start of first line is slightly different
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+1
bcc WGPrint_skipToEndFirst ; This line is above the clip box
lda WG_LOCALCURSORX ; Find start of line within clip box
cmp WG_VIEWCLIP+0
bcs WGPrint_visibleChars
lda WG_VIEWCLIP+0 ; Line begins before left clip plane
sec ; Advance string index and advance cursor into clip box
sbc WG_LOCALCURSORX
tay
lda WG_VIEWCLIP+0
sta WG_LOCALCURSORX
bra WGPrint_visibleChars
WGPrint_leapDone:
bra WGPrint_done
WGPrint_skipToEndFirst:
lda WG_SCRATCHA ; Skip string index ahead by distance to EOL
sec
sbc WG_LOCALCURSORX
cmp SCRATCH1
bcs WGPrint_done ; EOL is past the end of the string, so we're done
tay
lda WG_SCRATCHA ; Skip cursor ahead to EOL
sta WG_LOCALCURSORX
bra WGPrint_nextLine
WGPrint_skipToEnd:
tya ; Skip string index ahead by distance to EOL
clc
adc WG_SCRATCHA
cmp SCRATCH1
bcs WGPrint_done ; EOL is past the end of the string, so we're done
tay
lda WG_SCRATCHA ; Skip cursor ahead to EOL
sta WG_LOCALCURSORX
bra WGPrint_nextLine
WGPrint_lineLoop:
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+1
bcc WGPrint_skipToEnd ; This line is above the clip box
lda WG_LOCALCURSORX ; Find start of line within clip box
cmp WG_VIEWCLIP+0
bcs WGPrint_visibleChars
tya
clc
adc WG_VIEWCLIP+0 ; Jump ahead by left span
tay
lda WG_VIEWCLIP+0 ; Set cursor to left edge of visible area
sta WG_LOCALCURSORX
WGPrint_visibleChars:
jsr WGSyncGlobalCursor
lda INVERSE
cmp #CHAR_INVERSE
beq WGPrint_charLoopInverse
WGPrint_charLoopNormal:
lda (PARAM0),y ; Draw current character
beq WGPrint_done
ora WGPrint_specialMask
jsr WGPlot
iny
inc WG_CURSORX ; Advance cursors
inc WG_LOCALCURSORX
lda WG_LOCALCURSORX
cmp WG_SCRATCHA ; Check for wrap boundary
beq WGPrint_nextLine
cmp WG_VIEWCLIP+2 ; Check for right clip plane
beq WGPrint_endVisible
bra WGPrint_charLoopNormal
WGPrint_done: ; This is in the middle here to keep local branches in range
RESTORE_ZPS
RESTORE_AXY
rts
WGPrint_endVisible:
tya
clc
adc WG_VIEWCLIP+4 ; Advance string index by right span
cmp SCRATCH1
bcs WGPrint_done
tay
WGPrint_nextLine:
inc WG_LOCALCURSORY ; Advance cursor
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+3 ; Check for bottom clip plane
beq WGPrint_done
cmp WG_VIEWRECORDS+8,x ; Check for bottom of view
beq WGPrint_done
lda (PARAM0),y ; Check for end string landing exactly at line end
beq WGPrint_done
stz WG_LOCALCURSORX
bra WGPrint_lineLoop
WGPrint_charLoopInverse:
lda (PARAM0),y ; Draw current character
beq WGPrint_done
cmp #$60
bcc WGPrint_charLoopInverseLow
and #%01111111 ; Inverse lowercase is in alternate character set
bra WGPrint_charLoopInversePlot
WGPrint_charLoopInverseLow:
and WGPrint_setupMaskInverse ; Normal inverse
WGPrint_charLoopInversePlot:
jsr WGPlot
iny
inc WG_CURSORX ; Advance cursors
inc WG_LOCALCURSORX
lda WG_LOCALCURSORX
cmp WG_SCRATCHA ; Check for wrap boundary
beq WGPrint_nextLine
cmp WG_VIEWCLIP+2 ; Check for right clip plane
beq WGPrint_endVisible
bra WGPrint_charLoopInverse
WGPrint_specialMask:
.byte 0
WGPrint_setupMaskInverse:
.byte 0