Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | 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.         mov     ecx,eax                                 ; y start
  118.         shl     ecx,16                                  ; (=skin height)
  119.         or      ecx,edx                                 ; height
  120.         mov     edx,[wndColors + MOS_WNDCOLORS.work]
  121.         mov     eax,MOS_SC_DRAWBAR
  122.         int     0x40
  123.         popad
  124.  
  125.         ; calculate second hand radii
  126.         fild    dword [workwidth]
  127.         fmul    dword [SECR_FACTOR]
  128.         fstp    dword [SECRX]
  129.         fild    dword [workheight]
  130.         fmul    dword [SECR_FACTOR]
  131.         fstp    dword [SECRY]
  132.  
  133.         ; calculate minute hand radii
  134.         fild    dword [workwidth]
  135.         fmul    dword [MINR_FACTOR]
  136.         fstp    dword [MINRX]
  137.         fild    dword [workheight]
  138.         fmul    dword [MINR_FACTOR]
  139.         fstp    dword [MINRY]
  140.  
  141.         ; calculate hour hand radii
  142.         fild    dword [workwidth]
  143.         fmul    dword [HOURR_FACTOR]
  144.         fstp    dword [HOURRX]
  145.         fild    dword [workheight]
  146.         fmul    dword [HOURR_FACTOR]
  147.         fstp    dword [HOURRY]
  148.  
  149.         ; calculate tick mark radii
  150.         fild    dword [workwidth]
  151.         fmul    dword [TMR1_FACTOR]
  152.         fstp    dword [TMR1X]
  153.         fild    dword [workheight]
  154.         fmul    dword [TMR1_FACTOR]
  155.         fstp    dword [TMR1Y]
  156.         fild    dword [workwidth]
  157.         fmul    dword [TMR2_FACTOR]
  158.         fstp    dword [TMR2X]
  159.         fild    dword [workheight]
  160.         fmul    dword [TMR2_FACTOR]
  161.         fstp    dword [TMR2Y]
  162.  
  163.         ; get system clock (edx)
  164.         mov     eax,MOS_SC_GETSYSCLOCK
  165.         int     0x40
  166.         mov     edx,eax
  167.  
  168.         ; draw second hand
  169.         push    edx
  170.         mov     eax,edx
  171.         shr     eax,16
  172.         call    bcdbin
  173.         mov     ecx,eax                 ; save seconds for later
  174.         push    ecx
  175.         push    eax
  176.         fpush32 0.104719755             ; 2*pi/60
  177.         push    dword [SECRX]
  178.         push    dword [SECRY]
  179.         push    esi
  180.         push    edi
  181.         call    getHandCoords
  182.         mov     eax,MOS_SC_DRAWLINE
  183.         shl     ebx,16
  184.         or      ebx,esi
  185.         shl     ecx,16
  186.         or      ecx,edi
  187.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  188.         int     0x40
  189.         pop     ecx
  190.         pop     edx
  191.  
  192.         ; draw minute hand
  193.         push    edx
  194.         mov     eax,edx
  195.         shr     eax,8
  196.         call    bcdbin
  197.         mov     edx,60
  198.         mul     edx
  199.         add     eax,ecx
  200.         mov     ecx,eax                 ; save for later
  201.         push    ecx
  202.         push    eax
  203.         fpush32 0.001745329             ; 2*pi/60/60
  204.         push    dword [MINRX]
  205.         push    dword [MINRY]
  206.         push    esi
  207.         push    edi
  208.         call    getHandCoords
  209.         mov     eax,MOS_SC_DRAWLINE
  210.         shl     ebx,16
  211.         or      ebx,esi
  212.         shl     ecx,16
  213.         or      ecx,edi
  214.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  215.         int     0x40
  216.         pop     ecx
  217.         pop     edx
  218.  
  219.         ; draw hour hand
  220.         push    edx
  221.         mov     eax,edx
  222.         call    bcdbin
  223.         cmp     eax,11                  ; % 12 (just to be sure)
  224.         jnae    .hoursok
  225.         sub     eax,12
  226. .hoursok:
  227.         mov     edx,60*60
  228.         mul     edx
  229.         add     eax,ecx
  230.         push    eax
  231.         fpush32 0.000145444             ; 2*pi/60/60/12
  232.         push    dword [HOURRX]
  233.         push    dword [HOURRY]
  234.         push    esi
  235.         push    edi
  236.         call    getHandCoords
  237.         mov     eax,MOS_SC_DRAWLINE
  238.         shl     ebx,16
  239.         or      ebx,esi
  240.         shl     ecx,16
  241.         or      ecx,edi
  242.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  243.         int     0x40
  244.         pop     edx
  245.        
  246.         ; draw tick marks
  247.         mov     dword [i],11            ; draw 12 marks
  248. .drawtickmarks:
  249.         push    dword [i]               ; calculate start point
  250.         fpush32 0.523598776             ; 2*pi/12
  251.         push    dword [TMR1X]
  252.         push    dword [TMR1Y]
  253.         push    esi
  254.         push    edi
  255.         call    getHandCoords
  256.         mov     eax,ebx                 ; save in eax and edx
  257.         mov     edx,ecx
  258.         push    dword [i]
  259.         fpush32 0.523598776             ; 2*pi/12
  260.         push    dword [TMR2X]
  261.         push    dword [TMR2Y]
  262.         push    esi
  263.         push    edi
  264.         call    getHandCoords
  265.         shl     eax,16
  266.         shl     edx,16
  267.         or      ebx,eax                 ; ebx = x start and end
  268.         or      ecx,edx                 ; ecx = y start and end
  269.         mov     edx,[wndColors + MOS_WNDCOLORS.workText]
  270.         mov     eax,MOS_SC_DRAWLINE
  271.         int     0x40
  272.         dec     dword [i]
  273.         jns     .drawtickmarks
  274.  
  275.         %define DATE_WIDTH      48
  276.  
  277.         ; calculate text start position
  278.         mov     eax,[procInfo+MOS_PROCESSINFO.wndWidth]
  279.         sub     eax,DATE_WIDTH          ; x = (wndwidth-textwidth)/2
  280.         shr     eax,1                   ; eax = x
  281.         fild    dword [workheight]      ; y = DATE_FACTOR*workheight...
  282.         fmul    dword [DATE_FACTOR]
  283.         mov     [foo],edi               ; ... + y_clockcenter
  284.         fiadd   dword [foo]
  285.         fistp   dword [foo]
  286.         mov     ebx,[foo]               ; ebx = y
  287.  
  288.         ; draw text at all ?
  289.         cmp     dword [workwidth],DATE_WIDTH    ; text too wide ?
  290.         jb      .goodbye
  291.         mov     ecx,ebx                         ; text too high ?
  292.         add     ecx,10-1
  293.         mov     edx,[procInfo+MOS_PROCESSINFO.wndHeight]
  294.         sub     edx,MOS_WND_SKIN_BORDER_BOTTOM
  295.         cmp     ecx,edx
  296.         jnae    .yousuck
  297. .goodbye:
  298.         jmp     .bye
  299. .yousuck:
  300.  
  301.  
  302.         ; ebx = (x << 16) | y
  303.         shl     eax,16
  304.         or      ebx,eax
  305.        
  306.         ; get date (edi)
  307.         mov     eax,MOS_SC_GETDATE
  308.         int     0x40
  309.         mov     edi,eax
  310.  
  311.         ; display month
  312.         mov     eax,edi                 ; get month
  313.         shr     eax,8
  314.         call    bcdbin
  315.                                         ; ebx contains already position
  316.         mov     ecx,[wndColors+MOS_WNDCOLORS.workText]
  317.         lea     edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
  318.         mov     esi,3                   ; text length
  319.         mov     eax,MOS_SC_WRITETEXT
  320.         int     0x40
  321.  
  322.         ; display date
  323.         add     ebx,MOS_DWORD(3*6+3,0)
  324.         mov     eax,edi                 ; get date
  325.         shr     eax,16
  326.         call    bcdbin
  327.         mov     edx,ebx                 ; position must be in edx
  328.         mov     ebx,0x00020000          ; number, display two digits
  329.         mov     ecx,eax                 ; number to display
  330.         mov     esi,[wndColors+MOS_WNDCOLORS.workText]
  331.         mov     eax,MOS_SC_WRITENUMBER
  332.         int     0x40
  333.  
  334.         ; display year. the way we avoid the y2k bug is even
  335.         ; simpler, yet much better than in the last version:
  336.         ; now we simply display the last two digits and let the
  337.         ; user decide wether it's the year 1903 or 2003 =]
  338.         add     edx,MOS_DWORD(2*6+3,0)
  339.         mov     eax,edi                 ; get year
  340.         call    bcdbin
  341.         mov     ebx,0x00020000          ; number, display two digits
  342.         mov     ecx,eax                 ; number to display
  343.                                         ; edx contains already position
  344.         mov     esi,[wndColors+MOS_WNDCOLORS.workText]
  345.         mov     eax,MOS_SC_WRITENUMBER
  346.         int     0x40
  347.  
  348. .byebye:
  349.         popfd
  350.         popad
  351.         leave
  352.         ret
  353.         %pop
  354.  
  355.  
  356. ;**********************************************************
  357. ; bcdbin
  358. ; converts a 8 bit bcd number into a 32 bit binary number
  359. ;
  360. ; in            al = 8 bit bcd number
  361. ; out           eax = 32 bit binary number
  362. ; destroys      dl,flags
  363. ;**********************************************************
  364. bcdbin:
  365.         push    edx
  366.         pushfd
  367.         mov     dl,al                   ; save bcd number
  368.         shr     al,4                    ; convert upper nibble
  369.         mov     ah,10
  370.         mul     ah
  371.         and     dl,15                   ; add lower nibble
  372.         add     al,dl
  373.         and     eax,255                 ; !
  374.         popfd
  375.         pop     edx
  376.         ret
  377.  
  378.  
  379. ;********************************************************************
  380. ; getHandCoords
  381. ; calculates the end point of a hand
  382. ;
  383. ; input (on stack, push from top to bottom):
  384. ; ANGLE         angle (integer)
  385. ; DEG2RAD       conversion factor for ANGLE (32 bit real)
  386. ; RADIUSX       x radius (32 bit real)
  387. ; RADIUSY       y radius (32 bit real)
  388. ; CENTERX       x center of the clock (integer)
  389. ; CENTERY       y center of the clock (integer)
  390. ;
  391. ; output:
  392. ; ebx           x coordinate in bits 0..15, bits 16..31 are zero
  393. ; ecx           y coordinate in bits 0..15, bits 16..31 are zero
  394. ;
  395. ; destroys:
  396. ; nothing
  397. ;********************************************************************
  398. getHandCoords:
  399.  
  400. ANGLE   equ     28
  401. DEG2RAD equ     24
  402. RADIUSX equ     20
  403. RADIUSY equ     16
  404. CENTERX equ     12
  405. CENTERY equ     8
  406.  
  407.         enter   0,0
  408.         pushfd
  409.  
  410.         fild dword [ebp+ANGLE]          ; get angle
  411.         fmul dword [ebp+DEG2RAD]        ; convert to radians
  412.         fsincos
  413.         fmul dword [ebp+RADIUSY]        ; -y * radius + clockcy
  414.         fchs
  415.         fiadd dword [ebp+CENTERY]
  416.         fistp dword [ebp+CENTERY]      
  417.         fmul dword [ebp+RADIUSX]        ; x * radius + clockcx
  418.         fiadd dword [ebp+CENTERX]
  419.         fistp dword [ebp+CENTERX]
  420.        
  421.         mov ebx,[ebp+CENTERX]
  422.         mov ecx,[ebp+CENTERY]
  423.  
  424.         popfd
  425.         leave
  426.         ret     4*6
  427.  
  428.  
  429. %endif
  430.  
  431.