Added custom fonts. Added triangle drawing function

Dependents:   sc100016x4lcd REVO_Updated_Steering Driving_game Arkanoid_v1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers KS0108.cpp Source File

KS0108.cpp

00001 #include "KS0108.h"     
00002 
00003 
00004 KS0108::KS0108 (PinName _RST,PinName _DI, PinName _RW, PinName _E, PinName _CS2, PinName _CS1, PinName DB0, PinName DB1, PinName DB2, PinName DB3, PinName DB4, PinName DB5, PinName DB6, PinName DB7)
00005     : DB(DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7),RST (_RST),DI(_DI), RW(_RW), E(_E), CS2(_CS2), CS1(_CS1) {
00006    
00007     DB.output();      
00008     CS1.output(); CS2.output();    
00009     RST.write(0);
00010     wait_us(10);  
00011     RST.write(1);                         //reset screen
00012     E.write(0);                       
00013     ClearScreen();                      //clear display
00014     WriteInstruction(LCD_ON, BOTH);     //turn on lcd  
00015     Inverted = 0;     
00016 }
00017 
00018 
00019 
00020 void  KS0108::WriteInstruction(unsigned int Command,unsigned int side){
00021     E.write(0); 
00022     DI.write(0);
00023     RW.write(0);
00024         
00025     SelectSide(side);   //select controller
00026 
00027     wait(0.0000003);     //wait 300ns
00028     E.write(1);
00029     DB.output();
00030     DB.write(Command);        
00031     wait(0.0000001);
00032     E.write(0);
00033 }
00034 
00035 
00036 void  KS0108::WriteData(unsigned int data,unsigned char side){
00037     E.write(0); 
00038     DI.write(1);
00039     RW.write(0);
00040     
00041     SelectSide(side);
00042 
00043     wait(0.0000003); // 300ns
00044     E = 1;
00045     DB.output();
00046     DB.write(data);     
00047     wait(0.0000001);
00048     E = 0;
00049 }
00050 
00051 void KS0108::WriteData(unsigned int data) {
00052     unsigned int displayData, yOffset, chip;
00053     
00054     if(Coord.x >= SCREEN_WIDTH)
00055         return;
00056      chip = Coord.x/CHIP_WIDTH; 
00057      wait(0.000000450); // 300ns     
00058 
00059      if(Coord.x % CHIP_WIDTH == 0 && chip > 0){         
00060      GotoXY(Coord.x, Coord.y);
00061      }
00062 
00063     DI.write(1);                    // D/I = 1
00064     RW.write(0);                      // R/W = 0    
00065     DB.output();                    // data port is output
00066     
00067     yOffset = Coord.y%8;
00068 
00069     if(yOffset != 0) {                 // first page
00070 
00071     displayData = ReadData();
00072 
00073     DI.write(1);                            // D/I = 1
00074     RW.write(0);                              // R/W = 0    
00075     SelectSide(chip);    
00076     DB.output();
00077                                             // data port is output             
00078     displayData |= data << yOffset;
00079     if(Inverted)    displayData = ~displayData;
00080     DB.write(displayData);                     // write data
00081     wait(0.0000003);                         // 300ns
00082     E.write(1);
00083     wait(0.0000001);
00084     E.write(0);
00085         
00086                                     // second page
00087     GotoXY(Coord.x, Coord.y+8);
00088         
00089     displayData = ReadData();
00090 
00091     DI.write(1);                            // D/I = 1
00092     RW.write(0);                              // R/W = 0    
00093     SelectSide(chip);
00094 
00095     DB.output();                // data port is output
00096         
00097     displayData |= data >> (8-yOffset);
00098     
00099         if(Inverted)
00100             displayData = ~displayData;
00101             DB.write(displayData);        // write data
00102            
00103             wait(0.0000003);             // 300ns
00104             E.write(1);
00105             wait(0.0000001);
00106             E.write(0);
00107         
00108         GotoXY(Coord.x+1, Coord.y-8);
00109     }else    {
00110 
00111         // just this code gets executed if the write is on a single page
00112         if(Inverted)
00113             data = ~data;      
00114         wait(0.0000003);                 // 300nsEN_DELAY();
00115         DB.write(data);                    // write data
00116         wait(0.0000003);                 // 300ns
00117            E = 1;
00118            wait(0.0000001);
00119         E = 0;
00120         Coord.x++; 
00121     }
00122 }
00123 
00124 
00125 void KS0108::WriteDataColPag(unsigned int page, unsigned int col,  unsigned int data){
00126     
00127     SelectSide(NONE);  
00128     col     = col%SCREEN_WIDTH;
00129     page    = page%8;
00130 
00131     if(col<(SCREEN_WIDTH/2)){
00132     SelectSide(LEFT);           
00133     WriteInstruction(LCD_SET_PAGE|page,LEFT);     
00134     WriteInstruction(LCD_SET_ADD|col,LEFT);          //set page and column position
00135     WriteData(data,LEFT);                            //output data to D0-D7
00136     }else{
00137     
00138     SelectSide(RIGHT);
00139     col -= (SCREEN_WIDTH/2);     
00140     WriteInstruction(LCD_SET_PAGE|page,RIGHT);     
00141     WriteInstruction(LCD_SET_ADD|col,RIGHT);        //set page and column position
00142     WriteData(data,RIGHT);                          //output data to D0-D7
00143     }    
00144                            
00145     SelectSide(NONE);
00146 }
00147 
00148 
00149 
00150 unsigned int KS0108::ReadData(){
00151    unsigned int data;
00152    DB.input();
00153 
00154    DI.write(1);     
00155    RW.write(1);
00156 
00157    E.write(1);
00158    wait(0.00000045);
00159       
00160    data = DB.read();
00161    wait(0.0000001);
00162    E.write(0);   
00163    DB.output();
00164    
00165    return data;     
00166 }
00167 
00168 unsigned int KS0108::ReadStatus(){
00169    unsigned int status;
00170    DB.input();
00171  
00172    DI.write(0);
00173    
00174    RW.write(1);
00175    E.write(1);
00176    wait(0.00000045);
00177       
00178    status = DB.read();
00179    E.write(0);
00180    wait(0.0000001);
00181    DB.output();
00182    
00183    return status;     
00184 }                    
00185 
00186 
00187 
00188 void KS0108::SelectSide(unsigned char side){
00189     if(side==LEFT)
00190         {CS1.write(1);CS2.write(0);}
00191     else if(side==RIGHT)
00192         {CS1.write(0);CS2.write(1);}
00193     else if (side==BOTH)
00194         {CS1.write(1);CS2.write(1);}
00195     else if (side==NONE)
00196         {CS1.write(0);CS2.write(0);}
00197 }
00198 
00199 
00200 void KS0108::ClearScreen(){
00201      for (int col=0;col<128;col++) {
00202         for (int page=0;page<8;page++)
00203         {
00204             WriteDataColPag(page,col,WHITE);
00205         }
00206     }
00207 }     
00208 
00209 
00210 void KS0108::TurnOn(){
00211     WriteInstruction(LCD_ON,BOTH);
00212 }
00213 
00214 
00215 void KS0108::TurnOff(){
00216     WriteInstruction(LCD_OFF,BOTH);
00217 }
00218 
00219 
00220 /*******************************************************************************************/      
00221 
00222  
00223 void KS0108::SetPixel(unsigned int x,  unsigned int y,  unsigned int color){    
00224   
00225   unsigned int position;
00226    
00227   SelectSide(NONE);
00228   WriteInstruction(LCD_SET_ADD,NONE);    
00229   
00230   if(x>=64){           
00231   WriteInstruction(LCD_SET_PAGE|(y/8),RIGHT);
00232   WriteInstruction(LCD_SET_ADD|x,RIGHT);
00233   position = ReadData();                            //dummy read 
00234   position = ReadData();                            //actual read 
00235   WriteInstruction(LCD_SET_ADD|x,RIGHT);
00236   if(color==WHITE)                                
00237   WriteData(position&(~(1<<(y%8))),RIGHT);         // draw a white pixel
00238   else                                            
00239   WriteData(position|(1<<(y%8)),RIGHT);
00240   wait_us(450);
00241   }else{ 
00242   WriteInstruction(LCD_SET_PAGE|(y/8),LEFT);
00243   WriteInstruction(LCD_SET_ADD|x,LEFT);  
00244   position = ReadData();                            //dummy read 
00245   position = ReadData();                            //actual read 
00246   WriteInstruction(LCD_SET_ADD|x,LEFT);
00247   if(color==WHITE)                                
00248   WriteData(position&(~(1<<(y%8))),LEFT);              
00249   else                                            
00250   WriteData(position|(1<<(y%8)),LEFT);
00251   
00252   wait_us(450);
00253 
00254   }
00255 
00256 }       
00257 
00258 
00259 
00260 void KS0108::FullRectangle(unsigned int Xaxis1, unsigned int Yaxis1, unsigned int Xaxis2 ,unsigned int Yaxis2,unsigned int color){
00261            
00262     for(unsigned int i=Xaxis1;i<=Xaxis2;i++){
00263         for(unsigned int j=Yaxis1;j<=Yaxis2;j++){
00264             SetPixel(i,j,color);
00265         } 
00266     }   
00267 }  
00268 
00269 
00270 void KS0108::EmptyRectangle(unsigned int Xaxis1,unsigned int Yaxis1, unsigned int Xaxis2,unsigned int Yaxis2,unsigned int color){
00271       unsigned int CurrentValue;
00272 
00273     /* Draw the two horizontal lines */
00274       for (CurrentValue = 0; CurrentValue < Xaxis2 - Xaxis1+ 1; CurrentValue++) 
00275       {
00276         SetPixel(Xaxis1 + CurrentValue, Yaxis1,color);
00277         SetPixel(Xaxis1 + CurrentValue, Yaxis2,color);
00278     }
00279       
00280       /* draw the two vertical lines */
00281       for (CurrentValue = 0; CurrentValue < Yaxis2 - Yaxis1 + 1; CurrentValue++)    
00282       {
00283         SetPixel(Xaxis1, Yaxis1 + CurrentValue,color);
00284         SetPixel(Xaxis2, Yaxis1 + CurrentValue,color);
00285     }
00286 }
00287 
00288 
00289 void KS0108::RoundRectangle(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int radius, unsigned int color) {
00290       int tSwitch, x1 = 0, y1 = radius;
00291       tSwitch = 3 - 2 * radius;
00292     
00293     while (x1 <= y1) {
00294         SetPixel(x+radius - x1, y+radius - y1, color);
00295         SetPixel(x+radius - y1, y+radius - x1, color);
00296 
00297         SetPixel(x+width-radius + x1, y+radius - y1, color);
00298         SetPixel(x+width-radius + y1, y+radius - x1, color);
00299         
00300         SetPixel(x+width-radius + x1, y+height-radius + y1, color);
00301         SetPixel(x+width-radius + y1, y+height-radius + x1, color);
00302 
00303         SetPixel(x+radius - x1, y+height-radius + y1, color);
00304         SetPixel(x+radius - y1, y+height-radius + x1, color);
00305 
00306         if (tSwitch < 0) {
00307             tSwitch += (4 * x1 + 6);
00308         } else {
00309             tSwitch += (4 * (x1 - y1) + 10);
00310             y1--;
00311         }
00312         x1++;
00313     }
00314           
00315     HLineShort(x+radius,y, width-(2*radius), color);                // top
00316     HLineShort(x+radius,y+height, width-(2*radius),  color);        // bottom
00317     VLineShort(x,y+radius,height-(2*radius), color);                // left
00318     VLineShort(x+width, y+radius,height-(2*radius),  color);        // right
00319 }
00320 
00321 
00322 void KS0108::HLine(unsigned int Xaxis1, unsigned int Xaxis2 ,unsigned int Yaxis,unsigned int color){
00323     FullRectangle(Xaxis1,Yaxis,Xaxis2,Yaxis,color);
00324 
00325 }
00326 
00327 
00328 void KS0108::HLineShort(unsigned int Xaxis, unsigned int Yaxis,unsigned int width ,unsigned int color){
00329     FullRectangle(Xaxis,Yaxis,Xaxis+width,Yaxis,color);
00330 
00331 } 
00332 
00333 
00334 void KS0108::VLine(unsigned int Xaxis, unsigned int Yaxis1 ,unsigned int Yaxis2,unsigned int color){
00335     FullRectangle(Xaxis,Yaxis1,Xaxis,Yaxis2,color);    
00336 }
00337 
00338 
00339 void KS0108::VLineShort(unsigned int Xaxis,unsigned int Yaxis, unsigned int height ,unsigned int color){
00340     FullRectangle(Xaxis,Yaxis,Xaxis,Yaxis+height,color);
00341 
00342 }
00343 
00344 
00345 void KS0108::DegreeLine(unsigned int x, int y,unsigned int degree,unsigned int inner_radius,unsigned int outer_radius, unsigned int color){
00346   int fx,fy,tx,ty;
00347   fx = x + dfloor(inner_radius * sin(degree * 3.14 / 180));
00348   fy = y - dfloor(inner_radius * cos(degree * 3.14 / 180));
00349   tx = x + dfloor(outer_radius * sin(degree * 3.14 / 180));
00350   ty = y - dfloor(outer_radius * cos(degree * 3.14 / 180));
00351   SlantyLine(fx,fy,tx,ty,color);
00352 }
00353 
00354 
00355 double KS0108::dfloor( double value ) {
00356   
00357   if (value < 0.0)
00358     return ceil( value );
00359   else
00360     return floor( value );
00361     
00362 }
00363 
00364 
00365 void KS0108::SlantyLine(unsigned int lX1, unsigned int lY1, unsigned int lX2,unsigned int lY2,unsigned int color){
00366     long lError, lDeltaX, lDeltaY, lYStep, bSteep;       
00367     
00368     // A steep line has a bigger ordinate.
00369     
00370     if(((lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2)) > ((lX2 > lX1) ? (lX2 - lX1) : (lX1 - lX2))){
00371         bSteep = 1;
00372     }else {
00373         bSteep = 0;
00374     }
00375         
00376     // If line is steep, swap the X and Y coordinates.
00377     if(bSteep){
00378         lError = lX1;
00379         lX1 = lY1;
00380         lY1 = lError;
00381         lError = lX2;
00382         lX2 = lY2;
00383         lY2 = lError;
00384     }
00385 
00386    
00387     // If the starting X coordinate is larger than the ending X coordinate,
00388     // swap coordinates.
00389     if(lX1 > lX2){
00390         lError = lX1;
00391         lX1 = lX2;
00392         lX2 = lError;
00393         lError = lY1;
00394         lY1 = lY2;
00395         lY2 = lError;
00396     }
00397         
00398     // Compute the difference between the start and end coordinates.      
00399     lDeltaX = lX2 - lX1;
00400     lDeltaY = (lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2);
00401                                                                    
00402     lError = -lDeltaX / 2;          // Initialize the error term to negative half the X delta.
00403      
00404     if(lY1 < lY2){                   // Determine the direction to step in the Y axis when required.
00405         lYStep = 1;
00406     }else{
00407         lYStep = -1;
00408     }
00409         
00410     for(; lX1 <= lX2; lX1++){    // Loop through all the points along the X axis of the line.
00411         
00412         // See if this is a steep line.
00413         
00414         if(bSteep){
00415             
00416             // Plot this point of the line, swapping the X and Y coordinates.
00417             
00418             SetPixel(lY1, lX1,color);
00419         }
00420         else {           // Plot this point of the line, using the coordinates as is.            
00421             SetPixel(lX1, lY1,color);
00422         }                     
00423         
00424         // Increment the error term by the Y delta.
00425         
00426         lError += lDeltaY; 
00427                     
00428         if(lError > 0){                // See if the error term is now greater than zero.
00429                      
00430             lY1 += lYStep;            // Take a step in the Y axis.
00431                                                                        
00432             lError -= lDeltaX;         // Decrement the error term by the X delta.
00433         }
00434     }
00435 }
00436 
00437 
00438 
00439 void KS0108::Line(unsigned int x1, unsigned int  y1, unsigned int  x2, unsigned int  y2, unsigned int color){
00440 unsigned int  deltax, deltay, x,y, steep;
00441 int lerror, ystep;
00442 
00443     steep = absDiff(y1,y2) > absDiff(x1,x2);   //check slope
00444 
00445     if ( steep ){
00446         swap(x1, y1);
00447         swap(x2, y2);
00448     }
00449 
00450     if (x1 > x2){
00451         swap(x1, x2);
00452         swap(y1, y2);
00453     }
00454 
00455     deltax = x2 - x1;
00456     deltay = absDiff(y2,y1);  
00457     lerror = deltax / 2;
00458     y = y1;
00459     if(y1 < y2) ystep = 1;  else ystep = -1;
00460 
00461     for(x = x1; x <= x2; x++){
00462         if (steep) SetPixel(y,x, color); else SetPixel(x,y, color);
00463            lerror -= deltay;
00464         if (lerror < 0){
00465             y = y + ystep;
00466             lerror += deltax;
00467         }
00468     }
00469 }
00470 
00471 
00472 void KS0108::EmptyCircle(unsigned int CenterX, unsigned int CenterY, unsigned int Radius,unsigned int color){
00473   unsigned int y=0, x=0, d = 0;
00474   int part; 
00475   d = CenterY - CenterX;
00476   y = Radius;
00477   part = 3 - 2 * Radius;
00478 
00479   while (x <= y) { 
00480     SetPixel(CenterX + x, CenterY + y,color);  
00481     SetPixel(CenterX + x, CenterY - y,color);
00482     SetPixel(CenterX - x, CenterY + y,color);    
00483     SetPixel(CenterX - x, CenterY - y,color);
00484     SetPixel(CenterY + y - d, CenterY + x,color); 
00485     SetPixel(CenterY + y - d, CenterY - x,color);
00486     SetPixel(CenterY - y - d, CenterY + x,color);
00487     SetPixel(CenterY - y - d, CenterY - x,color); 
00488 
00489     if (part < 0) part += (4 * x + 6);
00490     else {
00491       part += (4 * (x - y) + 10);
00492       y--;
00493     }
00494     x++;
00495   }
00496 
00497 }  
00498 
00499  
00500 void KS0108::FullCircle(unsigned int CenterX, unsigned int CenterY, unsigned int Radius,unsigned int color){  
00501 
00502 int f = 1 - Radius;
00503 int ddF_x = 1;
00504 int ddF_y = 2 * Radius;             //changed sign of -2
00505 unsigned int x = 0;
00506 unsigned int y = Radius;      
00507     
00508      //Fill in the center between the two halves
00509      
00510     Line(CenterX, CenterY-Radius, CenterX, CenterY+Radius, color);
00511  
00512     while(x < y){
00513         if(f >= 0)
00514         {
00515             y--;
00516             ddF_y += 2;
00517             f += ddF_y;
00518         }
00519         x++;
00520         ddF_x += 2;
00521         f += ddF_x;    
00522 
00523         /*
00524          * Now draw vertical lines between the points on the circle rather than
00525          * draw the points of the circle. This draws lines between the 
00526          * perimeter points on the upper and lower quadrants of the 2 halves of the circle.
00527          */
00528 
00529         Line(CenterX+x, CenterY+y, CenterX+x, CenterY-y, color);
00530         Line(CenterX-x, CenterY+y, CenterX-x, CenterY-y, color);
00531         Line(CenterX+y, CenterY+x, y+CenterX, CenterY-x, color);
00532         Line(CenterX-y, CenterY+x, CenterX-y, CenterY-x, color);
00533       }
00534 }                 
00535 
00536 
00537 
00538 void KS0108::PlotEllipse(long CX, long  CY, long XRadius,long YRadius, int color) {
00539 
00540 
00541   long X, Y;
00542   long XChange, YChange;
00543   long EllipseError;
00544   long TwoASquare,TwoBSquare;
00545   long StoppingX, StoppingY;
00546   TwoASquare = 2*XRadius*XRadius;
00547   TwoBSquare = 2*YRadius*YRadius;
00548   X = XRadius;
00549   Y = 0;
00550   XChange = YRadius*YRadius*(1-2*XRadius);
00551   YChange = XRadius*XRadius;
00552   EllipseError = 0;
00553   StoppingX = TwoBSquare*XRadius;
00554   StoppingY = 0;
00555 
00556   while ( StoppingX >=StoppingY )                 //first set of points,y'>-1
00557   {
00558     Plot4EllipsePoints(CX,CY,X,Y,color);
00559     Y++;
00560     StoppingY=StoppingY+ TwoASquare;
00561     EllipseError = EllipseError+ YChange;
00562     YChange=YChange+TwoASquare;
00563     if ((2*EllipseError + XChange) > 0 ) {
00564       X--;
00565       StoppingX=StoppingX- TwoBSquare;
00566       EllipseError=EllipseError+ XChange;
00567       XChange=XChange+TwoBSquare;
00568     }
00569   }
00570 
00571   Y = YRadius;
00572   X = 0;
00573   YChange = XRadius*XRadius*(1-2*YRadius);
00574   XChange = YRadius*YRadius;
00575   EllipseError = 0;
00576   StoppingY = TwoASquare*YRadius;
00577   StoppingX = 0;
00578 
00579   while ( StoppingY >=StoppingX )                 //{2nd set of points, y'< -1}
00580   {
00581     Plot4EllipsePoints(CX,CY,X,Y,color);
00582     X++;
00583     StoppingX=StoppingX + TwoBSquare;
00584     EllipseError=EllipseError+ XChange;
00585     XChange=XChange+TwoBSquare;
00586     if ((2*EllipseError + YChange) > 0 ) {
00587       Y--;
00588       StoppingY=StoppingY- TwoASquare;
00589       EllipseError=EllipseError+ YChange;
00590       YChange=YChange+TwoASquare;
00591     }
00592   }
00593 } 
00594 
00595 
00596 
00597 void KS0108::Plot4EllipsePoints(long CX,long  CY, long X, long Y, int color){
00598   SetPixel(CX+X, CY+Y, color); //{point in quadrant 1}
00599   SetPixel(CX-X, CY+Y, color); //{point in quadrant 2}
00600   SetPixel(CX-X, CY-Y, color); //{point in quadrant 3}
00601   SetPixel(CX+X, CY-Y, color); //{point in quadrant 4}
00602 }                                                        
00603 
00604 
00605 void KS0108::RightTriangle ( int topx, int topy, int rightx, int righty) {
00606 
00607     //draw rectangle one line at a time
00608     Line( topx,topy, rightx,righty,BLACK );        //draw hypotenuse
00609     Line ( topx,righty,topx,topy,BLACK);         //draw perpendicular
00610     Line (topx,righty, rightx,righty,BLACK);      // draw base
00611     
00612 }
00613 
00614 void KS0108::Triangle ( int topx, int topy, int rightx, int righty) {
00615     int base =0;
00616     base = 2* rightx-topx;
00617     //draw rectangle one line at a time
00618     Line( topx,topy, rightx,righty,BLACK );                //draw hypotenuse
00619     Line ( topx,righty,topx,topy,BLACK);                     //draw perpendicular
00620     Line(topx-base/2,righty, rightx,righty,BLACK);         // draw base
00621     Line(topx-base/2, righty, topx,topy,BLACK);            // draw hypotenuse
00622     
00623 }
00624 
00625 
00626 
00627 
00628 /***********************************************************************************/
00629 
00630 
00631 void KS0108::FullScreenBMP (unsigned char *PictureData){
00632     unsigned int Page=0;
00633       unsigned int Column=0;
00634       
00635     // Draw left side of the picture 
00636     SelectSide(LEFT);
00637       for (Page = 0; Page < 8; Page++){                     /* loop on the 8 pages */            
00638               WriteInstruction(LCD_SET_PAGE | Page,LEFT); /* Set the page */
00639               for (Column = 0; Column < 64; Column++)
00640             WriteData(PictureData[(128*Page)+Column],LEFT);
00641     }
00642     
00643     // Draw right side of the picture
00644     SelectSide(RIGHT);
00645       for (Page = 0; Page < 8; Page++){                     /* loop on the 8 pages */
00646     
00647               WriteInstruction(LCD_SET_PAGE| Page,RIGHT); /* Set the page */
00648               for (Column = 64; Column < 128; Column++)
00649             WriteData(PictureData[(128*Page)+Column],RIGHT);
00650     }    
00651 }
00652 
00653 unsigned int KS0108::ReadArrayData(const unsigned int* ptr) { 
00654     return (*ptr);
00655 }
00656 
00657 void KS0108::DrawBitmap(const unsigned int * bitmap, unsigned int x, unsigned int y, unsigned int color){
00658 unsigned int width, height;
00659 unsigned int i, j;
00660 
00661   width = ReadArrayData(bitmap++); 
00662   height = ReadArrayData(bitmap++);
00663   for(j = 0; j < height / 8; j++) {
00664      GotoXY(x, y + (j*8) );
00665      for(i = 0; i < width; i++) {
00666          unsigned int displayData = ReadArrayData(bitmap++);
00667             if(color == BLACK)
00668             WriteData(displayData);
00669          else
00670             WriteData(~displayData);
00671      }
00672   }
00673 }  
00674 /******************************************************************************************/
00675 
00676 
00677 void KS0108::GotoXY(unsigned int x, unsigned int y) {
00678   unsigned int chip, cmd;
00679     
00680   if( (x > SCREEN_WIDTH-1) || (y > SCREEN_HEIGHT-1) )    // exit if coordinates are not legal
00681     return;
00682   Coord.x = x;                                    // save new coordinates
00683   Coord.y = y;
00684     
00685   if(y/8 != Coord.page) {
00686       Coord.page = y/8;
00687     cmd = LCD_SET_PAGE | Coord.page;            // set y address on all chips    
00688     for(chip=0; chip < 2; chip++){
00689        WriteInstruction(cmd, chip);    
00690     }
00691   }
00692   chip = Coord.x/64;
00693   x = x % 64;
00694   cmd = LCD_SET_ADD | x;
00695   WriteInstruction(cmd, chip);                    // set x address on active chip        
00696 
00697 }
00698 
00699 
00700 /*****************************************************************************************/
00701 
00702 
00703 
00704 void KS0108::Putchar (int page, int col,unsigned char c) {
00705     if (c>31 && c<127){
00706     for(int i=0;i<5;i++){
00707         WriteDataColPag(page,col+i,System5x7[((c-32)*5+i)+6]);
00708      }
00709     }
00710 }
00711 
00712 
00713 
00714 void KS0108::PutString(unsigned int x, unsigned int y,char* str){
00715 
00716     while(*str != 0){
00717      Putchar(x,y,*str);
00718      str++;
00719      y+=System5x7[2];
00720     }
00721 
00722 }
00723 
00724 void KS0108::PrintFloat(float val, unsigned int x,unsigned int y){
00725    char buf[20] = {};  // prints up to 20 digits         
00726    sprintf(buf,"%f",val);
00727    PutString(x,y,buf);
00728 
00729 }
00730 
00731 
00732 void KS0108::PrintInteger(int val,unsigned int x,unsigned int y){
00733    char buf[20] = {};  // prints up to 20 digits         
00734    sprintf(buf,"%d",val);
00735    PutString(x,y,buf);
00736 }
00737 
00738 void KS0108::SelectFont(unsigned int* font,unsigned int color, FontCallback callback) {
00739     Font = font;
00740     FontRead = callback;
00741     FontColor = color;
00742 }
00743 
00744 
00745 int KS0108::PrintChar(char c) {
00746     unsigned int width = 0;
00747     unsigned int height = FontRead(Font+FONT_HEIGHT);
00748     unsigned int bytes = (height+7)/8;
00749     
00750     unsigned int firstChar = FontRead(Font+FONT_FIRST_CHAR);
00751     unsigned int charCount = FontRead(Font+FONT_CHAR_COUNT);
00752         
00753     unsigned int index = 0;
00754     unsigned int x=Coord.x , y=Coord.y;
00755 
00756     if(c < firstChar || c >= (firstChar+charCount)) {
00757         return 1;
00758     }
00759     c-= firstChar;
00760 
00761     if( FontRead(Font+FONT_LENGTH) == 0 && FontRead(Font+FONT_LENGTH+1) == 0) {
00762     // zero length is flag indicating fixed width font (array does not contain width data entries)
00763        width = FontRead(Font+FONT_FIXED_WIDTH); 
00764        index = c*bytes*width+FONT_WIDTH_TABLE;
00765     }
00766     else{
00767     // variable width font, read width data, to get the index
00768        for(unsigned int i=0; i<c; i++) {  
00769          index += FontRead(Font+FONT_WIDTH_TABLE+i);
00770        }
00771        index = index*bytes+charCount+FONT_WIDTH_TABLE;
00772        width = FontRead(Font+FONT_WIDTH_TABLE+c);
00773     }
00774 
00775     // last but not least, draw the character
00776     for(unsigned int i=0; i<bytes; i++) {
00777         unsigned int page = i*width;
00778         for(unsigned int j=0; j<width; j++) {
00779             unsigned int data = FontRead(Font+index+page+j);
00780         
00781             if(height > 8 && height < (i+1)*8) {
00782                 data >>= (i+1)*8-height;
00783             }
00784             
00785             WriteData(data);
00786 
00787         }
00788         // 1px gap between chars
00789         WriteData(0x00);
00790         GotoXY(x,Coord.y+8);
00791     
00792     }
00793     GotoXY(x+width+1, y);
00794     
00795 
00796     return 0;
00797 }
00798 
00799 void KS0108::PrintString(char* str) {
00800     int x = Coord.x;
00801     while(*str != 0) {
00802         if(*str == '\n') {
00803             GotoXY(x, Coord.y+ FontRead(Font+FONT_HEIGHT));
00804         } else {
00805             PrintChar(*str);
00806         }
00807         str++;
00808     }
00809 }
00810 
00811 void KS0108::PrintNumber(long n){
00812    char buf[10];  // prints up to 10 digits  
00813    char i=0;
00814    if(n==0)
00815        PrintChar('0');
00816    else{
00817      if(n < 0){
00818         PrintChar('-');
00819         n = -n;
00820      }
00821      while(n>0 && i <= 10){
00822        buf[i++] = n % 10;  // n % base
00823        n /= 10;   // n/= base
00824      }
00825      for(; i >0; i--)
00826          PrintChar((char) (buf[i-1] < 10 ? '0' + buf[i-1] : 'A' + buf[i-1] - 10));      
00827    }
00828 }
00829 
00830 
00831 
00832             
00833 
00834     
00835