comparison src/tft_outputs.asm @ 250:20e3bad0b0f2

Graphical compass from kovacs
author heinrichsweikamp
date Wed, 18 Mar 2015 16:42:49 +0100
parents 94bf757690cf
children 3fec179a6220
comparison
equal deleted inserted replaced
249:94bf757690cf 250:20e3bad0b0f2
1427 STRCPY_TEXT_PRINT tHeading ; Heading: 1427 STRCPY_TEXT_PRINT tHeading ; Heading:
1428 return 1428 return
1429 1429
1430 global TFT_dive_compass_mask 1430 global TFT_dive_compass_mask
1431 TFT_dive_compass_mask: 1431 TFT_dive_compass_mask:
1432 WIN_TINY dive_compass_mask_column,dive_compass_mask_row 1432 WIN_FRAME_STD dive_compass_graph_row, dive_compass_graph_row+dive_compass_graph_height, .0, .159
1433 call TFT_divemask_color
1434 STRCPY_TEXT_PRINT tHeading ; Heading:
1435 return 1433 return
1436 1434
1437 global TFT_surface_compass_heading 1435 global TFT_surface_compass_heading
1438 TFT_surface_compass_heading: 1436 TFT_surface_compass_heading:
1439 rcall compass_heading_common 1437 rcall compass_heading_common
1494 return 1492 return
1495 1493
1496 global TFT_dive_compass_heading 1494 global TFT_dive_compass_heading
1497 TFT_dive_compass_heading: 1495 TFT_dive_compass_heading:
1498 rcall compass_heading_common 1496 rcall compass_heading_common
1497
1498 movff compass_heading_shown+0,xA+0
1499 movff compass_heading_shown+1,xA+1
1500
1501 ; 1. 160°: +360 offset for non-negative scale
1502 movlw high(d'360')
1503 addwf xA+1,1
1504 movlw low(d'360')
1505 addwf xA+0,1
1506 btfsc STATUS,C
1507 incf xA+1
1508 ; 2. -80: left pixel offset from the center
1509 movlw low( d'80' )
1510 subwf xA+0,1
1511 btfss STATUS,C
1512 decf xA+1
1513 ; 3. save it to RD
1514 movff xA+0,xRD+0
1515 movff xA+1,xRD+1
1516
1517 ; calculate mod15 for the ticks
1518 movlw d'15'
1519 movwf xB+0
1520 clrf xB+1
1521 call div16x16 ;xA/xB=xC with xA+0 as remainder
1522 ; check xA+0, it has the remainder
1523 movlw d'0'
1524 cpfsgt xA+0 ; mod15 > 0
1525 bra TFT_dive_compass_ruler ; no, RM = 0
1526 ; yes RM = 15 - RDmod15
1527 movlw d'15'
1528 subfwb xA+0,1
1529 TFT_dive_compass_ruler:
1530 ; xA+0 holds the RM, store it to 'lo'
1531 movff xA+0,lo
1532 ; init DD to zero, store it to 'hi'
1533 movlw d'0'
1534 movff WREG,hi
1535
1536 TFT_dive_compass_ruler_loop:
1537 ; 1. check if we run of from the display
1538 movlw d'160' ; Looks like 160 works because TFT_box limits the dispay
1539 cpfslt lo,1
1540 bra TFT_dive_compass_ruler_lend ; xRM >= W
1541 ; 2. Clear the tick area from DD to RM - in segments to avoid blinking
1542 ; don't do a clear if we are at 0 (zero) otherwise it will blink
1543 ; because of the width underflow
1544 movlw d'0'
1545 cpfsgt lo,1
1546 bra TFT_dive_compass_ruler_loop_zz
1547 call TFT_dive_compass_clr_ruler
1548 TFT_dive_compass_ruler_loop_zz:
1549 ; 3. Draw the markers @ RM
1550 call TFT_dive_compass_ruler_print
1551 ; 4. If D<82 and RM>79: means we put something over the center line
1552 ; redraw the center line
1553 movlw d'82'
1554 cpfslt hi,1
1555 bra TFT_dive_compass_ruler_loop_zz2
1556 movlw d'79'
1557 cpfsgt lo,1
1558 bra TFT_dive_compass_ruler_loop_zz2
1559 call TFT_dive_compass_c_mk
1560 TFT_dive_compass_ruler_loop_zz2:
1561 ; 5. set D = RM + 2 : position after the 2px tick
1562 movff lo,hi
1563 movlw d'2'
1564 addwf hi,1
1565 ; 6. set RM = RM + 15 : position to the next tick
1566 movlw d'15'
1567 addwf lo,1
1568 ; 7. loop
1569 bra TFT_dive_compass_ruler_loop
1570
1571 TFT_dive_compass_ruler_lend: ; loop end
1572 ; 8. clear the rest of the tick area if D<160
1573 movlw d'160'
1574 cpfslt hi,1
1575 bra TFT_dive_compass_ruler_lend2 ; D >= W
1576 ; 9. position left to end of display to clear the remaining area
1577 movlw d'160'
1578 movwf lo
1579 ; 10. clear it
1580 call TFT_dive_compass_clr_ruler
1581
1582 TFT_dive_compass_ruler_lend2:
1583 ; done with the compass ruler, put the labels on the screen
1584 ; get the RD abck to sub_b
1585 movff xRD+0,sub_b+0
1586 movff xRD+1,sub_b+1
1587 ; hi stores the display position
1588 movlw d'0'
1589 movwf hi
1590 ; lo stores the last item's display position
1591 movlw d'0'
1592 movwf lo
1593 bcf print_compass_label
1594
1595 movlw d'14'
1596 movwf up ; up stores the width of hte label
1597 movlw low( d'309' ) ; position of the label
1598 movwf sub_a+0
1599 movlw high( d'309' )
1600 movwf sub_a+1
1601 call TFT_dive_compass_label_proc ; check if the label should be on screen
1602 btfsc print_compass_label ; Yes?
1603 STRCPY_PRINT "NW" ; yes - print it
1604 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1605
1606 movlw d'6'
1607 movwf up ; up stores the width of hte label
1608 movlw low( d'358' ) ; position of the label
1609 movwf sub_a+0
1610 movlw high( d'358' )
1611 movwf sub_a+1
1612 call TFT_dive_compass_label_proc ; check if the label should be on screen
1613 btfsc print_compass_label ; Yes?
1614 STRCPY_PRINT "N" ; yes - print it
1615 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1616
1617 movlw d'13'
1618 movwf up ; up stores the width of hte label
1619 movlw low( d'399' ) ; position of the label
1620 movwf sub_a+0
1621 movlw high( d'399' )
1622 movwf sub_a+1
1623 call TFT_dive_compass_label_proc ; check if the label should be on screen
1624 btfsc print_compass_label ; Yes?
1625 STRCPY_PRINT "NE" ; yes - print it
1626 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1627
1628 movlw d'6'
1629 movwf up ; up stores the width of hte label
1630 movlw low( d'448' ) ; position of the label
1631 movwf sub_a+0
1632 movlw high( d'448' )
1633 movwf sub_a+1
1634 call TFT_dive_compass_label_proc ; check if the label should be on screen
1635 btfsc print_compass_label ; Yes?
1636 STRCPY_PRINT "E" ; yes - print it
1637 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1638
1639 movlw d'13'
1640 movwf up ; up stores the width of hte label
1641 movlw low( d'489' ) ; position of the label
1642 movwf sub_a+0
1643 movlw high( d'489' )
1644 movwf sub_a+1
1645 call TFT_dive_compass_label_proc ; check if the label should be on screen
1646 btfsc print_compass_label ; Yes?
1647 STRCPY_PRINT "SE" ; yes - print it
1648 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1649
1650 movlw d'6'
1651 movwf up ; up stores the width of hte label
1652 movlw low( d'538' ) ; position of the label
1653 movwf sub_a+0
1654 movlw high( d'538' )
1655 movwf sub_a+1
1656 call TFT_dive_compass_label_proc ; check if the label should be on screen
1657 btfsc print_compass_label ; Yes?
1658 STRCPY_PRINT "S" ; yes - print it
1659 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1660
1661 movlw d'14'
1662 movwf up ; up stores the width of hte label
1663 movlw low( d'579' ) ; position of the label
1664 movwf sub_a+0
1665 movlw high( d'579' )
1666 movwf sub_a+1
1667 call TFT_dive_compass_label_proc ; check if the label should be on screen
1668 btfsc print_compass_label ; Yes?
1669 STRCPY_PRINT "SW" ; yes - print it
1670 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1671
1672 movlw d'7'
1673 movwf up ; up stores the width of hte label
1674 movlw low( d'627' ) ; position of the label
1675 movwf sub_a+0
1676 movlw high( d'627' )
1677 movwf sub_a+1
1678 call TFT_dive_compass_label_proc ; check if the label should be on screen
1679 btfsc print_compass_label ; Yes?
1680 STRCPY_PRINT "W" ; yes - print it
1681 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1682
1683 movlw d'14'
1684 movwf up ; up stores the width of hte label
1685 movlw low( d'669' ) ; position of the label
1686 movwf sub_a+0
1687 movlw high( d'669' )
1688 movwf sub_a+1
1689 call TFT_dive_compass_label_proc ; check if the label should be on screen
1690 btfsc print_compass_label ; Yes?
1691 STRCPY_PRINT "NW" ; yes - print it
1692 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1693
1694 movlw d'6'
1695 movwf up ; up stores the width of hte label
1696 movlw low( d'718' ) ; position of the label
1697 movwf sub_a+0
1698 movlw high( d'718' )
1699 movwf sub_a+1
1700 call TFT_dive_compass_label_proc ; check if the label should be on screen
1701 btfsc print_compass_label ; Yes?
1702 STRCPY_PRINT "N" ; yes - print it
1703 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1704
1705 movlw d'13'
1706 movwf up ; up stores the width of hte label
1707 movlw low( d'759' ) ; position of the label
1708 movwf sub_a+0
1709 movlw high( d'759' )
1710 movwf sub_a+1
1711 call TFT_dive_compass_label_proc ; check if the label should be on screen
1712 btfsc print_compass_label ; Yes?
1713 STRCPY_PRINT "NE" ; yes - print it
1714 call TFT_dive_compass_c_mk ; check if label is on the center line or the marker
1715
1716 TFT_dive_compass_label_end:
1717 ; restore lo and hi for the final cleanup
1718 movff xLO,lo
1719 movff xHI,hi
1720 ; clear the rest of the SQ area if there are more space
1721 movlw d'160'
1722 cpfslt hi
1723 bra TFT_dive_compass_label_end2 ; D >= 160, no more space
1724 ; position left to end of display to clear the remaining area
1725 movlw d'160'
1726 movff WREG,lo
1727 ; clear it
1728 call TFT_dive_compass_clr_label
1729 call TFT_dive_compass_c_mk ; this is not required until marker implemented...
1730 TFT_dive_compass_label_end2:
1731 clrf WREG
1732 ;TFT_dive_compass_text:
1499 ; Text output 1733 ; Text output
1500 WIN_STD dive_compass_head_column,dive_compass_head_row 1734 WIN_SMALL dive_compass_head_column,dive_compass_head_row
1501 call TFT_standard_color 1735 call TFT_standard_color
1502 rcall TFT_surface_compass_heading_com ; Show "000° N" 1736 rcall TFT_surface_compass_heading_com ; Show "000° N"
1503 return ; No graphical output (yet) 1737 return
1738
1739 TFT_dive_compass_label_proc:
1740 ; Input:
1741 ; hi: DD - display current position
1742 ; sub_b: RD - ruler display offset
1743 ; sub_a: RP - item's ruler display offset
1744 ; get the RD abck to sub_b
1745 movff xRD+0,sub_b+0
1746 movff xRD+1,sub_b+1
1747 movff xHI,hi
1748 bcf print_compass_label
1749 ; 1/a. check if it's viewable ? sub_a(RP) >= sub_b(RD) ?
1750 ; set the carry flag if sub_b(xRD) is equal to or greater than sub_a(xRP):
1751 call subU16 ; sub_c = sub_a - sub_b
1752 btfsc neg_flag ; >=0?
1753 return ; No
1754 ; store the RO=RP-RD for drawing
1755 movff sub_c+0,xC+0
1756 movff sub_c+1,xC+1
1757
1758 ; 1/b. check if it's viewable ? sub_a(RP)+up(width) < sub_b(RD)+160
1759 ; if already above, no need to process the rest of the labels
1760 ;movff up,WREG ; don't worry about the width, low level call prevents overload
1761 movlw d'2' ; .. but still avoid thin mess on the side of the display
1762 addwf sub_a+0,1
1763 btfsc STATUS, C
1764 incf sub_a+1
1765
1766 movlw d'160'
1767 addwf sub_b+0,1
1768 btfsc STATUS, C
1769 incf sub_b+1
1770 call subU16 ; sub_c = sub_a - sub_b
1771 btfss neg_flag ; ? <0
1772 bra TFT_dive_compass_label_end ; No
1773 ;return ; instead of simple return go tho the end and
1774 ; skip the rest of the labels to speed up the process
1775
1776 ; 2. restore RO=RP-RD from 1/a.
1777 movff xC+0,lo
1778
1779 ; 3. Clear the segment from DD(hi) to lo
1780 ; don't do a clear if we are at 0 (zero) otherwise it will blink
1781 ; ?because of the width underflow?
1782 movlw d'0'
1783 cpfsgt lo
1784 bra TFT_dive_compass_label_proc_p
1785 call TFT_dive_compass_clr_label
1786 TFT_dive_compass_label_proc_p:
1787 ; 4. print the SQ on the screen
1788 call TFT_standard_color
1789 bsf print_compass_label
1790 call TFT_dive_compass_label_print
1791 ; 6. retain the new display positions
1792 movff hi,divB ; old-hi will be used by the c_mk : clear+marker printing
1793 movff lo,hi
1794 movff up,WREG
1795 addwf hi,1
1796 movff lo,xLO
1797 movff hi,xHI
1798 return
1799
1800 TFT_dive_compass_label_print:
1801 movlw dive_compass_label_row
1802 movff WREG,win_top
1803 movff lo,win_leftx2
1804 movlw FT_SMALL
1805 movff WREG,win_font
1806 return
1807
1808 TFT_dive_compass_c_mk:
1809 ; Common task to draw center line and marker
1810 ; until a proper implementation make it simple:
1811 call TFT_dive_compass_cline
1812 return
1813
1814 TFT_dive_compass_clr_label:
1815 movlw dive_compass_label_row-.2 ; set top & height
1816 movff WREG,win_top
1817 movlw dive_compass_label_height+.2
1818 movff WREG,win_height
1819 call TFT_dive_compass_clear
1820 return
1821
1822 TFT_dive_compass_clr_ruler:
1823 ; top tick
1824 movlw dive_compass_tick_top_top ; set top & height
1825 movff WREG,win_top
1826 movlw dive_compass_tick_height
1827 movff WREG,win_height
1828 call TFT_dive_compass_clear
1829 ;bottom tick
1830 movlw dive_compass_tick_bot_top ; set top & height
1831 movff WREG,win_top
1832 movlw dive_compass_tick_height
1833 movff WREG,win_height
1834 call TFT_dive_compass_clear
1835 return
1836
1837 TFT_dive_compass_clear:
1838 ; we receive RM in lo and DD in hi
1839 ; calculate width = RM-D
1840 movff hi,WREG
1841 subwf lo,0
1842 movff WREG,win_width ; RM-DD
1843 movff WREG,win_bargraph
1844 movff hi,win_leftx2
1845 movlw color_black
1846 call TFT_set_color
1847 call TFT_box
1848 return
1849
1850 TFT_dive_compass_ruler_print:
1851 ; we receive RM in lo and DD in hi
1852 movlw dive_compass_tick_top_top
1853 movff WREG,win_top
1854 movlw dive_compass_tick_height
1855 movff WREG,win_height
1856 movlw d'2'
1857 movff WREG,win_width
1858 movlw d'2'
1859 movff WREG,win_bargraph
1860 movff lo,win_leftx2 ; 0..159
1861 call TFT_standard_color
1862 call TFT_box
1863 movlw dive_compass_tick_bot_top
1864 movff WREG,win_top
1865 movlw dive_compass_tick_height
1866 movff WREG,win_height
1867 call TFT_standard_color
1868 call TFT_box
1869 return
1870
1871 TFT_dive_compass_cline:
1872 movlw color_yellow
1873 WIN_BOX_COLOR dive_compass_tick_top_top,dive_compass_tick_bot_bot,.80,.81
1874 return
1504 1875
1505 tft_compass_cardinal: 1876 tft_compass_cardinal:
1506 btfsc hi,0 ; Heading >255°? 1877 btfsc hi,0 ; Heading >255°?
1507 bra tft_compass_cardinal2 ; Yes must be W, NW or N 1878 bra tft_compass_cardinal2 ; Yes must be W, NW or N
1508 ; No, Must be W, SW, S, SE, E, NE or N 1879 ; No, Must be W, SW, S, SE, E, NE or N