; ; views.s ; Management routines for GUI views ; ; Created by Quinn Dunki on 8/15/14. ; Copyright (c) 2014 One Girl, One Laptop Productions. All rights reserved. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGCreateView ; Creates and selects a new view ; PARAM0: Pointer to configuration struct (LSB) ; PARAM1: Pointer to configuration struct (MSB) ; ; Configuration struct: ; ID: View ID (0-f) ; ST: Style ; XX: Screen X origin ; YY: Screen Y origin ; SW: Screen width ; SH: Screen height ; VW: View Width ; VH: View Height ; WGCreateView: SAVE_AXY ldy #0 lda (PARAM0),y ; Find our new view record pha ; Cache view ID so we can select when we're done asl asl asl asl ; Records are 8 bytes wide tax iny lda (PARAM0),y pha ; Cache style byte for later iny lda (PARAM0),y sta WG_VIEWRECORDS+0,x ; Screen X iny lda (PARAM0),y sta WG_VIEWRECORDS+1,x ; Screen Y iny lda (PARAM0),y sta WG_VIEWRECORDS+2,x ; Screen Width iny lda (PARAM0),y sta WG_VIEWRECORDS+3,x ; Screen Height pla sta WG_VIEWRECORDS+4,x ; Style stz WG_VIEWRECORDS+5,x ; Initialize scrolling stz WG_VIEWRECORDS+6,x iny lda (PARAM0),y sta WG_VIEWRECORDS+7,x ; View Width iny lda (PARAM0),y sta WG_VIEWRECORDS+8,x ; View Height stz WG_VIEWRECORDS+9,x ; Initialize state stz WG_VIEWRECORDS+10,x ; Initialize callback stz WG_VIEWRECORDS+11,x stz WG_VIEWRECORDS+12,x ; Initialize title stz WG_VIEWRECORDS+13,x pla jsr WGSelectView ; Leave this as the active view WGCreateView_done: RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGCreateCheckbox ; Creates a new checkbox ; PARAM0: Pointer to configuration struct (LSB) ; PARAM1: Pointer to configuration struct (MSB) ; ; Configuration struct: ; ID: View ID (0-f) ; XX: Screen X origin ; YY: Screen Y origin ; SL: String pointer (LSB) ; SH: String pointer (MSB) ; WGCreateCheckbox: SAVE_AXY ldy #0 lda (PARAM0),y ; Find our new view record pha ; Cache view ID so we can select when we're done asl asl asl asl ; Records are 16 bytes wide tax iny lda (PARAM0),y sta WG_VIEWRECORDS+0,x ; Screen X iny lda (PARAM0),y sta WG_VIEWRECORDS+1,x ; Screen Y lda #1 sta WG_VIEWRECORDS+2,x ; Initialize screen width sta WG_VIEWRECORDS+3,x ; Initialize screen height sta WG_VIEWRECORDS+7,x ; Initialize view width sta WG_VIEWRECORDS+8,x ; Initialize view height lda #VIEW_STYLE_CHECK sta WG_VIEWRECORDS+4,x ; Style stz WG_VIEWRECORDS+5,x ; Initialize scrolling stz WG_VIEWRECORDS+6,x stz WG_VIEWRECORDS+9,x ; Initialize state stz WG_VIEWRECORDS+10,x ; Initialize callback stz WG_VIEWRECORDS+11,x iny lda (PARAM0),y sta WG_VIEWRECORDS+12,x ; Title iny lda (PARAM0),y sta WG_VIEWRECORDS+13,x pla jsr WGSelectView ; Leave this as the active view WGCreateCheckbox_done: RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGCreateButton ; Creates a new button ; PARAM0: Pointer to configuration struct (LSB) ; PARAM1: Pointer to configuration struct (MSB) ; ; Configuration struct: ; ID: View ID (0-f) ; XX: Screen X origin ; YY: Screen Y origin ; BW: Button width ; PL: Action callback (LSB) ; PH: Action callback (MSB) ; SL: Title string pointer (LSB) ; SH: Title string pointer (MSB) WGCreateButton: SAVE_AXY ldy #0 lda (PARAM0),y ; Find our new view record pha ; Cache view ID so we can select when we're done asl asl asl asl ; Records are 16 bytes wide tax iny lda (PARAM0),y sta WG_VIEWRECORDS+0,x ; Screen X iny lda (PARAM0),y sta WG_VIEWRECORDS+1,x ; Screen Y iny lda (PARAM0),y sta WG_VIEWRECORDS+2,x ; Screen width sta WG_VIEWRECORDS+7,x ; View width lda #1 sta WG_VIEWRECORDS+3,x ; Initialize screen height sta WG_VIEWRECORDS+8,x ; Initialize view height lda #VIEW_STYLE_BUTTON sta WG_VIEWRECORDS+4,x ; Style stz WG_VIEWRECORDS+5,x ; Initialize scrolling stz WG_VIEWRECORDS+6,x stz WG_VIEWRECORDS+9,x ; Initialize state iny lda (PARAM0),y sta WG_VIEWRECORDS+10,x ; Callback iny lda (PARAM0),y sta WG_VIEWRECORDS+11,x iny lda (PARAM0),y sta WG_VIEWRECORDS+12,x ; Title iny lda (PARAM0),y sta WG_VIEWRECORDS+13,x pla jsr WGSelectView ; Leave this as the active view WGCreateButton_done: RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGPaintView ; Paints the current view ; WGPaintView: SAVE_AXY SAVE_ZPP LDY_ACTIVEVIEW lda WG_VIEWRECORDS+4,y ; Cache style information and #$f ; Mask off flag bits pha lda WG_VIEWRECORDS+0,y ; Fetch the geometry sta PARAM0 lda WG_VIEWRECORDS+1,y sta PARAM1 lda WG_VIEWRECORDS+2,y sta PARAM2 lda WG_VIEWRECORDS+3,y sta PARAM3 pla ; Draw outline cmp #VIEW_STYLE_FANCY beq WGPaintView_decorated jsr WGStrokeRect cmp #VIEW_STYLE_CHECK beq WGPaintView_check cmp #VIEW_STYLE_BUTTON beq WGPaintView_button bra WGPaintView_done WGPaintView_decorated: jsr WGFancyRect jsr paintWindowTitle bra WGPaintView_done WGPaintView_check: jsr paintCheck bra WGPaintView_done WGPaintView_button: jsr paintButton WGPaintView_done: RESTORE_ZPP RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; paintCheck ; Paints the contents of a checkbox ; Y: Index into view records of checkbox to paint ; Side effects: Clobbers all registers,P0,P1 paintCheck: lda WG_VIEWRECORDS+0,y ; Position cursor sta WG_CURSORX lda WG_VIEWRECORDS+1,y sta WG_CURSORY lda WG_VIEWRECORDS+9,y ; Determine our visual state and #$80 bne paintCheck_selected lda WG_VIEWRECORDS+9,y and #$01 beq paintCheck_unselectedUnchecked lda #'D' bra paintCheck_plot paintCheck_unselectedUnchecked: lda #' '+$80 bra paintCheck_plot paintCheck_selected: lda WG_VIEWRECORDS+9,y and #$01 beq paintCheck_selectedUnchecked lda #'E' bra paintCheck_plot paintCheck_selectedUnchecked: lda #' ' paintCheck_plot: ; Paint our state jsr WGPlot inc WG_CURSORX ; Prepare for title inc WG_CURSORX lda #CHAR_NORMAL sta INVERSE lda WG_VIEWRECORDS+12,y sta PARAM0 lda WG_VIEWRECORDS+13,y sta PARAM1 ldy #0 paintCheck_titleLoop: lda (PARAM0),y beq paintCheck_done ora #$80 jsr WGPlot inc WG_CURSORX iny bra paintCheck_titleLoop paintCheck_done: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; paintButton ; Paints the contents of a button ; Y: Index into view records of button to paint ; Side effects: Clobbers all registers,P0,P1,S1 paintButton: lda WG_VIEWRECORDS+12,y ; Prep the title string sta PARAM0 lda WG_VIEWRECORDS+13,y sta PARAM1 jsr WGStrLen ; Compute centering offset for title lsr sta SCRATCH1 lda WG_VIEWRECORDS+2,y lsr sec sbc SCRATCH1 sta SCRATCH1 ; Cache this for left margin rendering lda #0 ; Position and print title sta WG_LOCALCURSORX lda #0 sta WG_LOCALCURSORY jsr WGSyncGlobalCursor lda WG_VIEWRECORDS+9,y ; Is button highlighted? and #$80 bne paintButton_titleSelected lda #CHAR_NORMAL sta INVERSE lda #' '+$80 bra paintButton_titleMarginLeft paintButton_titleSelected: lda #CHAR_INVERSE sta INVERSE lda #' ' paintButton_titleMarginLeft: ldx #0 paintButton_titleMarginLeftLoop: cpx SCRATCH1 bcs paintButton_title ; Left margin finished jsr WGPlot inc WG_CURSORX inc WG_LOCALCURSORX inx jmp paintButton_titleMarginLeftLoop paintButton_title: jsr WGPrint ldx WG_VIEWRECORDS+2,y stx SCRATCH1 ; Loop until right edge of button is reached ldx WG_LOCALCURSORX paintButton_titleMarginRightLoop: cpx SCRATCH1 bcs paintButton_done ; Right margin finished jsr WGPlot inc WG_CURSORX inc WG_LOCALCURSORX inx jmp paintButton_titleMarginRightLoop paintButton_done: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; paintWindowTitle ; Paints the title of a fancy window ; Y: Index into view records of view title to paint ; Side effects: Clobbers all registers,P0,P1,S1 paintWindowTitle: lda WG_VIEWRECORDS+12,y ; Prep the title string sta PARAM0 lda WG_VIEWRECORDS+13,y sta PARAM1 bne paintWindowTitle_compute paintWindowTitle_checkNull: lda PARAM0 beq paintWindowTitle_done paintWindowTitle_compute: jsr WGStrLen ; Compute centering offset for title lsr sta SCRATCH1 lda WG_VIEWRECORDS+2,y lsr sec sbc SCRATCH1 sta WG_LOCALCURSORX ; Position cursor lda #-1 sta WG_LOCALCURSORY jsr WGSyncGlobalCursor ldy #0 paintWindowTitleLoop: lda (PARAM0),y beq paintWindowTitle_done ora #%10000000 jsr WGPlot ; Draw the character iny inc WG_CURSORX ; Advance cursors bra paintWindowTitleLoop paintWindowTitle_done: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGEraseViewContents ; Erases the contents of the current view (interior contents only) ; WGEraseViewContents: SAVE_AY SAVE_ZPP LDY_ACTIVEVIEW lda WG_VIEWRECORDS,y ; Fetch the record sta PARAM0 iny lda WG_VIEWRECORDS,y sta PARAM1 iny lda WG_VIEWRECORDS,y sta PARAM2 iny lda WG_VIEWRECORDS,y sta PARAM3 ldy #' '+$80 jsr WGFillRect WGEraseViewContents_done: RESTORE_ZPP RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGSelectView ; Selects the active view ; A: ID ; WGSelectView: sta WG_ACTIVEVIEW ; Initialize cursor to local origin stz WG_LOCALCURSORX stz WG_LOCALCURSORY jsr cacheClipPlanes ; View changed, so clipping cache is stale WGSelectView_done: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFocus ; Shifts focus to the selected view ; Side effects: Changes selected view, repaints some views ; WGViewFocus: SAVE_AY lda WG_ACTIVEVIEW ; Stash current selection pha jsr unfocusCurrent pla sta WG_FOCUSVIEW ; Focus on our current selection jsr focusCurrent RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewUnfocus ; Unfocuses all views ; Side effects: Changes selected view, repaints some views ; WGViewUnfocus: pha jsr unfocusCurrent lda #$ff sta WG_FOCUSVIEW WGViewUnfocus_done: pla rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFocusNext ; Shifts focus to the next view ; Side effects: Changes selected view, repaints some views ; WGViewFocusNext: SAVE_AY jsr unfocusCurrent WGViewFocusNext_loop: inc WG_FOCUSVIEW ; Increment and wrap LDY_FOCUSVIEW lda WG_VIEWRECORDS+2,y bne WGViewFocusNext_wantFocus lda #0 sta WG_FOCUSVIEW WGViewFocusNext_wantFocus: ; Does this view accept focus? LDY_FOCUSVIEW lda WG_VIEWRECORDS+4,y and #$f ; Mask off flag bits cmp #VIEW_STYLE_TAKESFOCUS bcc WGViewFocusNext_loop WGViewFocusNext_focus: jsr focusCurrent RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFocusPrev ; Shifts focus to the prev view ; Side effects: Changes selected view, repaints some views ; WGViewFocusPrev: SAVE_AXY jsr unfocusCurrent WGViewFocusPrev_loop: dec WG_FOCUSVIEW ; Decrement and wrap bpl WGViewFocusPrev_wantFocus WGViewFocusPrev_hadNone: ldx #$f WGViewFocusPrev_findEndLoop: stx WG_FOCUSVIEW LDY_FOCUSVIEW lda WG_VIEWRECORDS+2,y bne WGViewFocusPrev_wantFocus dex bra WGViewFocusPrev_findEndLoop WGViewFocusPrev_wantFocus: ; Does this view accept focus? LDY_FOCUSVIEW lda WG_VIEWRECORDS+4,y and #$f ; Mask off flag bits cmp #VIEW_STYLE_TAKESFOCUS bcc WGViewFocusPrev_loop WGViewFocusPrev_focus: jsr focusCurrent RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; unfocusCurrent ; Unfocuses current view, if any ; Side effects: Clobbers A, ; Leaves Y pointed at current focus view record ; Changes active view selection unfocusCurrent: lda WG_FOCUSVIEW bmi unfocusCurrentDone ; No current focus LDY_FOCUSVIEW ; Unfocus current view lda WG_VIEWRECORDS+9,y and #%01111111 sta WG_VIEWRECORDS+9,y lda WG_FOCUSVIEW jsr WGSelectView jsr WGPaintView unfocusCurrentDone: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; focusCurrent ; Sets focus to desired view, and repaints ; Side effects: Clobbers A focusCurrent: lda WG_FOCUSVIEW jsr WGSelectView lda WG_VIEWRECORDS+9,y ora #%10000000 sta WG_VIEWRECORDS+9,y jsr WGPaintView rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFocusAction ; Performs the action of the focused view ; WG_GOSUB : Set if the caller should perform an Applesoft GOSUB ; Side effects: Changes selected view, Repaints some views ; WGViewFocusAction: SAVE_AY lda WG_FOCUSVIEW bmi WGViewFocusAction_done LDY_FOCUSVIEW lda WG_VIEWRECORDS+4,y ; What kind of view is it? and #$f ; Mask off flag bits cmp #VIEW_STYLE_CHECK beq WGViewFocusAction_toggleCheckbox cmp #VIEW_STYLE_BUTTON beq WGViewFocusAction_buttonClick bra WGViewFocusAction_done WGViewFocusAction_toggleCheckbox: lda WG_VIEWRECORDS+9,y ; Change the checkbox's state and redraw eor #%00000001 sta WG_VIEWRECORDS+9,y lda WG_FOCUSVIEW jsr WGSelectView jsr WGPaintView ; Fall through so checkboxes can have callbacks too ; NOTE: Self-modifying code ahead! WGViewFocusAction_buttonClick: lda WG_VIEWRECORDS+4,y ; Are we an Applesoft button? and #VIEW_STYLE_APPLESOFT bne WGViewFocusAction_buttonClickApplesoft lda WG_VIEWRECORDS+11,y ; Do we have a callback? beq WGViewFocusAction_done sta WGViewFocusAction_userJSR+2 ; Modify code below so we can JSR to user's code lda WG_VIEWRECORDS+10,y sta WGViewFocusAction_userJSR+1 WGViewFocusAction_userJSR: jsr WGViewFocusAction_done ; Overwritten with user's function pointer bra WGViewFocusAction_done WGViewFocusAction_buttonClickApplesoft: lda #0 sta WG_GOSUB lda WG_VIEWRECORDS+10,y ; Do we have a callback? beq WGViewFocusAction_mightBeZero WGViewFocusAction_buttonClickApplesoftNotZero: sta PARAM0 lda WG_VIEWRECORDS+11,y sta PARAM1 WGViewFocusAction_buttonClickApplesoftGosub: ; Caller needs to handle Applesoft Gosub, so signal with a flag and return lda #1 sta WG_GOSUB bra WGViewFocusAction_done WGViewFocusAction_mightBeZero: lda WG_VIEWRECORDS+11,y beq WGViewFocusAction_done lda WG_VIEWRECORDS+10,y bra WGViewFocusAction_buttonClickApplesoftNotZero WGViewFocusAction_done: RESTORE_AY WGViewFocusAction_knownRTS: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGPendingViewAction ; Performs the action of the pending view, if any ; Global flag set if the caller should perform an Applesoft GOSUB ; Side effects: Changes selected view, Repaints some views ; WGPendingViewAction: pha lda WG_PENDINGACTIONVIEW bmi WGPendingViewAction_done jsr WGUndrawPointer jsr WGSelectView jsr WGViewFocus jsr WGViewFocusAction jsr delayShort jsr WGViewUnfocus jsr WGDrawPointer ; Leave pointer hidden, but ensure jsr WGUndrawPointer ; Background is correct when it moves next lda #$ff sta WG_PENDINGACTIONVIEW WGPendingViewAction_done: pla rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGPendingView ; Returns the view that is currently pending ; OUT A : Pending view ID, or $ff if none ; WGPendingView: lda WG_PENDINGACTIONVIEW rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewSetTitle ; Sets the title of the active view ; PARAM0: Null-terminated string pointer (LSB) ; PARAM1: Null-terminated string pointer (MSB) WGViewSetTitle: SAVE_AY LDY_ACTIVEVIEW lda PARAM0 sta WG_VIEWRECORDS+12,y lda PARAM1 sta WG_VIEWRECORDS+13,y WGViewSetTitle_done: RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewSetAction ; Sets the callback action of the active view ; PARAM0: Null-terminated function pointer (LSB) ; PARAM1: Null-terminated function pointer (MSB) WGViewSetAction: SAVE_AY LDY_ACTIVEVIEW lda PARAM0 sta WG_VIEWRECORDS+10,y lda PARAM1 sta WG_VIEWRECORDS+11,y WGViewSetAction_done: RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGSetCursor ; Sets the current local view cursor ; PARAM0: X ; PARAM1: Y ; WGSetCursor: pha lda PARAM0 sta WG_LOCALCURSORX lda PARAM1 sta WG_LOCALCURSORY pla rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGSetGlobalCursor ; Sets the current global cursor ; PARAM0: X ; PARAM1: Y ; WGSetGlobalCursor: pha lda PARAM0 sta WG_CURSORX lda PARAM1 sta WG_CURSORY pla rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGSyncGlobalCursor ; Synchronizes the global cursor with the current local view's ; cursor ; WGSyncGlobalCursor: SAVE_AY LDY_ACTIVEVIEW ; Sync X clc ; Transform to viewspace lda WG_LOCALCURSORX adc WG_VIEWRECORDS+0,y clc adc WG_VIEWRECORDS+5,y ; Transform to scrollspace sta WG_CURSORX ; Sync Y clc ; Transform to viewspace lda WG_LOCALCURSORY adc WG_VIEWRECORDS+1,y clc adc WG_VIEWRECORDS+6,y ; Transform to scrollspace sta WG_CURSORY WGSyncGlobalCursor_done: RESTORE_AY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGScrollX ; Scrolls the current view horizontally ; A: New scroll amount ; Side effects: Clobbers A ; WGScrollX: phy pha LDY_ACTIVEVIEW pla sta WG_VIEWRECORDS+5,y jsr cacheClipPlanes ; Scroll offset changed, so clipping cache is stale WGScrollX_done: ply rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGScrollXBy ; Scrolls the current view horizontally by a delta ; A: Scroll delta ; Side effects: Clobbers A,S0 ; WGScrollXBy: SAVE_XY tax LDY_ACTIVEVIEW txa bpl WGScrollXBy_contentRight lda WG_VIEWRECORDS+2,y ; Compute left limit sec sbc WG_VIEWRECORDS+7,y sta SCRATCH0 txa ; Compute new scroll value clc adc WG_VIEWRECORDS+5,y cmp SCRATCH0 ; Clamp if needed bmi WGScrollXBy_clampLeft sta WG_VIEWRECORDS+5,y bra WGScrollXBy_done WGScrollXBy_clampLeft: lda SCRATCH0 sta WG_VIEWRECORDS+5,y bra WGScrollXBy_done WGScrollXBy_contentRight: clc ; Compute new scroll value adc WG_VIEWRECORDS+5,y beq @0 ; Clamp if needed bpl WGScrollXBy_clampRight @0: sta WG_VIEWRECORDS+5,y bra WGScrollXBy_done WGScrollXBy_clampRight: lda #0 sta WG_VIEWRECORDS+5,y WGScrollXBy_done: RESTORE_XY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGScrollY ; Scrolls the current view vertically ; A: New scroll amount ; Side effects: Clobbers A ; WGScrollY: phy pha LDY_ACTIVEVIEW pla sta WG_VIEWRECORDS+6,y jsr cacheClipPlanes ; Scroll offset changed, so clipping cache is stale WGScrollY_done: ply rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGScrollYBy ; Scrolls the current view horizontally by a delta ; A: Scroll delta ; Side effects: Clobbers A,S0 ; WGScrollYBy: SAVE_XY tax LDY_ACTIVEVIEW txa bpl WGScrollYBy_contentDown lda WG_VIEWRECORDS+3,y ; Compute bottom limit sec sbc WG_VIEWRECORDS+8,y sta SCRATCH0 txa ; Compute new scroll value clc adc WG_VIEWRECORDS+6,y cmp SCRATCH0 ; Clamp if needed bmi WGScrollYBy_clampTop sta WG_VIEWRECORDS+6,y bra WGScrollYBy_done WGScrollYBy_clampTop: lda SCRATCH0 sta WG_VIEWRECORDS+6,y bra WGScrollYBy_done WGScrollYBy_contentDown: clc ; Compute new scroll value adc WG_VIEWRECORDS+6,y beq @0 ; Clamp if needed bpl WGScrollYBy_clampBottom @0: sta WG_VIEWRECORDS+6,y bra WGScrollYBy_done WGScrollYBy_clampBottom: lda #0 sta WG_VIEWRECORDS+6,y WGScrollYBy_done: RESTORE_XY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewPaintAll ; Repaints all views ; Side effects: Changes selected view ; WGViewPaintAll: SAVE_AXY ldx #0 WGViewPaintAll_loop: txa jsr WGSelectView LDY_ACTIVEVIEW lda WG_VIEWRECORDS+2,y ; Last view? beq WGViewPaintAll_done jsr WGEraseViewContents jsr WGPaintView inx bra WGViewPaintAll_loop WGViewPaintAll_done: RESTORE_AXY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFromPoint ; Finds a view containing the given point ; PARAM0:X ; PARAM1:Y ; OUT A: View ID (or $ff if no match) WGViewFromPoint: SAVE_XY ldx #$f ; Scan views backwards, because controls are usually at the end WGViewFromPoint_loop: txa LDY_AVIEW lda WG_VIEWRECORDS+2,y beq WGViewFromPoint_loopNext ; Not an allocated view lda PARAM0 ; Check left edge cmp WG_VIEWRECORDS+0,y bcc WGViewFromPoint_loopNext lda PARAM1 ; Check top edge cmp WG_VIEWRECORDS+1,y bcc WGViewFromPoint_loopNext lda WG_VIEWRECORDS+0,y ; Check right edge clc adc WG_VIEWRECORDS+2,y cmp PARAM0 bcc WGViewFromPoint_loopNext beq WGViewFromPoint_loopNext lda WG_VIEWRECORDS+1,y ; Check bottom edge clc adc WG_VIEWRECORDS+3,y cmp PARAM1 bcc WGViewFromPoint_loopNext beq WGViewFromPoint_loopNext txa ; Found a match RESTORE_XY rts WGViewFromPoint_loopNext: dex bmi WGViewFromPoint_noMatch bra WGViewFromPoint_loop WGViewFromPoint_noMatch: lda #$ff RESTORE_XY rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; cacheClipPlanes ; Internal routine to cache the clipping planes for the view ; cacheClipPlanes: SAVE_AY ; Compute clip planes in view space LDY_ACTIVEVIEW lda WG_VIEWRECORDS+5,y ; Left edge eor #$ff inc sta WG_VIEWCLIP+0 clc adc WG_VIEWRECORDS+2,y ; Right edge sta WG_VIEWCLIP+2 lda WG_VIEWRECORDS+7,y ; Right span (distance from window edge to view edge, in viewspace sec sbc WG_VIEWCLIP+2 sta WG_VIEWCLIP+4 lda WG_VIEWRECORDS+6,y ; Top edge eor #$ff inc sta WG_VIEWCLIP+1 clc adc WG_VIEWRECORDS+3,y ; Bottom edge sta WG_VIEWCLIP+3 RESTORE_AY rts