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 >
Wrap
C/C++ Source or Header
|
1992-04-27
|
4KB
|
233 lines
//////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Atari Machine Specific Library,
// and is Copyright 1992 by Warwick W. Allison.
//
// You are free to copy and modify these sources, provided you acknoledge
// the origin by retaining this notice, and adhere to the conditions
// described in the file COPYING.
//
//////////////////////////////////////////////////////////////////////////////
#include "FastCounter.h"
#include <DoubleBuffer.h>
CounterFont::CounterFont(short Height, short Plane=0)
{
height=Height;
for (shifts=0; 1<<shifts < Height; shifts++);
Data=new short[111<<shifts];
plane=Plane;
}
CounterFont::GetImages(Screen& S,short x,short y)
{
short *From=(short*)S.Location()+((x>>4)<<2)+y*80; // LOW REZ ONLY *****
int n;
short *Blank=Data+(110<<shifts);
for (int h=0; h<height; h++) {
Blank[h]=From[h*80-4];
}
for (n=0; n<=9; n++) {
short *D=Data+((n+100)<<shifts);
for (int h=0; h<height; h++) {
D[h]=*(From+80*h);
if (!(n&1)) D[h]>>=8;
D[h]&=0xFF;
D[h]|=Blank[h]<<8;
}
if (n&1) From+=4;
}
for (n=0; n<=99; n++) {
short *D=Data+(n<<shifts);
short *S1=Data+((n/10+100)<<shifts);
short *S2=Data+((n%10+100)<<shifts);
for (int h=0; h<height; h++) {
D[h]=((S1[h]&0xff)<<8)|(S2[h]&0xff);
}
}
}
CounterFont::Draw(short n,long Offset)
{
short *At=(short*)Pages->Location()+Offset+plane;
short *D=Data+(n<<shifts);
for (int h=0; h<height; h++) {
*At=*D;
D++;
At+=80;
}
}
FastCounter::FastCounter(CounterFont* F,int x,int y,unsigned v=0,short digits=6)
: Font(F),
Size((digits>>1)+(digits&1)),
Digit(new unsigned short[Size]),
Offset(((x>>4)<<2)+y*80+(Size-1)*4)
{
Changed[0]=Size;
Changed[1]=Size;
Set(v);
}
FastCounter::~FastCounter()
{
delete Digit;
}
void FastCounter::Draw()
{
long O=Offset;
short top=Changed[Pages->Pulse];
for (int d=0; d<top; d++) {
Font->Draw(Digit[d],O);
O-=4;
}
Changed[Pages->Pulse]=0;
}
void FastCounter::Add(short Carry)
{
unsigned short *D=Digit;
int Ch=0;
while (Carry && Ch<Size) {
short C;
if (LeadingZeroes || *D<100) {
C=Carry+*D;
} else {
if (*D==110)
C=Carry;
else
C=Carry+*D-100;
}
Carry=0;
while (C>=1000) {
C-=1000;
Carry+=10;
}
while (C>=100) {
C-=100;
Carry++;
}
*D++=C;
Ch++;
}
Changed[0]=Changed[0] >? Ch >? Changed[1];
Changed[1]=Changed[0];
if (!LeadingZeroes) {
while (Ch>0 && *--D<10) {
if (*D || Ch==1) {
*D+=100;
Ch=0;
} else {
*D=110;
}
Ch--;
}
}
}
void FastCounter::ZeroSuppression(bool on=TRUE)
{
LeadingZeroes=!on;
Changed[0]=Size;
Changed[1]=Size;
unsigned short *D=&Digit[Size-1];
if (!LeadingZeroes) {
int Ch=Size;
while (Ch>0 && *--D<10) {
if (*D || Ch==1) {
*D+=100;
Ch=0;
} else {
*D=110;
}
Ch--;
}
} else {
int Ch=Size;
while (Ch>0 && *--D>99) {
if (*D<110) {
*D-=100;
Ch=0;
} else {
*D=0;
}
Ch--;
}
}
}
void FastCounter::Set(unsigned Carry)
{
unsigned short *D=Digit;
for (int d=0; d<Size; d++) {
if (!LeadingZeroes && Carry<10) {
if (Carry || !d) {
*D++=Carry%10+100;
Carry=0;
} else {
*D++=110;
}
} else {
*D++=Carry%100;
Carry/=100;
}
}
Changed[0]=Size;
Changed[1]=Size;
}
void FastCounter::MoveTo(short x,short y)
{
Offset=((x>>4)<<3)+y/80;
Changed[0]=Size;
Changed[1]=Size;
}
FastCounter::operator int()
{
int result=0;
for (int d=Size; d>=0; d--) {
if (LeadingZeroes || Digit[d]<100) {
result=result*100+Digit[d];
} else {
if (Digit[d]==110) {
result=result*100;
} else {
result=result*100+(Digit[d]-100);
}
}
}
return result;
}
FastCounter::operator double()
{
double result=0.0;
for (int d=Size; d>=0; d--) {
if (LeadingZeroes || Digit[d]<100) {
result=result*100.0+(double)Digit[d];
} else {
if (Digit[d]==110) {
result=result*100.0;
} else {
result=result*100.0+(double)(Digit[d]-100);
}
}
}
return result;
}