diff --git a/.gitignore b/.gitignore index 0fcd880..97d55bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ /WeeGUI.xcodeproj/xcuserdata/ /gui.lst + +/guidemo.lst diff --git a/WeeGUI.xcodeproj/project.pbxproj b/WeeGUI.xcodeproj/project.pbxproj index fae5090..a874f05 100644 --- a/WeeGUI.xcodeproj/project.pbxproj +++ b/WeeGUI.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXFileReference section */ + 70868EE019BD150C00E4B4CB /* rects.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = rects.s; sourceTree = ""; }; + 70868EE119BD178F00E4B4CB /* zeropage.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = zeropage.s; sourceTree = ""; }; 709E88E319AC0A5F0069DB55 /* views.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = views.s; sourceTree = ""; }; 709E88E419AC0DC20069DB55 /* unit_test.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = unit_test.s; sourceTree = ""; }; 70B2272519A9685200702171 /* utility.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = utility.s; sourceTree = ""; }; @@ -28,9 +30,11 @@ 70D435B119A0137F001BFD9B /* Makefile */, 70F1DB4A19A56CDA00321637 /* macros.s */, 70F1DB4B19A56D6300321637 /* switches.s */, + 70868EE119BD178F00E4B4CB /* zeropage.s */, 70F1DB5D19A7FF8700321637 /* memory.s */, 70B2272519A9685200702171 /* utility.s */, 70F1DB5619A6B02900321637 /* painting.s */, + 70868EE019BD150C00E4B4CB /* rects.s */, 709E88E319AC0A5F0069DB55 /* views.s */, 70D435B219A013AF001BFD9B /* gui.s */, 709E88E419AC0DC20069DB55 /* unit_test.s */, diff --git a/gui.s b/gui.s index 73779fc..0eee19c 100644 --- a/gui.s +++ b/gui.s @@ -12,10 +12,10 @@ ; Common definitions +.include "zeropage.s" .include "switches.s" .include "macros.s" - ; Main main: @@ -32,6 +32,12 @@ main: sta PARAM1 jsr WGCreateView + lda #testTitle0 + sta PARAM1 + jsr WGViewSetTitle + lda #testCheck @@ -230,13 +236,14 @@ read80ColSwitch_40: ; Code modules .include "utility.s" .include "painting.s" +.include "rects.s" .include "views.s" .include "unit_test.s" .include "memory.s" testView: - .byte "0007033e133e7e" ; 0, 7,3,62,19,62,126 + .byte "1007033e133e7e" ; 1:0, 7,3,62,19,62,126 testCheck: .byte "011004" @@ -252,9 +259,20 @@ testStr: .byte "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ !",34,"#$%&'()*+,-./0123456789:;<=>?`abcdefghijklmno",0 testStr2: .byte "pqrstuvwxyz{|}~",$ff,0 +testTitle0: + .byte "Nifty Window",0 testTitle1: .byte "Okay",0 testTitle2: .byte "Cancel",0 + + +; Suppress some linker warnings - Must be the last thing in the file +.SEGMENT "ZPSAVE" +.SEGMENT "EXEHDR" +.SEGMENT "STARTUP" +.SEGMENT "INIT" +.SEGMENT "LOWCODE" + diff --git a/guidemo.dsk b/guidemo.dsk index 5ccef5b..2af0829 100644 Binary files a/guidemo.dsk and b/guidemo.dsk differ diff --git a/guidemo.lst b/guidemo.lst deleted file mode 100644 index b80b3fa..0000000 --- a/guidemo.lst +++ /dev/null @@ -1,37 +0,0 @@ -ca65 V2.13.3 - (C) Copyright 1998-2012 Ullrich von Bassewitz -Main file : guidemo.s -Current file: guidemo.s - -000000r 1 ; -000000r 1 ; gui.s -000000r 1 ; AssemblyTest -000000r 1 ; -000000r 1 ; Created by Quinn Dunki on 8/15/14. -000000r 1 ; Copyright (c) 2014 One Girl, One Laptop Productions. All rights reserved. -000000r 1 ; -000000r 1 -000000r 1 -000000r 1 .org $6000 -006000 1 -006000 1 ; Reserved locations -006000 1 -006000 1 -006000 1 ; Constants -006000 1 -006000 1 -006000 1 ; ROM entry points -006000 1 -006000 1 -006000 1 ; WeeGUI entry points -006000 1 -006000 1 GUI_MAIN = $4000 -006000 1 -006000 1 -006000 1 ; Main -006000 1 -006000 1 main: -006000 1 4C 00 40 jmp GUI_MAIN -006003 1 -006003 1 -006003 1 -006003 1 diff --git a/guidemo.s b/guidemo.s index 0c89cf8..7bcb69b 100644 --- a/guidemo.s +++ b/guidemo.s @@ -1,5 +1,5 @@ ; -; gui.s +; guidemo.s ; AssemblyTest ; ; Created by Quinn Dunki on 8/15/14. @@ -30,3 +30,10 @@ main: + +; Suppress some linker warnings - Must be the last thing in the file +.SEGMENT "ZPSAVE" +.SEGMENT "EXEHDR" +.SEGMENT "STARTUP" +.SEGMENT "INIT" +.SEGMENT "LOWCODE" diff --git a/memory.s b/memory.s index 838d437..169f307 100644 --- a/memory.s +++ b/memory.s @@ -7,21 +7,6 @@ ; -; Reserved locations - -INVERSE = $32 -BASL = $28 -BASH = $29 - - -; Zero page locations we use (unused by Monitor, Applesoft, or ProDOS) -PARAM0 = $06 -PARAM1 = $07 -PARAM2 = $08 -PARAM3 = $09 -SCRATCH0 = $19 -SCRATCH1 = $1A - ; Constants CHAR_NORMAL = $ff @@ -144,3 +129,4 @@ TEXTLINES_L: .byte $d0 ;21 .byte $50 ;22 .byte $d0 ;23 + diff --git a/painting.s b/painting.s index be8b640..a5aa498 100644 --- a/painting.s +++ b/painting.s @@ -1,6 +1,6 @@ ; ; painting.s -; Rendering routines for 80 column text elements +; 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. @@ -43,426 +43,6 @@ WGClearScreen_charLoop: rts -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGFillRect -; Fills a rectangle (assumes 80 cols) -; PARAM0: Left edge -; PARAM1: Top edge -; PARAM2: Width -; PARAM3: Height -; X: Character to fill -; Side effects: Clobbers BASL,BASH -; -WGFillRect: - - SAVE_AXY - SAVE_ZPS - stx SCRATCH0 - - clc ; Compute bottom edge - lda PARAM1 - adc PARAM3 - dec - tax - -WGFillRect_vertLoop: - phx ; We'll need X back for now, but save the line number - - lda TEXTLINES_L,x ; Compute video memory address of left edge of rect - sta BASL - lda TEXTLINES_H,x - sta BASH - - lda PARAM0 - lsr - clc - adc BASL - sta BASL - lda #$0 - adc BASH - sta BASH - - lda PARAM0 ; Left edge even? - and #$01 - bne WGFillRect_horzLoopOdd - - ; CASE 1: Left edge even-aligned, even width - SETSWITCH PAGE2OFF - lda PARAM2 - lsr - tay ; Iterate w/2 - dey - phy ; We'll reuse this calculation for the odd columns - -WGFillRect_horzLoopEvenAligned0: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGFillRect_horzLoopEvenAligned0 ; Loop for w/2 - - SETSWITCH PAGE2ON ; Prepare for odd columns - ply ; Iterate w/2 again - -WGFillRect_horzLoopEvenAligned1: ; Draw odd columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGFillRect_horzLoopEvenAligned1 ; Loop for w/2 - - lda PARAM2 ; Is width even? - and #$01 - beq WGFillRect_horzLoopEvenAlignedEvenWidth - - ; CASE 1a: Left edge even aligned, odd width - lda PARAM2 ; Fill in extra last column - lsr - tay - lda SCRATCH0 ; Plot the character - sta (BASL),y - -WGFillRect_horzLoopEvenAlignedEvenWidth: - plx ; Prepare for next row - dex - cpx PARAM1 - bcs WGFillRect_vertLoop - jmp WGFillRect_done - -WGFillRect_horzLoopOdd: - ; CASE 2: Left edge odd-aligned, even width - SETSWITCH PAGE2ON - lda PARAM2 - lsr - tay ; Iterate w/2 - phy ; We'll reuse this calculation for the even columns - -WGFillRect_horzLoopOddAligned0: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bne WGFillRect_horzLoopOddAligned0 ; Loop for w/2 - - SETSWITCH PAGE2OFF ; Prepare for odd columns - ply ; Iterate w/2 again, shift left 1 - dey - -WGFillRect_horzLoopOddAligned1: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGFillRect_horzLoopOddAligned1 ; Loop for w/2 - - lda PARAM2 ; Is width even? - and #$01 - beq WGFillRect_horzLoopOddAlignedEvenWidth - - ; CASE 2a: Left edge odd aligned, odd width - lda PARAM2 ; Fill in extra last column - lsr - tay - lda SCRATCH0 ; Plot the character - sta (BASL),y - -WGFillRect_horzLoopOddAlignedEvenWidth: - plx ; Prepare for next row - dex - cpx PARAM1 - bcs WGFillRect_vertLoopJmp - jmp WGFillRect_done -WGFillRect_vertLoopJmp: - jmp WGFillRect_vertLoop - -WGFillRect_done: - RESTORE_ZPS - RESTORE_AXY - rts - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGStrokeRect -; Strokes a rectangle (assumes 80 cols) -; PARAM0: Left edge -; PARAM1: Top edge -; PARAM2: Width -; PARAM3: Height -; Side effects: Clobbers BASL,BASH -; -CH_TOP = '_'+$80 -CH_BOTTOM = 'L';'_'+$80 -CH_LEFT = 'Z';'_'+$80 -CH_RIGHT = '_' -CH_BOTTOMLEFT = 'L' -CH_BOTTOMRIGHT = '_'+$80 - -WGStrokeRect: - - SAVE_AXY - SAVE_ZPS - - ; Top and bottom edges - ; - ldx PARAM1 ; Start with top edge - dex - lda #CH_TOP - sta SCRATCH0 - -WGStrokeRect_horzEdge: - lda TEXTLINES_L,x ; Compute video memory address of left edge of rect - sta BASL - lda TEXTLINES_H,x - sta BASH - - lda PARAM0 - lsr - clc - adc BASL - sta BASL - lda #$0 - adc BASH - sta BASH - - lda PARAM0 ; Left edge even? - and #$01 - bne WGStrokeRect_horzLoopOdd - - lda PARAM2 - cmp #1 ; Width==1 is a special case - beq WGStrokeRect_horzLoopEvenAlignedOneWidth - - ; CASE 1: Left edge even-aligned, even width - SETSWITCH PAGE2OFF - lda PARAM2 - lsr - tay ; Start at right edge - dey - phy ; We'll reuse this calculation for the odd columns - -WGStrokeRect_horzLoopEvenAligned0: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGStrokeRect_horzLoopEvenAligned0 ; Loop for w/2 - - SETSWITCH PAGE2ON ; Prepare for odd columns - ply ; Start at right edge again - -WGStrokeRect_horzLoopEvenAligned1: ; Draw odd columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGStrokeRect_horzLoopEvenAligned1 ; Loop for w/2 - - lda PARAM2 ; Is width even? - and #$01 - beq WGStrokeRect_horzLoopEvenAlignedEvenWidth - -WGStrokeRect_horzLoopEvenAlignedOddWidth: - ; CASE 1a: Left edge even aligned, odd width - lda PARAM2 ; Fill in extra last column - lsr - tay - lda SCRATCH0 ; Plot the character - sta (BASL),y - -WGStrokeRect_horzLoopEvenAlignedEvenWidth: - inx - cpx PARAM1 - bne WGStrokeRect_vertEdge - clc ; Prepare for bottom edge - lda PARAM1 - adc PARAM3 - tax - lda #CH_BOTTOM - sta SCRATCH0 - jmp WGStrokeRect_horzEdge - -WGStrokeRect_horzLoopEvenAlignedOneWidth: - SETSWITCH PAGE2ON - bra WGStrokeRect_horzLoopEvenAlignedOddWidth - -WGStrokeRect_horzLoopOdd: - ; CASE 2: Left edge odd-aligned, even width - - lda PARAM2 - cmp #1 ; Width==1 is a special case - beq WGStrokeRect_horzLoopOddAlignedOneWidth - - SETSWITCH PAGE2ON - lda PARAM2 - lsr - tay ; Iterate w/2 - phy ; We'll reuse this calculation for the even columns - -WGStrokeRect_horzLoopOddAligned0: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bne WGStrokeRect_horzLoopOddAligned0 ; Loop for w/2 - - SETSWITCH PAGE2OFF ; Prepare for odd columns - ply ; Iterate w/2 again, shift left 1 - dey - -WGStrokeRect_horzLoopOddAligned1: ; Draw even columns - lda SCRATCH0 ; Plot the character - sta (BASL),y - dey - bpl WGStrokeRect_horzLoopOddAligned1 ; Loop for w/2 - - lda PARAM2 ; Is width even? - and #$01 - beq WGStrokeRect_horzLoopOddAlignedEvenWidth - -WGStrokeRect_horzLoopOddAlignedOddWidth: - ; CASE 2a: Left edge odd aligned, odd width - lda PARAM2 ; Fill in extra last column - dec - lsr - tay - lda SCRATCH0 ; Plot the character - sta (BASL),y - -WGStrokeRect_horzLoopOddAlignedEvenWidth: - inx - cpx PARAM1 - bne WGStrokeRect_vertEdge - clc ; Prepare for bottom edge - lda PARAM1 - adc PARAM3 - tax - lda #CH_BOTTOM - sta SCRATCH0 - jmp WGStrokeRect_horzEdge - -WGStrokeRect_horzLoopOddAlignedOneWidth: - SETSWITCH PAGE2OFF - bra WGStrokeRect_horzLoopOddAlignedOddWidth - -WGStrokeRect_vertEdge: - ; Left and right edges - ; - clc - lda PARAM1 ; Compute bottom edge - adc PARAM3 - sta SCRATCH0 - - ldx PARAM1 ; Start with top edge - -WGStrokeRect_vertLoop: - - phx ; We'll need X back for now, but save the line number - - lda TEXTLINES_L,x ; Compute video memory address of left edge of rect - sta BASL - lda TEXTLINES_H,x - sta BASH - - lda PARAM0 - dec - lsr - clc - adc BASL - sta BASL - lda #$0 - adc BASH - sta BASH - - lda PARAM0 ; Left edge even? - dec - and #$01 - bne WGStrokeRect_vertLoopOdd - - ; CASE 1: Left edge even-aligned, even width - SETSWITCH PAGE2ON - ldy #$0 - lda #CH_LEFT ; Plot the left edge - sta (BASL),y - - lda PARAM2 ; Is width even? - inc - inc - and #$01 - bne WGStrokeRect_vertLoopEvenAlignedOddWidth - - lda PARAM2 ; Calculate right edge - inc - inc - lsr - dec - tay - SETSWITCH PAGE2OFF - lda #CH_RIGHT ; Plot the right edge - sta (BASL),y - jmp WGStrokeRect_vertLoopEvenAlignedNextRow - -WGStrokeRect_vertLoopEvenAlignedOddWidth: - ; CASE 1a: Left edge even-aligned, odd width - SETSWITCH PAGE2ON - lda PARAM2 ; Calculate right edge - inc - inc - lsr - tay - lda #CH_RIGHT ; Plot the right edge - sta (BASL),y - -WGStrokeRect_vertLoopEvenAlignedNextRow: - plx ; Prepare for next row - inx - cpx SCRATCH0 - bne WGStrokeRect_vertLoop - jmp WGStrokeRect_done - - -WGStrokeRect_vertLoopOdd: - ; CASE 2: Left edge odd-aligned, even width - SETSWITCH PAGE2OFF - ldy #$0 - lda #CH_LEFT ; Plot the left edge - sta (BASL),y - - lda PARAM2 ; Is width even? - inc - inc - and #$01 - bne WGStrokeRect_vertLoopOddAlignedOddWidth - - lda PARAM2 ; Calculate right edge - inc - inc - lsr - tay - SETSWITCH PAGE2ON - lda #CH_RIGHT ; Plot the right edge - sta (BASL),y - jmp WGStrokeRect_vertLoopOddAlignedNextRow - -WGStrokeRect_vertLoopOddAlignedOddWidth: - ; CASE 2a: Left edge odd-aligned, odd width - SETSWITCH PAGE2OFF - lda PARAM2 ; Calculate right edge - inc - inc - lsr - tay - lda #CH_RIGHT ; Plot the right edge - sta (BASL),y - -WGStrokeRect_vertLoopOddAlignedNextRow: - plx ; Prepare for next row - inx - cpx SCRATCH0 - bne WGStrokeRect_vertLoopJmp - jmp WGStrokeRect_done -WGStrokeRect_vertLoopJmp: - jmp WGStrokeRect_vertLoop - -WGStrokeRect_done: - RESTORE_ZPS - RESTORE_AXY - rts - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGPlot ; Plots a character at current cursor position (assumes 80 cols) diff --git a/rects.s b/rects.s new file mode 100644 index 0000000..cc0850e --- /dev/null +++ b/rects.s @@ -0,0 +1,745 @@ +; +; rects.s +; Rectangle 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. +; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGFillRect +; Fills a rectangle (assumes 80 cols) +; PARAM0: Left edge +; PARAM1: Top edge +; PARAM2: Width +; PARAM3: Height +; X: Character to fill +; Side effects: Clobbers BASL,BASH +; +WGFillRect: + + SAVE_AXY + SAVE_ZPS + stx SCRATCH0 + + clc ; Compute bottom edge + lda PARAM1 + adc PARAM3 + dec + tax + +WGFillRect_vertLoop: + phx ; We'll need X back for now, but save the line number + + lda TEXTLINES_L,x ; Compute video memory address of left edge of rect + sta BASL + lda TEXTLINES_H,x + sta BASH + + lda PARAM0 + lsr + clc + adc BASL + sta BASL + lda #$0 + adc BASH + sta BASH + + lda PARAM0 ; Left edge even? + and #$01 + bne WGFillRect_horzLoopOdd + + ; CASE 1: Left edge even-aligned, even width + SETSWITCH PAGE2OFF + lda PARAM2 + lsr + tay ; Iterate w/2 + dey + phy ; We'll reuse this calculation for the odd columns + +WGFillRect_horzLoopEvenAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFillRect_horzLoopEvenAligned0 ; Loop for w/2 + + SETSWITCH PAGE2ON ; Prepare for odd columns + ply ; Iterate w/2 again + +WGFillRect_horzLoopEvenAligned1: ; Draw odd columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFillRect_horzLoopEvenAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGFillRect_horzLoopEvenAlignedEvenWidth + + ; CASE 1a: Left edge even aligned, odd width + lda PARAM2 ; Fill in extra last column + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGFillRect_horzLoopEvenAlignedEvenWidth: + plx ; Prepare for next row + dex + cpx PARAM1 + bcs WGFillRect_vertLoop + jmp WGFillRect_done + +WGFillRect_horzLoopOdd: + ; CASE 2: Left edge odd-aligned, even width + SETSWITCH PAGE2ON + lda PARAM2 + lsr + tay ; Iterate w/2 + phy ; We'll reuse this calculation for the even columns + +WGFillRect_horzLoopOddAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bne WGFillRect_horzLoopOddAligned0 ; Loop for w/2 + + SETSWITCH PAGE2OFF ; Prepare for odd columns + ply ; Iterate w/2 again, shift left 1 + dey + +WGFillRect_horzLoopOddAligned1: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFillRect_horzLoopOddAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGFillRect_horzLoopOddAlignedEvenWidth + + ; CASE 2a: Left edge odd aligned, odd width + lda PARAM2 ; Fill in extra last column + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGFillRect_horzLoopOddAlignedEvenWidth: + plx ; Prepare for next row + dex + cpx PARAM1 + bcs WGFillRect_vertLoopJmp + jmp WGFillRect_done +WGFillRect_vertLoopJmp: + jmp WGFillRect_vertLoop + +WGFillRect_done: + RESTORE_ZPS + RESTORE_AXY + rts + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGStrokeRect +; Strokes a rectangle (assumes 80 cols) +; PARAM0: Left edge +; PARAM1: Top edge +; PARAM2: Width +; PARAM3: Height +; Side effects: Clobbers BASL,BASH +; +CH_TOP = '_'+$80 +CH_BOTTOM = 'L' +CH_LEFT = 'Z' +CH_RIGHT = '_' + +WGStrokeRect: + + SAVE_AXY + SAVE_ZPS + + ; Top and bottom edges + ; + ldx PARAM1 ; Start with top edge + dex + lda #CH_TOP + sta SCRATCH0 + +WGStrokeRect_horzEdge: + lda TEXTLINES_L,x ; Compute video memory address of left edge of rect + sta BASL + lda TEXTLINES_H,x + sta BASH + + lda PARAM0 + lsr + clc + adc BASL + sta BASL + lda #$0 + adc BASH + sta BASH + + lda PARAM0 ; Left edge even? + and #$01 + bne WGStrokeRect_horzLoopOdd + + lda PARAM2 + cmp #1 ; Width==1 is a special case + beq WGStrokeRect_horzLoopEvenAlignedOneWidth + + ; CASE 1: Left edge even-aligned, even width + SETSWITCH PAGE2OFF + lda PARAM2 + lsr + tay ; Start at right edge + dey + phy ; We'll reuse this calculation for the odd columns + +WGStrokeRect_horzLoopEvenAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGStrokeRect_horzLoopEvenAligned0 ; Loop for w/2 + + SETSWITCH PAGE2ON ; Prepare for odd columns + ply ; Start at right edge again + +WGStrokeRect_horzLoopEvenAligned1: ; Draw odd columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGStrokeRect_horzLoopEvenAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGStrokeRect_horzLoopEvenAlignedEvenWidth + +WGStrokeRect_horzLoopEvenAlignedOddWidth: + ; CASE 1a: Left edge even aligned, odd width + lda PARAM2 ; Fill in extra last column + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGStrokeRect_horzLoopEvenAlignedEvenWidth: + inx + cpx PARAM1 + bne WGStrokeRect_vertEdge + clc ; Prepare for bottom edge + lda PARAM1 + adc PARAM3 + tax + lda #CH_BOTTOM + sta SCRATCH0 + jmp WGStrokeRect_horzEdge + +WGStrokeRect_horzLoopEvenAlignedOneWidth: + SETSWITCH PAGE2ON + bra WGStrokeRect_horzLoopEvenAlignedOddWidth + +WGStrokeRect_horzLoopOdd: + ; CASE 2: Left edge odd-aligned, even width + + lda PARAM2 + cmp #1 ; Width==1 is a special case + beq WGStrokeRect_horzLoopOddAlignedOneWidth + + SETSWITCH PAGE2ON + lda PARAM2 + lsr + tay ; Iterate w/2 + phy ; We'll reuse this calculation for the even columns + +WGStrokeRect_horzLoopOddAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bne WGStrokeRect_horzLoopOddAligned0 ; Loop for w/2 + + SETSWITCH PAGE2OFF ; Prepare for odd columns + ply ; Iterate w/2 again, shift left 1 + dey + +WGStrokeRect_horzLoopOddAligned1: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGStrokeRect_horzLoopOddAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGStrokeRect_horzLoopOddAlignedEvenWidth + +WGStrokeRect_horzLoopOddAlignedOddWidth: + ; CASE 2a: Left edge odd aligned, odd width + lda PARAM2 ; Fill in extra last column + dec + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGStrokeRect_horzLoopOddAlignedEvenWidth: + inx + cpx PARAM1 + bne WGStrokeRect_vertEdge + clc ; Prepare for bottom edge + lda PARAM1 + adc PARAM3 + tax + lda #CH_BOTTOM + sta SCRATCH0 + jmp WGStrokeRect_horzEdge + +WGStrokeRect_horzLoopOddAlignedOneWidth: + SETSWITCH PAGE2OFF + bra WGStrokeRect_horzLoopOddAlignedOddWidth + +WGStrokeRect_vertEdge: + ; Left and right edges + ; + clc + lda PARAM1 ; Compute bottom edge + adc PARAM3 + sta SCRATCH0 + + ldx PARAM1 ; Start with top edge + +WGStrokeRect_vertLoop: + + phx ; We'll need X back for now, but save the line number + + lda TEXTLINES_L,x ; Compute video memory address of left edge of rect + sta BASL + lda TEXTLINES_H,x + sta BASH + + lda PARAM0 + dec + lsr + clc + adc BASL + sta BASL + lda #$0 + adc BASH + sta BASH + + lda PARAM0 ; Left edge even? + dec + and #$01 + bne WGStrokeRect_vertLoopOdd + + ; CASE 1: Left edge even-aligned, even width + SETSWITCH PAGE2ON + ldy #$0 + lda #CH_LEFT ; Plot the left edge + sta (BASL),y + + lda PARAM2 ; Is width even? + inc + inc + and #$01 + bne WGStrokeRect_vertLoopEvenAlignedOddWidth + + lda PARAM2 ; Calculate right edge + inc + inc + lsr + dec + tay + SETSWITCH PAGE2OFF + lda #CH_RIGHT ; Plot the right edge + sta (BASL),y + jmp WGStrokeRect_vertLoopEvenAlignedNextRow + +WGStrokeRect_vertLoopEvenAlignedOddWidth: + ; CASE 1a: Left edge even-aligned, odd width + SETSWITCH PAGE2ON + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + lda #CH_RIGHT ; Plot the right edge + sta (BASL),y + +WGStrokeRect_vertLoopEvenAlignedNextRow: + plx ; Prepare for next row + inx + cpx SCRATCH0 + bne WGStrokeRect_vertLoop + jmp WGStrokeRect_done + + +WGStrokeRect_vertLoopOdd: + ; CASE 2: Left edge odd-aligned, even width + SETSWITCH PAGE2OFF + ldy #$0 + lda #CH_LEFT ; Plot the left edge + sta (BASL),y + + lda PARAM2 ; Is width even? + inc + inc + and #$01 + bne WGStrokeRect_vertLoopOddAlignedOddWidth + + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + SETSWITCH PAGE2ON + lda #CH_RIGHT ; Plot the right edge + sta (BASL),y + jmp WGStrokeRect_vertLoopOddAlignedNextRow + +WGStrokeRect_vertLoopOddAlignedOddWidth: + ; CASE 2a: Left edge odd-aligned, odd width + SETSWITCH PAGE2OFF + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + lda #CH_RIGHT ; Plot the right edge + sta (BASL),y + +WGStrokeRect_vertLoopOddAlignedNextRow: + plx ; Prepare for next row + inx + cpx SCRATCH0 + bne WGStrokeRect_vertLoopJmp + jmp WGStrokeRect_done +WGStrokeRect_vertLoopJmp: + jmp WGStrokeRect_vertLoop + +WGStrokeRect_done: + RESTORE_ZPS + RESTORE_AXY + rts + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGFancyRect +; Draws a fancy rectangle (assumes 80 cols) +; PARAM0: Left edge +; PARAM1: Top edge +; PARAM2: Width +; PARAM3: Height +; Side effects: Clobbers BASL,BASH +; +FR_TOP = '\' +FR_BOTTOM = '_'+$80 +FR_LEFT = 'Z' +FR_RIGHT = 'Z' +FR_TOPLEFT = 'Z' +FR_TOPRIGHT = '^' +FR_TOPRIGHTA = 'R' +FR_BOTTOMRIGHT = $7f +FR_BOTTOMRIGHTA1 = 'Q' +FR_BOTTOMRIGHTA2 = 'P' +FR_BOTTOMLEFT = 'Z' +FR_BOTTOMLEFTA = 'O' + +WGFancyRect: + SAVE_AXY + SAVE_ZPS + + ; Top and bottom edges + ; + ldx PARAM1 ; Start with top edge + dex + lda #FR_TOP + sta SCRATCH0 + +WGFancyRect_horzEdge: + lda TEXTLINES_L,x ; Compute video memory address of left edge of rect + sta BASL + lda TEXTLINES_H,x + sta BASH + + lda PARAM0 + lsr + clc + adc BASL + sta BASL + lda #$0 + adc BASH + sta BASH + + lda PARAM0 ; Left edge even? + and #$01 + bne WGFancyRect_horzLoopOdd + + ; CASE 1: Left edge even-aligned, even width + SETSWITCH PAGE2OFF + lda PARAM2 + lsr + tay ; Start at right edge + dey + phy ; We'll reuse this calculation for the odd columns + +WGFancyRect_horzLoopEvenAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFancyRect_horzLoopEvenAligned0 ; Loop for w/2 + + SETSWITCH PAGE2ON ; Prepare for odd columns + ply ; Start at right edge again + +WGFancyRect_horzLoopEvenAligned1: ; Draw odd columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFancyRect_horzLoopEvenAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGFancyRect_horzLoopEvenAlignedEvenWidth + +WGFancyRect_horzLoopEvenAlignedOddWidth: + ; CASE 1a: Left edge even aligned, odd width + lda PARAM2 ; Fill in extra last column + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGFancyRect_horzLoopEvenAlignedEvenWidth: + inx + cpx PARAM1 + bne WGFancyRect_vertEdge + clc ; Prepare for bottom edge + lda PARAM1 + adc PARAM3 + tax + lda #FR_BOTTOM + sta SCRATCH0 + jmp WGFancyRect_horzEdge + +WGFancyRect_horzLoopOdd: + ; CASE 2: Left edge odd-aligned, even width + + SETSWITCH PAGE2ON + lda PARAM2 + lsr + tay ; Iterate w/2 + phy ; We'll reuse this calculation for the even columns + +WGFancyRect_horzLoopOddAligned0: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bne WGFancyRect_horzLoopOddAligned0 ; Loop for w/2 + + SETSWITCH PAGE2OFF ; Prepare for odd columns + ply ; Iterate w/2 again, shift left 1 + dey + +WGFancyRect_horzLoopOddAligned1: ; Draw even columns + lda SCRATCH0 ; Plot the character + sta (BASL),y + dey + bpl WGFancyRect_horzLoopOddAligned1 ; Loop for w/2 + + lda PARAM2 ; Is width even? + and #$01 + beq WGFancyRect_horzLoopOddAlignedEvenWidth + +WGFancyRect_horzLoopOddAlignedOddWidth: + ; CASE 2a: Left edge odd aligned, odd width + lda PARAM2 ; Fill in extra last column + dec + lsr + tay + lda SCRATCH0 ; Plot the character + sta (BASL),y + +WGFancyRect_horzLoopOddAlignedEvenWidth: + inx + cpx PARAM1 + bne WGFancyRect_vertEdge + clc ; Prepare for bottom edge + lda PARAM1 + adc PARAM3 + tax + lda #FR_BOTTOM + sta SCRATCH0 + jmp WGFancyRect_horzEdge + +WGFancyRect_vertEdge: + ; Left and right edges + ; + clc + lda PARAM1 ; Compute bottom edge + adc PARAM3 + sta SCRATCH0 + + ldx PARAM1 ; Start with top edge + +WGFancyRect_vertLoop: + + phx ; We'll need X back for now, but save the line number + + lda TEXTLINES_L,x ; Compute video memory address of left edge of rect + sta BASL + lda TEXTLINES_H,x + sta BASH + + lda PARAM0 + dec + lsr + clc + adc BASL + sta BASL + lda #$0 + adc BASH + sta BASH + + lda PARAM0 ; Left edge even? + dec + and #$01 + bne WGFancyRect_vertLoopOdd + + ; CASE 1: Left edge even-aligned, even width + SETSWITCH PAGE2ON + ldy #$0 + lda #FR_LEFT ; Plot the left edge + sta (BASL),y + + lda PARAM2 ; Is width even? + inc + inc + and #$01 + bne WGFancyRect_vertLoopEvenAlignedOddWidth + + lda PARAM2 ; Calculate right edge + inc + inc + lsr + dec + tay + SETSWITCH PAGE2OFF + lda #FR_RIGHT ; Plot the right edge + sta (BASL),y + jmp WGFancyRect_vertLoopEvenAlignedNextRow + +WGFancyRect_vertLoopEvenAlignedOddWidth: + ; CASE 1a: Left edge even-aligned, odd width + SETSWITCH PAGE2ON + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + lda #FR_RIGHT ; Plot the right edge + sta (BASL),y + +WGFancyRect_vertLoopEvenAlignedNextRow: + plx ; Prepare for next row + inx + cpx SCRATCH0 + bne WGFancyRect_vertLoop + jmp WGFancyRect_corners + + +WGFancyRect_vertLoopOdd: + ; CASE 2: Left edge odd-aligned, even width + SETSWITCH PAGE2OFF + ldy #$0 + lda #FR_LEFT ; Plot the left edge + sta (BASL),y + + lda PARAM2 ; Is width even? + inc + inc + and #$01 + bne WGFancyRect_vertLoopOddAlignedOddWidth + + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + SETSWITCH PAGE2ON + lda #FR_RIGHT ; Plot the right edge + sta (BASL),y + jmp WGFancyRect_vertLoopOddAlignedNextRow + +WGFancyRect_vertLoopOddAlignedOddWidth: + ; CASE 2a: Left edge odd-aligned, odd width + SETSWITCH PAGE2OFF + lda PARAM2 ; Calculate right edge + inc + inc + lsr + tay + lda #FR_RIGHT ; Plot the right edge + sta (BASL),y + +WGFancyRect_vertLoopOddAlignedNextRow: + plx ; Prepare for next row + inx + cpx SCRATCH0 + bne WGFancyRect_vertLoopJmp + jmp WGFancyRect_corners +WGFancyRect_vertLoopJmp: + jmp WGFancyRect_vertLoop + +WGFancyRect_corners: + lda PARAM0 ; Top left corner + dec + sta WG_CURSORX + lda PARAM1 + dec + sta WG_CURSORY + lda #FR_TOPLEFT + jsr WGPlot + + lda PARAM0 ; Top right corner + clc + adc PARAM2 + sta WG_CURSORX + lda #FR_TOPRIGHT + jsr WGPlot + + inc WG_CURSORY + lda #FR_TOPRIGHTA + jsr WGPlot + + lda PARAM1 ; Bottom right corner + dec + clc + adc PARAM3 + sta WG_CURSORY + lda #FR_BOTTOMRIGHTA1 + jsr WGPlot + + inc WG_CURSORY + lda #FR_BOTTOMRIGHT + jsr WGPlot + + dec WG_CURSORX + lda #FR_BOTTOMRIGHTA2 + jsr WGPlot + + lda PARAM0 ; Bottom left corner + sta WG_CURSORX + lda #FR_BOTTOMLEFTA + jsr WGPlot + dec WG_CURSORX + lda #FR_BOTTOMLEFT + jsr WGPlot + +WGFancyRect_done: + RESTORE_ZPS + RESTORE_AXY + rts + diff --git a/views.s b/views.s index 8e7b35d..7e9d4d3 100644 --- a/views.s +++ b/views.s @@ -257,7 +257,11 @@ WGPaintView: lda WG_VIEWRECORDS+3,y sta PARAM3 - jsr WGStrokeRect ; Draw outline + lda SCRATCH0 ; Draw outline + cmp #VIEW_STYLE_FANCY + beq WGPaintView_decorated + + jsr WGStrokeRect lda SCRATCH0 cmp #VIEW_STYLE_CHECK @@ -266,6 +270,11 @@ WGPaintView: beq WGPaintView_button bra WGPaintView_done +WGPaintView_decorated: + jsr WGFancyRect + jsr paintWindowTitle + bra WGPaintView_done + WGPaintView_check: jsr paintCheck bra WGPaintView_done @@ -395,6 +404,39 @@ paintButton_done: rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; paintWindowTitle +; Paints the title of a fancy window +; Y: Index into view records of view title to paint +; +paintWindowTitle: + SAVE_AX + SAVE_ZPS + + lda WG_VIEWRECORDS+13,y ; Prep the title string + sta PARAM0 + lda WG_VIEWRECORDS+12,y + sta PARAM1 + + jsr WGStrLen ; Compute centering offset for title + lsr + sta SCRATCH1 + lda WG_VIEWRECORDS+2,y + lsr + sec + sbc SCRATCH1 + sta WG_LOCALCURSORX + lda #-1 + sta WG_LOCALCURSORY + + jsr WGPrint + +paintWindowTitle_done: + RESTORE_ZPS + RESTORE_AX + rts + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGEraseView ; Erases the current view (including decoration) diff --git a/zeropage.s b/zeropage.s new file mode 100644 index 0000000..b8c1632 --- /dev/null +++ b/zeropage.s @@ -0,0 +1,23 @@ +; +; zeropage.s +; Zero page information +; +; Created by Quinn Dunki on 8/15/14. +; Copyright (c) 2014 One Girl, One Laptop Productions. All rights reserved. +; + + +; Reserved locations + +INVERSE = $32 +BASL = $28 +BASH = $29 + + +; Zero page locations we use (unused by Monitor, Applesoft, or ProDOS) +PARAM0 = $06 +PARAM1 = $07 +PARAM2 = $08 +PARAM3 = $09 +SCRATCH0 = $19 +SCRATCH1 = $1A