Mercurial > public > hwos_code
changeset 250:20e3bad0b0f2
Graphical compass from kovacs
author | heinrichsweikamp |
---|---|
date | Wed, 18 Mar 2015 16:42:49 +0100 |
parents | 94bf757690cf |
children | 3fec179a6220 |
files | src/divemode.inc src/ostc3.inc src/tft_outputs.asm |
diffstat | 3 files changed, 398 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/divemode.inc Tue Mar 17 12:16:15 2015 +0100 +++ b/src/divemode.inc Wed Mar 18 16:42:49 2015 +0100 @@ -207,13 +207,17 @@ #DEFINE dive_compass_mask_row decoplan_title_row #DEFINE dive_compass_mask_column decoplan_title_column -#DEFINE dive_compass_head_column .57 -#DEFINE dive_compass_head_row divemode_customview_row+.30 +#DEFINE dive_compass_head_column .62 +#DEFINE dive_compass_head_row divemode_customview_row+.39 + +#DEFINE dive_compass_graph_row .101 +#DEFINE dive_compass_graph_height .33 -#DEFINE dive_compass_graph_row .102 -#DEFINE dive_compass_graph_height .23 -#DEFINE dive_compass_graph_width .2 -#DEFINE dive_compass_graph_left .5 -#DEFINE dive_compass_graph_leftx2 dive_compass_graph_left*.2 -#DEFINE dive_compass_graph_right .155 +#DEFINE dive_compass_tick_height .3 +#DEFINE dive_compass_tick_top_top .102 +#DEFINE dive_compass_tick_top_bot .105 +#DEFINE dive_compass_label_row .107 +#DEFINE dive_compass_label_height .24 +#DEFINE dive_compass_tick_bot_top .131 +#DEFINE dive_compass_tick_bot_bot .134
--- a/src/ostc3.inc Tue Mar 17 12:16:15 2015 +0100 +++ b/src/ostc3.inc Wed Mar 18 16:42:49 2015 +0100 @@ -660,6 +660,15 @@ #DEFINE voting_logic_sensor3 flag11,5; =1: This sensor is within the voting logic threshold #DEFINE cc_active flag11,6; =1: Constant Current active (cR Hardware) #DEFINE cv_active flag11,7; =1: Constant Voltage active (cR Hardware) + +flag12 res 1 +#DEFINE print_compass_label flag12,0 ; print the grpahical comapss label + +;---- Data for graphical compass +xRD res 2 ; virtual compass ruler offset +xLO res 1 ; lo backup to prevent trashing +xHI res 1 ; hi backup to prevent trashing + ;============================================================================= ; C-code Routines ; PART 2
--- a/src/tft_outputs.asm Tue Mar 17 12:16:15 2015 +0100 +++ b/src/tft_outputs.asm Wed Mar 18 16:42:49 2015 +0100 @@ -1429,9 +1429,7 @@ global TFT_dive_compass_mask TFT_dive_compass_mask: - WIN_TINY dive_compass_mask_column,dive_compass_mask_row - call TFT_divemask_color - STRCPY_TEXT_PRINT tHeading ; Heading: + WIN_FRAME_STD dive_compass_graph_row, dive_compass_graph_row+dive_compass_graph_height, .0, .159 return global TFT_surface_compass_heading @@ -1496,11 +1494,384 @@ global TFT_dive_compass_heading TFT_dive_compass_heading: rcall compass_heading_common + + movff compass_heading_shown+0,xA+0 + movff compass_heading_shown+1,xA+1 + + ; 1. 160°: +360 offset for non-negative scale + movlw high(d'360') + addwf xA+1,1 + movlw low(d'360') + addwf xA+0,1 + btfsc STATUS,C + incf xA+1 + ; 2. -80: left pixel offset from the center + movlw low( d'80' ) + subwf xA+0,1 + btfss STATUS,C + decf xA+1 + ; 3. save it to RD + movff xA+0,xRD+0 + movff xA+1,xRD+1 + + ; calculate mod15 for the ticks + movlw d'15' + movwf xB+0 + clrf xB+1 + call div16x16 ;xA/xB=xC with xA+0 as remainder + ; check xA+0, it has the remainder + movlw d'0' + cpfsgt xA+0 ; mod15 > 0 + bra TFT_dive_compass_ruler ; no, RM = 0 + ; yes RM = 15 - RDmod15 + movlw d'15' + subfwb xA+0,1 +TFT_dive_compass_ruler: + ; xA+0 holds the RM, store it to 'lo' + movff xA+0,lo + ; init DD to zero, store it to 'hi' + movlw d'0' + movff WREG,hi + +TFT_dive_compass_ruler_loop: + ; 1. check if we run of from the display + movlw d'160' ; Looks like 160 works because TFT_box limits the dispay + cpfslt lo,1 + bra TFT_dive_compass_ruler_lend ; xRM >= W + ; 2. Clear the tick area from DD to RM - in segments to avoid blinking + ; don't do a clear if we are at 0 (zero) otherwise it will blink + ; because of the width underflow + movlw d'0' + cpfsgt lo,1 + bra TFT_dive_compass_ruler_loop_zz + call TFT_dive_compass_clr_ruler +TFT_dive_compass_ruler_loop_zz: + ; 3. Draw the markers @ RM + call TFT_dive_compass_ruler_print + ; 4. If D<82 and RM>79: means we put something over the center line + ; redraw the center line + movlw d'82' + cpfslt hi,1 + bra TFT_dive_compass_ruler_loop_zz2 + movlw d'79' + cpfsgt lo,1 + bra TFT_dive_compass_ruler_loop_zz2 + call TFT_dive_compass_c_mk +TFT_dive_compass_ruler_loop_zz2: + ; 5. set D = RM + 2 : position after the 2px tick + movff lo,hi + movlw d'2' + addwf hi,1 + ; 6. set RM = RM + 15 : position to the next tick + movlw d'15' + addwf lo,1 + ; 7. loop + bra TFT_dive_compass_ruler_loop + +TFT_dive_compass_ruler_lend: ; loop end + ; 8. clear the rest of the tick area if D<160 + movlw d'160' + cpfslt hi,1 + bra TFT_dive_compass_ruler_lend2 ; D >= W + ; 9. position left to end of display to clear the remaining area + movlw d'160' + movwf lo + ; 10. clear it + call TFT_dive_compass_clr_ruler + +TFT_dive_compass_ruler_lend2: + ; done with the compass ruler, put the labels on the screen + ; get the RD abck to sub_b + movff xRD+0,sub_b+0 + movff xRD+1,sub_b+1 + ; hi stores the display position + movlw d'0' + movwf hi + ; lo stores the last item's display position + movlw d'0' + movwf lo + bcf print_compass_label + + movlw d'14' + movwf up ; up stores the width of hte label + movlw low( d'309' ) ; position of the label + movwf sub_a+0 + movlw high( d'309' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "NW" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'6' + movwf up ; up stores the width of hte label + movlw low( d'358' ) ; position of the label + movwf sub_a+0 + movlw high( d'358' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "N" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'13' + movwf up ; up stores the width of hte label + movlw low( d'399' ) ; position of the label + movwf sub_a+0 + movlw high( d'399' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "NE" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'6' + movwf up ; up stores the width of hte label + movlw low( d'448' ) ; position of the label + movwf sub_a+0 + movlw high( d'448' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "E" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'13' + movwf up ; up stores the width of hte label + movlw low( d'489' ) ; position of the label + movwf sub_a+0 + movlw high( d'489' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "SE" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'6' + movwf up ; up stores the width of hte label + movlw low( d'538' ) ; position of the label + movwf sub_a+0 + movlw high( d'538' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "S" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'14' + movwf up ; up stores the width of hte label + movlw low( d'579' ) ; position of the label + movwf sub_a+0 + movlw high( d'579' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "SW" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'7' + movwf up ; up stores the width of hte label + movlw low( d'627' ) ; position of the label + movwf sub_a+0 + movlw high( d'627' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "W" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'14' + movwf up ; up stores the width of hte label + movlw low( d'669' ) ; position of the label + movwf sub_a+0 + movlw high( d'669' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "NW" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'6' + movwf up ; up stores the width of hte label + movlw low( d'718' ) ; position of the label + movwf sub_a+0 + movlw high( d'718' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "N" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + + movlw d'13' + movwf up ; up stores the width of hte label + movlw low( d'759' ) ; position of the label + movwf sub_a+0 + movlw high( d'759' ) + movwf sub_a+1 + call TFT_dive_compass_label_proc ; check if the label should be on screen + btfsc print_compass_label ; Yes? + STRCPY_PRINT "NE" ; yes - print it + call TFT_dive_compass_c_mk ; check if label is on the center line or the marker + +TFT_dive_compass_label_end: + ; restore lo and hi for the final cleanup + movff xLO,lo + movff xHI,hi + ; clear the rest of the SQ area if there are more space + movlw d'160' + cpfslt hi + bra TFT_dive_compass_label_end2 ; D >= 160, no more space + ; position left to end of display to clear the remaining area + movlw d'160' + movff WREG,lo + ; clear it + call TFT_dive_compass_clr_label + call TFT_dive_compass_c_mk ; this is not required until marker implemented... +TFT_dive_compass_label_end2: + clrf WREG +;TFT_dive_compass_text: ; Text output - WIN_STD dive_compass_head_column,dive_compass_head_row - call TFT_standard_color + WIN_SMALL dive_compass_head_column,dive_compass_head_row + call TFT_standard_color rcall TFT_surface_compass_heading_com ; Show "000° N" - return ; No graphical output (yet) + return + +TFT_dive_compass_label_proc: + ; Input: + ; hi: DD - display current position + ; sub_b: RD - ruler display offset + ; sub_a: RP - item's ruler display offset + ; get the RD abck to sub_b + movff xRD+0,sub_b+0 + movff xRD+1,sub_b+1 + movff xHI,hi + bcf print_compass_label + ; 1/a. check if it's viewable ? sub_a(RP) >= sub_b(RD) ? + ; set the carry flag if sub_b(xRD) is equal to or greater than sub_a(xRP): + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; >=0? + return ; No + ; store the RO=RP-RD for drawing + movff sub_c+0,xC+0 + movff sub_c+1,xC+1 + + ; 1/b. check if it's viewable ? sub_a(RP)+up(width) < sub_b(RD)+160 + ; if already above, no need to process the rest of the labels + ;movff up,WREG ; don't worry about the width, low level call prevents overload + movlw d'2' ; .. but still avoid thin mess on the side of the display + addwf sub_a+0,1 + btfsc STATUS, C + incf sub_a+1 + + movlw d'160' + addwf sub_b+0,1 + btfsc STATUS, C + incf sub_b+1 + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; ? <0 + bra TFT_dive_compass_label_end ; No + ;return ; instead of simple return go tho the end and + ; skip the rest of the labels to speed up the process + + ; 2. restore RO=RP-RD from 1/a. + movff xC+0,lo + + ; 3. Clear the segment from DD(hi) to lo + ; don't do a clear if we are at 0 (zero) otherwise it will blink + ; ?because of the width underflow? + movlw d'0' + cpfsgt lo + bra TFT_dive_compass_label_proc_p + call TFT_dive_compass_clr_label +TFT_dive_compass_label_proc_p: + ; 4. print the SQ on the screen + call TFT_standard_color + bsf print_compass_label + call TFT_dive_compass_label_print + ; 6. retain the new display positions + movff hi,divB ; old-hi will be used by the c_mk : clear+marker printing + movff lo,hi + movff up,WREG + addwf hi,1 + movff lo,xLO + movff hi,xHI + return + +TFT_dive_compass_label_print: + movlw dive_compass_label_row + movff WREG,win_top + movff lo,win_leftx2 + movlw FT_SMALL + movff WREG,win_font + return + +TFT_dive_compass_c_mk: + ; Common task to draw center line and marker + ; until a proper implementation make it simple: + call TFT_dive_compass_cline + return + +TFT_dive_compass_clr_label: + movlw dive_compass_label_row-.2 ; set top & height + movff WREG,win_top + movlw dive_compass_label_height+.2 + movff WREG,win_height + call TFT_dive_compass_clear + return + +TFT_dive_compass_clr_ruler: + ; top tick + movlw dive_compass_tick_top_top ; set top & height + movff WREG,win_top + movlw dive_compass_tick_height + movff WREG,win_height + call TFT_dive_compass_clear + ;bottom tick + movlw dive_compass_tick_bot_top ; set top & height + movff WREG,win_top + movlw dive_compass_tick_height + movff WREG,win_height + call TFT_dive_compass_clear + return + +TFT_dive_compass_clear: + ; we receive RM in lo and DD in hi + ; calculate width = RM-D + movff hi,WREG + subwf lo,0 + movff WREG,win_width ; RM-DD + movff WREG,win_bargraph + movff hi,win_leftx2 + movlw color_black + call TFT_set_color + call TFT_box + return + +TFT_dive_compass_ruler_print: + ; we receive RM in lo and DD in hi + movlw dive_compass_tick_top_top + movff WREG,win_top + movlw dive_compass_tick_height + movff WREG,win_height + movlw d'2' + movff WREG,win_width + movlw d'2' + movff WREG,win_bargraph + movff lo,win_leftx2 ; 0..159 + call TFT_standard_color + call TFT_box + movlw dive_compass_tick_bot_top + movff WREG,win_top + movlw dive_compass_tick_height + movff WREG,win_height + call TFT_standard_color + call TFT_box + return + +TFT_dive_compass_cline: + movlw color_yellow + WIN_BOX_COLOR dive_compass_tick_top_top,dive_compass_tick_bot_bot,.80,.81 + return tft_compass_cardinal: btfsc hi,0 ; Heading >255°?