OSDN Git Service

Update samples to nxtOSEK_v212.zip (I did not check their licenses.)
[nxt-jsp/etrobo-atk.git] / nxtOSEK / samples_c++ / cc / sprite_devl / Screen.cc
1 #include "Screen.h"\r
2 \r
3 #ifdef _MSC_VER\r
4 #include <assert.h>\r
5 #else\r
6 extern "C"\r
7 {\r
8         #include "systick.h"\r
9 }\r
10 #endif\r
11 \r
12 Screen::Screen()\r
13 {\r
14         memset(mLcd, 0x00, NXT_LCD_DEPTH*NXT_LCD_WIDTH);\r
15         for(int i = 0; i < NUM_SPRITES; ++i)\r
16         {\r
17                 mSpriteList[i] = NULL;\r
18         }\r
19 }\r
20 \r
21 void Screen::update()\r
22 {\r
23         memset(mLcd, 0x00, NXT_LCD_DEPTH*NXT_LCD_WIDTH);\r
24         for(int i = 0; i < NUM_SPRITES; ++i)\r
25         {\r
26                 if(mSpriteList[i])\r
27                 {\r
28                         if(mSpriteList[i]->frameIsRenderable())\r
29                         {\r
30                                 renderBitmap(   mLcd, \r
31                                                                 mSpriteList[i]->getCurrentFramePtr(), \r
32                                                                 mSpriteList[i]->getWidth(), \r
33                                                                 mSpriteList[i]->getHeight(), \r
34                                                                 mSpriteList[i]->getPosition().mX, \r
35                                                                 mSpriteList[i]->getPosition().mY, \r
36                                                                 mSpriteList[i]->getInvert(), \r
37                                                                 mSpriteList[i]->getHFlip(), \r
38                                                                 mSpriteList[i]->getVFlip());\r
39                         }\r
40                         \r
41                         mSpriteList[i]->update();\r
42                 }\r
43         }\r
44 #ifndef _MSC_VER\r
45         // Display update of NXT LCD takes 16msec according LEGO HW development kit. \r
46         // Thus faster refresh rate(update) than 16msec does not work. \r
47         // Actually it makes the system busy by frequest ISR requests and \r
48         // it may cause a system crash. Then it needs to insert 20msec (> 16msec) wait.\r
49         systick_wait_ms(20);\r
50 #endif\r
51         display_bitmap_copy(mLcd, NXT_LCD_WIDTH, NXT_LCD_DEPTH, 0, 0);\r
52         display_update();\r
53 }\r
54 \r
55 Sprite* Screen::newSprite(Sprite *sprite)\r
56 {\r
57         for(int i = 0; i < NUM_SPRITES; ++i)\r
58         {\r
59                 if(mSpriteList[i] == NULL)\r
60                 {\r
61                         mSpriteList[i] = sprite;\r
62                         return sprite;\r
63                 }\r
64         }\r
65 \r
66         return sprite;\r
67 }\r
68 \r
69 void Screen::deleteSprite(Sprite *sprite)\r
70 {\r
71         for(int i = 0; i < NUM_SPRITES; ++i)\r
72         {\r
73                 if(mSpriteList[i] == sprite)\r
74                 {\r
75                         mSpriteList[i] = NULL;\r
76                         return;\r
77                 }\r
78         }\r
79 }\r
80 #ifdef _MSC_VER\r
81 void Screen::renderBitmap(U8 *lcd, const CHAR *sprite, S32 width, S32 height, S32 xPos, S32 yPos, bool invert, bool hflip, bool vflip)\r
82 {\r
83     int spriteByteWidth = width/8;\r
84     int currentSpriteByte = 0;\r
85     int spriteRow = 0;\r
86 \r
87     for (int y = 0; y < height; ++y)\r
88     {\r
89         if(vflip == true)\r
90         {\r
91             spriteRow = height - 1 - y;\r
92         }\r
93         else\r
94         {\r
95             spriteRow = y;\r
96         }\r
97 \r
98         if (spriteRow + yPos < 0 || spriteRow + yPos > 63)\r
99         {\r
100             currentSpriteByte += spriteByteWidth;\r
101             continue;\r
102         }\r
103 \r
104         int spriteCol = 0;\r
105         for (int x = 0; x < spriteByteWidth; x++)\r
106         {\r
107             if (hflip == true)\r
108             {\r
109                 spriteCol = spriteByteWidth - 1 - x;\r
110             }\r
111             else\r
112             {\r
113                 spriteCol = x;\r
114             }\r
115 \r
116             unsigned char workByte = sprite[currentSpriteByte++];\r
117 \r
118             if(invert)\r
119                 {\r
120                 workByte ^= 0xff;\r
121                 }\r
122 \r
123             int spritePixelOffset = (spriteCol * 8) + xPos;\r
124             \r
125             int lcdPixelOffset = ((spriteRow + yPos) * 100) + spritePixelOffset;\r
126             int pixelShift = 0;\r
127             for (int px = 0; px < 8; ++px)\r
128             {\r
129                 if (hflip == true)\r
130                 {\r
131                     pixelShift = px;\r
132                 }\r
133                 else\r
134                 {\r
135                     pixelShift = 7 - px;\r
136                 }\r
137 \r
138                 if (spritePixelOffset + px < 0 || spritePixelOffset + px > 99)\r
139                 {\r
140                     continue;\r
141                 }\r
142 \r
143                 if (workByte > 0)\r
144                 {\r
145                     int lcdBytePos = (lcdPixelOffset + px) / 8;\r
146                     int lcdBitPos = (lcdPixelOffset + px) % 8;\r
147 \r
148                     if ((workByte & (1 << pixelShift)) == (1 << pixelShift))\r
149                     {\r
150                         lcd[lcdBytePos] |= (char)(1 << lcdBitPos);\r
151                     }\r
152                 }\r
153             }\r
154         }\r
155     }\r
156 }\r
157 #else\r
158 void Screen::renderBitmap(U8 *lcd, const CHAR *file, S32 width, S32 height, S32 xPos, S32 yPos, bool invert, bool hflip, bool vflip)\r
159 {       \r
160         SINT bmp_line = width / 8;\r
161         if (width % 8)\r
162         {\r
163                 bmp_line++;\r
164         }\r
165 \r
166         //iterate through each row of the bitmap\r
167         for (SINT bmp_row = 0; bmp_row < height; bmp_row++)\r
168         {\r
169                 //if the position of any row puts it off screen, the don' render it\r
170                 if(bmp_row + yPos < 0 || bmp_row + yPos > 63)\r
171                 {\r
172                         continue;\r
173                 }\r
174 \r
175                 //setup the pixel position on the lcd to render\r
176                 SINT lcd_row = (bmp_row + yPos) / 8;\r
177                 SINT lcd_bit_pos = 7 - ((bmp_row + yPos) % 8);\r
178 \r
179                 //iterate through each column\r
180                 for(SINT bmp_col = 0; bmp_col < bmp_line ; bmp_col++)\r
181                 {\r
182                         //vflip if nevessary\r
183                         U8 row = bmp_row;\r
184 \r
185                         if(vflip)\r
186                         {\r
187                                 row = (height - bmp_row);\r
188                         }\r
189 \r
190                         //hflp if necessary\r
191                         SINT renderColumn = bmp_col;\r
192 \r
193                         if(hflip)\r
194                         {\r
195                                 renderColumn = bmp_line - bmp_col;\r
196                         }\r
197 \r
198                         //get the byte to render\r
199                         U8 bmp_data = file[(row * bmp_line) + bmp_col];\r
200 \r
201                         //invert the bits if necessary\r
202                         if(invert)\r
203                         {\r
204                                 bmp_data ^= 0xff;\r
205                         }\r
206 \r
207                         //get the position on the lcd to render\r
208                         SINT lcd_pos = (lcd_row * NXT_LCD_WIDTH) + ((renderColumn * 8) + xPos);\r
209 \r
210                         //now iterate through each bit in the render byte\r
211                         for (SINT bmp_bit_pos = 0; bmp_bit_pos < 8; bmp_bit_pos++)\r
212                         {\r
213 \r
214                                 //hflip the renderbytes bits if necessary\r
215                                 U8 bitToDraw = (7 - bmp_bit_pos);\r
216 \r
217                                 if(hflip)\r
218                                 {\r
219                                         bitToDraw = bmp_bit_pos;\r
220                                 }\r
221 \r
222                                 //if ever a bit is off screen, don't render it\r
223                                 if((renderColumn * 8) + xPos + bitToDraw < 0 || \r
224                                         (renderColumn * 8) + xPos + bitToDraw  > 99)\r
225                                 {\r
226                                         continue;\r
227                                 }\r
228 \r
229                                 //finally, render the pixel\r
230                                 if (bmp_data & (0x01 << bitToDraw))\r
231                                 {\r
232                                         SINT lcd_index = lcd_pos + bmp_bit_pos;\r
233                                         // checks the size of render data to be stored into LCD\r
234                                         if (lcd_index < NXT_LCD_DEPTH*NXT_LCD_WIDTH)\r
235                                         {\r
236                                                 lcd[lcd_index] |= (0x80 >> lcd_bit_pos);\r
237                                         }\r
238                                 }\r
239                                 /*else\r
240                                 {\r
241                                         //if the bitmap pixel is clear and we're not rendering transparently,\r
242                                         //clear this pixel location on the lcd\r
243                                         if(!transparent)\r
244                                         {\r
245                                                 lcd[lcd_pos + bmp_bit_pos] &= (~0x80 >> lcd_bit_pos);\r
246                                         }\r
247                                 }*/\r
248                         }\r
249                 }\r
250         }\r
251 }\r
252 #endif\r
253 \r