Subversion Repositories Kolibri OS

Rev

Rev 109 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; drawing code for aclock
  2. ;
  3. ; Copyright (c) 2003 Thomas Mathys
  4. ; killer@vantage.ch
  5. ;
  6. ; This program is free software; you can redistribute it and/or modify
  7. ; it under the terms of the GNU General Public License as published by
  8. ; the Free Software Foundation; either version 2 of the License, or
  9. ; (at your option) any later version.
  10. ;
  11. ; This program is distributed in the hope that it will be useful,
  12. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ; GNU General Public License for more details.
  15. ;
  16. ; You should have received a copy of the GNU General Public License
  17. ; along with this program; if not, write to the Free Software
  18. ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. ;
  20. %ifndef _DRAW_INC
  21. %define _DRAW_INC
  22.  
  23.  
  24. TMR1_FACTOR     dd      0.45
  25. TMR2_FACTOR     dd      0.426315789
  26. SECR_FACTOR     dd      0.378947368
  27. MINR_FACTOR     dd      0.355263158
  28. HOURR_FACTOR    dd      0.189473684
  29. DATE_FACTOR     dd      0.1
  30.  
  31.  
  32. monthNames:
  33.                 db "Jan"
  34.                 db "Feb"
  35.                 db "Mar"
  36.                 db "Apr"
  37.                 db "May"
  38.                 db "Jun"
  39.                 db "Jul"
  40.                 db "Aug"
  41.                 db "Sep"
  42.                 db "Oct"
  43.                 db "Nov"
  44.                 db "Dec"
  45.  
  46.  
  47. ;********************************************************************
  48. ;       draws the clock
  49. ;       input           :       nothing
  50. ;       output          :       nothing
  51. ;       destroys        :       nothing
  52. ;********************************************************************
  53. drawClock:
  54.         %push   drawClock_context
  55.         %stacksize flat
  56.         %assign %$localsize 0
  57.  
  58.         %local  i:dword,                \
  59.                 TMR1X:dword,            \
  60.                 TMR1Y:dword,            \
  61.                 TMR2X:dword,            \
  62.                 TMR2Y:dword,            \
  63.                 SECRX:dword,            \
  64.                 SECRY:dword,            \
  65.                 MINRX:dword,            \
  66.                 MINRY:dword,            \
  67.                 HOURRX:dword,           \
  68.                 HOURRY:dword,           \
  69.                 workwidth:dword,        \
  70.                 workheight:dword,       \
  71.                 foo:dword
  72.        
  73.         enter   %$localsize,0
  74.         pushad
  75.         pushfd
  76.  
  77.         ; get window dimensions
  78.         mov     eax,MOS_SC_GETPROCESSINFO
  79.         mov     ebx,procInfo
  80.         mov     ecx,-1
  81.         int     0x40
  82.  
  83.         ; calculate work area size (width/height = ecx/edx)
  84.         ; if the work area is too small (maybe the window is shaded)
  85.         ; we don't draw anything.
  86.         mov     eax,MOS_SC_WINDOWPROPERTIES
  87.         mov     ebx,4                   ; get skin height (eax)
  88.         int     0x40
  89.         mov     ecx,[procInfo + MOS_PROCESSINFO.wndWidth]
  90.         sub     ecx,MOS_WND_SKIN_BORDER_LEFT+MOS_WND_SKIN_BORDER_RIGHT
  91.         mov     edx,[procInfo + MOS_PROCESSINFO.wndHeight]
  92.         sub     edx,eax
  93.         sub     edx,MOS_WND_SKIN_BORDER_BOTTOM
  94.         cmp     ecx,0                   ; width too small ?
  95.         jle     .bye
  96.         cmp     edx,0                   ; height too small ?
  97.         jnle    .continue
  98. .bye:
  99.         jmp     .byebye
  100. .continue:
  101.         mov     [workwidth],ecx         ; save for later (for fpu)
  102.         mov     [workheight],edx
  103.  
  104.         ; calculate center of clock (x/y = esi/edi)
  105.         mov     esi,[procInfo + MOS_PROCESSINFO.wndWidth]
  106.         shr     esi,1
  107.         mov     edi,[procInfo + MOS_PROCESSINFO.wndHeight]
  108.         sub     edi,MOS_WND_SKIN_BORDER_BOTTOM
  109.         sub     edi,eax
  110.         shr     edi,1
  111.         add     edi,eax
  112.  
  113.         ; clear work area
  114.         pushad
  115.         mov     ebx,(MOS_WND_SKIN_BORDER_LEFT)*0x10000  ; x start
  116.         or      ebx,ecx                                 ; width
  117.         inc     ebx
  118.         mov     ecx,eax                                 ; y start
  119.         shl     ecx,16                                  ; (=skin height)
  120.         or      ecx,edx                                 ; height
  121.         inc     ecx
  122.         mov     edx,[wndColors + MOS_WNDCOLORS.work]
  123.         mov     eax,MOS_SC_DRAWBAR
  124.         int     0x40
  125.         popad
  126.  
  127.         ; calculate second hand radii
  128.         fild    dword [workwidth]
  129.         fmul    dword [SECR_FACTOR]
  130.         fstp    dword [SECRX]
  131.         fild    dword [workheight]
  132.         fmul    dword [SECR_FACTOR]
  133.         fstp    dword [SECRY]
  134.  
  135.         ; calculate minute hand radii
  136.         fild    dword [workwidth]
  137.         fmul    dword [MINR_FACTOR]
  138.         fstp    dword [MINRX]
  139.         fild    dword [workheight]
  140.         fmul    dword [MINR_FACTOR]
  141.         fstp    dword [MINRY]
  142.  
  143.         ; calculate hour hand radii
  144.         fild    dword [workwidth]
  145.         fmul    dword [HOURR_FACTOR]
  146.         fstp    dword [HOURRX]
  147.         fild    dword [workheight]
  148.         fmul    dword [HOURR_FACTOR]
  149.         fstp    dword [HOURRY]
  150.  
  151.         ; calculate tick mark radii
  152.         fild    dword [workwidth]
  153.         fmul    dword [TMR1_FACTOR]
  154.         fstp    dword [TMR1X]
  155.         fild    dword [workheight]
  156.         fmul    dword [TMR1_FACTOR]
  157.         fstp    dword [TMR1Y]
  158.         fild    dword [workwidth]
  159.         fmul    dword [TMR2_FACTOR]
  160.         fstp    dword [TMR2X]
  161.         fild    dword [workheight]
  162.         fmul    dword [TMR2_FACTOR]
  163.         fstp    dword [TMR2Y]
  164.  
  165.         ; get system clock (edx)
  166.         mov     eax,MOS_SC_GETSYSCLOCK
  167.         int     0x40
  168.         mov     edx,eax
  169.  
  170.         ; draw second hand
  171.         push    edx
  172.         mov     eax,edx
  173.         shr     eax,16
  174.         call    bcdbin
  175.         mov     ecx,eax                 ; save seconds for later
  176.         push    ecx
  177.         push    eax
  178.         fpush32 0.104719755             ; 2*pi/60
  179.         push    dword [SECRX]
  180.         push    dword [SECRY]
  181.         push    esi
  182.         push    edi
  183.         call    getHandCoords
  184.         mov     eax,MOS_SC_DRAWLINE
  185.         shl     ebx,16
  186.         or      ebx,esi
  187.         shl     ecx,16
  188.         or      ecx,edi
  189.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  190.         int     0x40
  191.         pop     ecx
  192.         pop     edx
  193.  
  194.         ; draw minute hand
  195.         push    edx
  196.         mov     eax,edx
  197.         shr     eax,8
  198.         call    bcdbin
  199.         mov     edx,60
  200.         mul     edx
  201.         add     eax,ecx
  202.         mov     ecx,eax                 ; save for later
  203.         push    ecx
  204.         push    eax
  205.         fpush32 0.001745329             ; 2*pi/60/60
  206.         push    dword [MINRX]
  207.         push    dword [MINRY]
  208.         push    esi
  209.         push    edi
  210.         call    getHandCoords
  211.         mov     eax,MOS_SC_DRAWLINE
  212.         shl     ebx,16
  213.         or      ebx,esi
  214.         shl     ecx,16
  215.         or      ecx,edi
  216.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  217.         int     0x40
  218.         pop     ecx
  219.         pop     edx
  220.  
  221.         ; draw hour hand
  222.         push    edx
  223.         mov     eax,edx
  224.         call    bcdbin
  225.         cmp     eax,11                  ; % 12 (just to be sure)
  226.         jnae    .hoursok
  227.         sub     eax,12
  228. .hoursok:
  229.         mov     edx,60*60
  230.         mul     edx
  231.         add     eax,ecx
  232.         push    eax
  233.         fpush32 0.000145444             ; 2*pi/60/60/12
  234.         push    dword [HOURRX]
  235.         push    dword [HOURRY]
  236.         push    esi
  237.         push    edi
  238.         call    getHandCoords
  239.         mov     eax,MOS_SC_DRAWLINE
  240.         shl     ebx,16
  241.         or      ebx,esi
  242.         shl     ecx,16
  243.         or      ecx,edi
  244.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  245.         int     0x40
  246.         pop     edx
  247.        
  248.         ; draw tick marks
  249.         mov     dword [i],11            ; draw 12 marks
  250. .drawtickmarks:
  251.         push    dword [i]               ; calculate start point
  252.         fpush32 0.523598776             ; 2*pi/12
  253.         push    dword [TMR1X]
  254.         push    dword [TMR1Y]
  255.         push    esi
  256.         push    edi
  257.         call    getHandCoords
  258.         mov     eax,ebx                 ; save in eax and edx
  259.         mov     edx,ecx
  260.         push    dword [i]
  261.         fpush32 0.523598776             ; 2*pi/12
  262.         push    dword [TMR2X]
  263.         push    dword [TMR2Y]
  264.         push    esi
  265.         push    edi
  266.         call    getHandCoords
  267.         shl     eax,16
  268.         shl     edx,16
  269.         or      ebx,eax                 ; ebx = x start and end
  270.         or      ecx,edx                 ; ecx = y start and end
  271.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  272.         mov     eax,MOS_SC_DRAWLINE
  273.         int     0x40
  274.         dec     dword [i]
  275.         jns     .drawtickmarks
  276.  
  277.         %define DATE_WIDTH      48
  278.  
  279.         ; calculate text start position
  280.         mov     eax,[procInfo+MOS_PROCESSINFO.wndWidth]
  281.         sub     eax,DATE_WIDTH          ; x = (wndwidth-textwidth)/2
  282.         shr     eax,1                   ; eax = x
  283.         fild    dword [workheight]      ; y = DATE_FACTOR*workheight...
  284.         fmul    dword [DATE_FACTOR]
  285.         mov     [foo],edi               ; ... + y_clockcenter
  286.         fiadd   dword [foo]
  287.         fistp   dword [foo]
  288.         mov     ebx,[foo]               ; ebx = y
  289.  
  290.         ; draw text at all ?
  291.         cmp     dword [workwidth],DATE_WIDTH    ; text too wide ?
  292.         jb      .goodbye
  293.         mov     ecx,ebx                         ; text too high ?
  294.         add     ecx,10-1
  295.         mov     edx,[procInfo+MOS_PROCESSINFO.wndHeight]
  296.         sub     edx,MOS_WND_SKIN_BORDER_BOTTOM
  297.         cmp     ecx,edx
  298.         jnae    .yousuck
  299. .goodbye:
  300.         jmp     .bye
  301. .yousuck:
  302.  
  303.  
  304.         ; ebx = (x << 16) | y
  305.         shl     eax,16
  306.         or      ebx,eax
  307.        
  308.         ; get date (edi)
  309.         mov     eax,MOS_SC_GETDATE
  310.         int     0x40
  311.         mov     edi,eax
  312.  
  313.         ; display month
  314.         mov     eax,edi                 ; get month
  315.         shr     eax,8
  316.         call    bcdbin
  317.                                         ; ebx contains already position
  318.         mov     ecx,[wndColors+MOS_WNDCOLORS.workText]
  319.         lea     edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
  320.         mov     esi,3                   ; text length
  321.         mov     eax,MOS_SC_WRITETEXT
  322.         int     0x40
  323.  
  324.         ; display date
  325.         add     ebx,MOS_DWORD(3*6+3,0)
  326.         mov     eax,edi                 ; get date
  327.         shr     eax,16
  328.         call    bcdbin
  329.         mov     edx,ebx                 ; position must be in edx
  330.         mov     ebx,0x00020000          ; number, display two digits
  331.         mov     ecx,eax                 ; number to display
  332.         mov     esi,[wndColors+MOS_WNDCOLORS.workText]
  333.         mov     eax,MOS_SC_WRITENUMBER
  334.         int     0x40
  335.  
  336.         ; display year. the way we avoid the y2k bug is even
  337.         ; simpler, yet much better than in the last version:
  338.         ; now we simply display the last two digits and let the
  339.         ; user decide wether it's the year 1903 or 2003 =]
  340.         add     edx,MOS_DWORD(2*6+3,0)
  341.         mov     eax,edi                 ; get year
  342.         call    bcdbin
  343.         mov     ebx,0x00020000          ; number, display two digits
  344.         mov     ecx,eax                 ; number to display
  345.                                         ; edx contains already position
  346.         mov     esi,[wndColors+MOS_WNDCOLORS.workText]
  347.         mov     eax,MOS_SC_WRITENUMBER
  348.         int     0x40
  349.  
  350. .byebye:
  351.         popfd
  352.         popad
  353.         leave
  354.         ret
  355.         %pop
  356.  
  357.  
  358. ;**********************************************************
  359. ; bcdbin
  360. ; converts a 8 bit bcd number into a 32 bit binary number
  361. ;
  362. ; in            al = 8 bit bcd number
  363. ; out           eax = 32 bit binary number
  364. ; destroys      dl,flags
  365. ;**********************************************************
  366. bcdbin:
  367.         push    edx
  368.         pushfd
  369.         mov     dl,al                   ; save bcd number
  370.         shr     al,4                    ; convert upper nibble
  371.         mov     ah,10
  372.         mul     ah
  373.         and     dl,15                   ; add lower nibble
  374.         add     al,dl
  375.         and     eax,255                 ; !
  376.         popfd
  377.         pop     edx
  378.         ret
  379.  
  380.  
  381. ;********************************************************************
  382. ; getHandCoords
  383. ; calculates the end point of a hand
  384. ;
  385. ; input (on stack, push from top to bottom):
  386. ; ANGLE         angle (integer)
  387. ; DEG2RAD       conversion factor for ANGLE (32 bit real)
  388. ; RADIUSX       x radius (32 bit real)
  389. ; RADIUSY       y radius (32 bit real)
  390. ; CENTERX       x center of the clock (integer)
  391. ; CENTERY       y center of the clock (integer)
  392. ;
  393. ; output:
  394. ; ebx           x coordinate in bits 0..15, bits 16..31 are zero
  395. ; ecx           y coordinate in bits 0..15, bits 16..31 are zero
  396. ;
  397. ; destroys:
  398. ; nothing
  399. ;********************************************************************
  400. getHandCoords:
  401.  
  402. ANGLE   equ     28
  403. DEG2RAD equ     24
  404. RADIUSX equ     20
  405. RADIUSY equ     16
  406. CENTERX equ     12
  407. CENTERY equ     8
  408.  
  409.         enter   0,0
  410.         pushfd
  411.  
  412.         fild dword [ebp+ANGLE]          ; get angle
  413.         fmul dword [ebp+DEG2RAD]        ; convert to radians
  414.         fsincos
  415.         fmul dword [ebp+RADIUSY]        ; -y * radius + clockcy
  416.         fchs
  417.         fiadd dword [ebp+CENTERY]
  418.         fistp dword [ebp+CENTERY]      
  419.         fmul dword [ebp+RADIUSX]        ; x * radius + clockcx
  420.         fiadd dword [ebp+CENTERX]
  421.         fistp dword [ebp+CENTERX]
  422.        
  423.         mov ebx,[ebp+CENTERX]
  424.         mov ecx,[ebp+CENTERY]
  425.  
  426.         popfd
  427.         leave
  428.         ret     4*6
  429.  
  430.  
  431. %endif
  432.  
  433.