home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / gchsrc31 / atarilib / fastcoun.cc < prev    next >
C/C++ Source or Header  |  1992-04-27  |  4KB  |  233 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is part of the Atari Machine Specific Library,
  4. //  and is Copyright 1992 by Warwick W. Allison.
  5. //
  6. //  You are free to copy and modify these sources, provided you acknoledge
  7. //  the origin by retaining this notice, and adhere to the conditions
  8. //  described in the file COPYING.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "FastCounter.h"
  13. #include <DoubleBuffer.h>
  14.  
  15. CounterFont::CounterFont(short Height, short Plane=0)
  16. {
  17.     height=Height;
  18.  
  19.     for (shifts=0; 1<<shifts < Height; shifts++);
  20.  
  21.     Data=new short[111<<shifts];
  22.     plane=Plane;
  23. }
  24.  
  25. CounterFont::GetImages(Screen& S,short x,short y)
  26. {
  27.     short *From=(short*)S.Location()+((x>>4)<<2)+y*80; // LOW REZ ONLY *****
  28.     int n;
  29.  
  30.     short *Blank=Data+(110<<shifts);
  31.     for (int h=0; h<height; h++) {
  32.         Blank[h]=From[h*80-4];
  33.     }
  34.  
  35.     for (n=0; n<=9; n++) {
  36.         short *D=Data+((n+100)<<shifts);
  37.         for (int h=0; h<height; h++) {
  38.             D[h]=*(From+80*h);
  39.             if (!(n&1)) D[h]>>=8;
  40.             D[h]&=0xFF;
  41.             D[h]|=Blank[h]<<8;
  42.         }
  43.         if (n&1) From+=4;
  44.     }
  45.  
  46.     for (n=0; n<=99; n++) {
  47.         short *D=Data+(n<<shifts);
  48.         short *S1=Data+((n/10+100)<<shifts);
  49.         short *S2=Data+((n%10+100)<<shifts);
  50.         for (int h=0; h<height; h++) {
  51.             D[h]=((S1[h]&0xff)<<8)|(S2[h]&0xff);
  52.         }
  53.     }
  54. }
  55.  
  56. CounterFont::Draw(short n,long Offset)
  57. {
  58.     short *At=(short*)Pages->Location()+Offset+plane;
  59.     short *D=Data+(n<<shifts);
  60.     for (int h=0; h<height; h++) {
  61.         *At=*D;
  62.         D++;
  63.         At+=80;
  64.     }
  65. }
  66.  
  67. FastCounter::FastCounter(CounterFont* F,int x,int y,unsigned v=0,short digits=6)
  68.     :    Font(F),
  69.         Size((digits>>1)+(digits&1)),
  70.         Digit(new unsigned short[Size]),
  71.         Offset(((x>>4)<<2)+y*80+(Size-1)*4)
  72. {
  73.     Changed[0]=Size;
  74.     Changed[1]=Size;
  75.     Set(v);
  76. }
  77.  
  78. FastCounter::~FastCounter()
  79. {
  80.     delete Digit;
  81. }
  82.  
  83. void FastCounter::Draw()
  84. {
  85.     long O=Offset;
  86.     short top=Changed[Pages->Pulse];
  87.  
  88.     for (int d=0; d<top; d++) {
  89.         Font->Draw(Digit[d],O);
  90.         O-=4;
  91.     }
  92.     Changed[Pages->Pulse]=0;
  93. }
  94.  
  95. void FastCounter::Add(short Carry)
  96. {
  97.     unsigned short *D=Digit;
  98.  
  99.     int Ch=0;
  100.     while (Carry && Ch<Size) {
  101.         short C;
  102.         if (LeadingZeroes || *D<100) {
  103.             C=Carry+*D;
  104.         } else {
  105.             if (*D==110)
  106.                 C=Carry;
  107.             else
  108.                 C=Carry+*D-100;
  109.         }
  110.         Carry=0;
  111.         while (C>=1000) {
  112.             C-=1000;
  113.             Carry+=10;
  114.         }
  115.         while (C>=100) {
  116.             C-=100;
  117.             Carry++;
  118.         }
  119.         *D++=C;
  120.         Ch++;
  121.     }
  122.  
  123.     Changed[0]=Changed[0] >? Ch >? Changed[1];
  124.     Changed[1]=Changed[0];
  125.  
  126.     if (!LeadingZeroes) {
  127.         while (Ch>0 && *--D<10) {
  128.             if (*D || Ch==1) {
  129.                 *D+=100;
  130.                 Ch=0;
  131.             } else {
  132.                 *D=110;
  133.             }
  134.             Ch--;
  135.         }
  136.     }
  137. }
  138.  
  139. void FastCounter::ZeroSuppression(bool on=TRUE)
  140. {
  141.     LeadingZeroes=!on;
  142.     Changed[0]=Size;
  143.     Changed[1]=Size;
  144.  
  145.     unsigned short *D=&Digit[Size-1];
  146.  
  147.     if (!LeadingZeroes) {
  148.         int Ch=Size;
  149.         while (Ch>0 && *--D<10) {
  150.             if (*D || Ch==1) {
  151.                 *D+=100;
  152.                 Ch=0;
  153.             } else {
  154.                 *D=110;
  155.             }
  156.             Ch--;
  157.         }
  158.     } else {
  159.         int Ch=Size;
  160.         while (Ch>0 && *--D>99) {
  161.             if (*D<110) {
  162.                 *D-=100;
  163.                 Ch=0;
  164.             } else {
  165.                 *D=0;
  166.             }
  167.             Ch--;
  168.         }
  169.     }
  170. }
  171.  
  172. void FastCounter::Set(unsigned Carry)
  173. {
  174.     unsigned short *D=Digit;
  175.  
  176.     for (int d=0; d<Size; d++) {
  177.         if (!LeadingZeroes && Carry<10) {
  178.             if (Carry || !d) {
  179.                 *D++=Carry%10+100;
  180.                 Carry=0;
  181.             } else {
  182.                 *D++=110;
  183.             }
  184.         } else {
  185.             *D++=Carry%100;
  186.             Carry/=100;
  187.         }
  188.     }
  189.     Changed[0]=Size;
  190.     Changed[1]=Size;
  191. }
  192.  
  193. void FastCounter::MoveTo(short x,short y)
  194. {
  195.     Offset=((x>>4)<<3)+y/80;
  196.     Changed[0]=Size;
  197.     Changed[1]=Size;
  198. }
  199.  
  200. FastCounter::operator int()
  201. {
  202.     int result=0;
  203.     for (int d=Size; d>=0; d--) {
  204.         if (LeadingZeroes || Digit[d]<100) {
  205.             result=result*100+Digit[d];
  206.         } else {
  207.             if (Digit[d]==110) {    
  208.                 result=result*100;
  209.             } else {
  210.                 result=result*100+(Digit[d]-100);
  211.             }
  212.         }
  213.     }
  214.     return result;
  215. }
  216.  
  217. FastCounter::operator double()
  218. {
  219.     double result=0.0;
  220.     for (int d=Size; d>=0; d--) {
  221.         if (LeadingZeroes || Digit[d]<100) {
  222.             result=result*100.0+(double)Digit[d];
  223.         } else {
  224.             if (Digit[d]==110) {    
  225.                 result=result*100.0;
  226.             } else {
  227.                 result=result*100.0+(double)(Digit[d]-100);
  228.             }
  229.         }
  230.     }
  231.     return result;
  232. }
  233.