D:/DRISSI/arduino-0022/arduino-0022/libraries/Sprite/Sprite.cpp
00001 /*
00002   Sprite.cpp - 2D sprite buffer library for Arduino & Wiring
00003   Copyright (c) 2006 David A. Mellis.  All right reserved.
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00020 #include <stdlib.h>
00021 #include <stdarg.h>
00022 //#include <stdio.h>
00023 
00024 #include "Sprite.h"
00025 
00026 void Sprite::init(uint8_t width, uint8_t height)
00027 {
00028   _width = width >= 8 ? 8 : width;
00029   _height = height >= 8 ? 8 : height;
00030 
00031   // for now, do nothing if this allocation fails.  methods that require it
00032   // should silently fail if _buffer is null.
00033   _buffer = (uint8_t *) calloc(_height, 1);
00034 }
00035   
00036 Sprite::Sprite(uint8_t width, uint8_t height)
00037 {
00038   init(width, height);
00039 }
00040 
00041 Sprite::Sprite(uint8_t width, uint8_t height, uint8_t row, ...)
00042 {
00043   init(width, height);
00044   
00045   if (!_buffer) return;
00046   
00047   va_list ap;
00048   va_start(ap, row);
00049 
00050   int y = 0;
00051   
00052   for (y = 0; ; y++) {
00053     for (int x = 0; x < width && x < 8; x++)
00054       write(x, y, (row >> (width - x - 1)) & 0x01);
00055     
00056     if (y == height - 1)
00057       break;
00058       
00059     row = va_arg(ap, int); // using '...' promotes uint8_t to int
00060   }
00061   
00062   va_end(ap);
00063 }
00064 
00065 uint8_t Sprite::width() const
00066 {
00067   return _width;
00068 }
00069 
00070 uint8_t Sprite::height() const
00071 {
00072   return _height;
00073 }
00074 
00075 void Sprite::write(uint8_t x, uint8_t y, uint8_t value)
00076 {
00077   if (!_buffer) return;
00078   
00079   // uint8_t's can't be negative, so don't test for negative x and y.
00080   if (x >= _width || y >= _height) return;
00081   
00082   // we need to bitwise-or the value of the other pixels in the byte with
00083   // the new value, masked and shifted into the proper bits.
00084   _buffer[y] = (_buffer[y] & ~(0x01 << x)) | ((value & 0x01) << x);
00085 }
00086 
00087 uint8_t Sprite::read(uint8_t x, uint8_t y) const
00088 {
00089   if (!_buffer) return 0;
00090   
00091   // uint8_t's can't be negative, so don't test for negative x and y.
00092   if (x >= _width || y >= _height) return 0;
00093   
00094   return (_buffer[y] >> x) & 0x01;
00095 }