Demo of low res colour vga video for stm32f3 discovery board
Dependencies: STM32F3-Discovery-minimal
Fork of Space_Invaders_Demo by
moredemos.c@11:1b3dc5581b1b, 2018-05-31 (annotated)
- Committer:
- MartinJohnson
- Date:
- Thu May 31 03:11:33 2018 +0000
- Revision:
- 11:1b3dc5581b1b
add rotozoom and cube demos
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MartinJohnson | 11:1b3dc5581b1b | 1 | #include "stm32f30x.h" |
MartinJohnson | 11:1b3dc5581b1b | 2 | #include "video.h" |
MartinJohnson | 11:1b3dc5581b1b | 3 | #include <stdlib.h> |
MartinJohnson | 11:1b3dc5581b1b | 4 | #include <math.h> |
MartinJohnson | 11:1b3dc5581b1b | 5 | #include "sys.h" |
MartinJohnson | 11:1b3dc5581b1b | 6 | #include "gdi.h" |
MartinJohnson | 11:1b3dc5581b1b | 7 | |
MartinJohnson | 11:1b3dc5581b1b | 8 | typedef unsigned Unit; |
MartinJohnson | 11:1b3dc5581b1b | 9 | |
MartinJohnson | 11:1b3dc5581b1b | 10 | #define cols VID_HSIZE |
MartinJohnson | 11:1b3dc5581b1b | 11 | #define rows VID_VSIZE |
MartinJohnson | 11:1b3dc5581b1b | 12 | #define bits 1 |
MartinJohnson | 11:1b3dc5581b1b | 13 | |
MartinJohnson | 11:1b3dc5581b1b | 14 | extern char *fb[VID_VSIZE]; |
MartinJohnson | 11:1b3dc5581b1b | 15 | |
MartinJohnson | 11:1b3dc5581b1b | 16 | void conway_demo() { |
MartinJohnson | 11:1b3dc5581b1b | 17 | vidClearScreen(); |
MartinJohnson | 11:1b3dc5581b1b | 18 | for (int i=0;i<rows*cols/8;i=i+1) |
MartinJohnson | 11:1b3dc5581b1b | 19 | fb[rand()%rows][rand()%cols]=(rand()%7)|1; |
MartinJohnson | 11:1b3dc5581b1b | 20 | while(1) { |
MartinJohnson | 11:1b3dc5581b1b | 21 | for (int y=1;y<rows-2;y=y+1) { |
MartinJohnson | 11:1b3dc5581b1b | 22 | for (int x=1;x<cols-2;x=x+1) { |
MartinJohnson | 11:1b3dc5581b1b | 23 | int v=fb[y][x]&7; |
MartinJohnson | 11:1b3dc5581b1b | 24 | int count = (fb[y][x+1]&1)+(fb[y+1][x]&1)+ |
MartinJohnson | 11:1b3dc5581b1b | 25 | (fb[y][x-1]&1)+(fb[y-1][x]&1)+ |
MartinJohnson | 11:1b3dc5581b1b | 26 | (fb[y+1][x+1]&1)+(fb[y-1][x+1]&1) + |
MartinJohnson | 11:1b3dc5581b1b | 27 | (fb[y-1][x-1]&1)+(fb[y+1][x-1]&1); |
MartinJohnson | 11:1b3dc5581b1b | 28 | if (count==3 && v==0) v=(rand()%7)|1; |
MartinJohnson | 11:1b3dc5581b1b | 29 | if ((count<2 || count>3) && v!=0) v=0; |
MartinJohnson | 11:1b3dc5581b1b | 30 | fb[y][x] = (fb[y][x] | (v<<4)); |
MartinJohnson | 11:1b3dc5581b1b | 31 | } |
MartinJohnson | 11:1b3dc5581b1b | 32 | } |
MartinJohnson | 11:1b3dc5581b1b | 33 | waitForRefresh(); |
MartinJohnson | 11:1b3dc5581b1b | 34 | vidNextBuffer(); |
MartinJohnson | 11:1b3dc5581b1b | 35 | if(buttonPress()) return; |
MartinJohnson | 11:1b3dc5581b1b | 36 | } |
MartinJohnson | 11:1b3dc5581b1b | 37 | } |
MartinJohnson | 11:1b3dc5581b1b | 38 | #define NBUBBLES 50 |
MartinJohnson | 11:1b3dc5581b1b | 39 | float bubblearray[NBUBBLES*6]; |
MartinJohnson | 11:1b3dc5581b1b | 40 | #define X 0 |
MartinJohnson | 11:1b3dc5581b1b | 41 | #define Y 1 |
MartinJohnson | 11:1b3dc5581b1b | 42 | #define VX 2 |
MartinJohnson | 11:1b3dc5581b1b | 43 | #define VY 3 |
MartinJohnson | 11:1b3dc5581b1b | 44 | #define R 4 |
MartinJohnson | 11:1b3dc5581b1b | 45 | #define CR 5 |
MartinJohnson | 11:1b3dc5581b1b | 46 | void bubbleUpdate(int nb, |
MartinJohnson | 11:1b3dc5581b1b | 47 | int touched, int width,int height,float dt,float gx, float gy) { |
MartinJohnson | 11:1b3dc5581b1b | 48 | float *mBubbles = bubblearray; |
MartinJohnson | 11:1b3dc5581b1b | 49 | for (int i=0;i<nb*6;i+=6) { |
MartinJohnson | 11:1b3dc5581b1b | 50 | float *bubble=mBubbles+i; |
MartinJohnson | 11:1b3dc5581b1b | 51 | bubble[X]+=bubble[VX]*dt*100; |
MartinJohnson | 11:1b3dc5581b1b | 52 | bubble[Y]+=bubble[VY]*dt*100; |
MartinJohnson | 11:1b3dc5581b1b | 53 | if (bubble[Y] < bubble[R] || bubble[Y] > height-bubble[R]) { |
MartinJohnson | 11:1b3dc5581b1b | 54 | bubble[Y]-=bubble[VY]*dt*100; |
MartinJohnson | 11:1b3dc5581b1b | 55 | bubble[VY]=-bubble[VY]; |
MartinJohnson | 11:1b3dc5581b1b | 56 | } |
MartinJohnson | 11:1b3dc5581b1b | 57 | if (bubble[X] < bubble[R] || bubble[X] > width-bubble[R]) { |
MartinJohnson | 11:1b3dc5581b1b | 58 | bubble[X]-=bubble[VX]*dt*100; |
MartinJohnson | 11:1b3dc5581b1b | 59 | bubble[VX]=-bubble[VX]; |
MartinJohnson | 11:1b3dc5581b1b | 60 | } |
MartinJohnson | 11:1b3dc5581b1b | 61 | if(i!=touched) { |
MartinJohnson | 11:1b3dc5581b1b | 62 | bubble[VX] += dt * gx * 10; |
MartinJohnson | 11:1b3dc5581b1b | 63 | bubble[VY] += dt * gy * 10; |
MartinJohnson | 11:1b3dc5581b1b | 64 | } |
MartinJohnson | 11:1b3dc5581b1b | 65 | } |
MartinJohnson | 11:1b3dc5581b1b | 66 | float x,y,r,x1,y1,r1,d,d1; |
MartinJohnson | 11:1b3dc5581b1b | 67 | float *bubble,*bubble1; |
MartinJohnson | 11:1b3dc5581b1b | 68 | for (int i=0;i<nb*6;i+=6) { |
MartinJohnson | 11:1b3dc5581b1b | 69 | bubble=mBubbles+i; |
MartinJohnson | 11:1b3dc5581b1b | 70 | x=bubble[X]; |
MartinJohnson | 11:1b3dc5581b1b | 71 | y=bubble[Y]; |
MartinJohnson | 11:1b3dc5581b1b | 72 | r=bubble[R]; |
MartinJohnson | 11:1b3dc5581b1b | 73 | bubble[CR]=r; |
MartinJohnson | 11:1b3dc5581b1b | 74 | for(int j=i+6;j<nb*6;j+=6) { |
MartinJohnson | 11:1b3dc5581b1b | 75 | bubble1=mBubbles+j; |
MartinJohnson | 11:1b3dc5581b1b | 76 | x1=bubble1[X]; |
MartinJohnson | 11:1b3dc5581b1b | 77 | y1=bubble1[Y]; |
MartinJohnson | 11:1b3dc5581b1b | 78 | r1=bubble1[R]; |
MartinJohnson | 11:1b3dc5581b1b | 79 | d=(x1-x); |
MartinJohnson | 11:1b3dc5581b1b | 80 | d1=(y1-y); |
MartinJohnson | 11:1b3dc5581b1b | 81 | d=d*d+d1*d1; |
MartinJohnson | 11:1b3dc5581b1b | 82 | d1=(r1+r); |
MartinJohnson | 11:1b3dc5581b1b | 83 | d1=d1*d1; |
MartinJohnson | 11:1b3dc5581b1b | 84 | float bncy=0.99f; |
MartinJohnson | 11:1b3dc5581b1b | 85 | if(d<d1) { |
MartinJohnson | 11:1b3dc5581b1b | 86 | d = sqrt(d); |
MartinJohnson | 11:1b3dc5581b1b | 87 | float sz = d - bubble1[CR]; |
MartinJohnson | 11:1b3dc5581b1b | 88 | if (sz < 4) |
MartinJohnson | 11:1b3dc5581b1b | 89 | sz = 4; |
MartinJohnson | 11:1b3dc5581b1b | 90 | if (sz < bubble[CR]) |
MartinJohnson | 11:1b3dc5581b1b | 91 | bubble[CR] = sz; |
MartinJohnson | 11:1b3dc5581b1b | 92 | float dx = x1 - x; |
MartinJohnson | 11:1b3dc5581b1b | 93 | float dy = y1 - y; |
MartinJohnson | 11:1b3dc5581b1b | 94 | if(d!=0) { |
MartinJohnson | 11:1b3dc5581b1b | 95 | dx = dx / d; |
MartinJohnson | 11:1b3dc5581b1b | 96 | dy = dy / d; |
MartinJohnson | 11:1b3dc5581b1b | 97 | } |
MartinJohnson | 11:1b3dc5581b1b | 98 | float displacement = (r + r1) - d; |
MartinJohnson | 11:1b3dc5581b1b | 99 | if (i != touched) { |
MartinJohnson | 11:1b3dc5581b1b | 100 | bubble[VX] = (bubble[VX] - bncy * dx * displacement) * 0.9f; |
MartinJohnson | 11:1b3dc5581b1b | 101 | bubble[VY] = (bubble[VY] - bncy * dy * displacement) * 0.9f; |
MartinJohnson | 11:1b3dc5581b1b | 102 | } |
MartinJohnson | 11:1b3dc5581b1b | 103 | if (j != touched) { |
MartinJohnson | 11:1b3dc5581b1b | 104 | bubble1[VX] = (bubble1[VX] + bncy * dx * displacement) * 0.9f; |
MartinJohnson | 11:1b3dc5581b1b | 105 | bubble1[VY] = (bubble1[VY] + bncy * dy * displacement) * 0.9f; |
MartinJohnson | 11:1b3dc5581b1b | 106 | } |
MartinJohnson | 11:1b3dc5581b1b | 107 | } |
MartinJohnson | 11:1b3dc5581b1b | 108 | } |
MartinJohnson | 11:1b3dc5581b1b | 109 | |
MartinJohnson | 11:1b3dc5581b1b | 110 | } |
MartinJohnson | 11:1b3dc5581b1b | 111 | } |
MartinJohnson | 11:1b3dc5581b1b | 112 | |
MartinJohnson | 11:1b3dc5581b1b | 113 | void bubble_demo() { |
MartinJohnson | 11:1b3dc5581b1b | 114 | int16_t accel[3]; |
MartinJohnson | 11:1b3dc5581b1b | 115 | MemsConfig(); |
MartinJohnson | 11:1b3dc5581b1b | 116 | vidClearScreen(); |
MartinJohnson | 11:1b3dc5581b1b | 117 | for(int i=0;i<NBUBBLES;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 118 | int r=rand()%10+4; |
MartinJohnson | 11:1b3dc5581b1b | 119 | bubblearray[i*6+X]=rand()%(VID_HSIZE-2*r)+r; |
MartinJohnson | 11:1b3dc5581b1b | 120 | bubblearray[i*6+Y]=rand()%(VID_VSIZE-2*r)+r; |
MartinJohnson | 11:1b3dc5581b1b | 121 | bubblearray[i*6+R]=r; |
MartinJohnson | 11:1b3dc5581b1b | 122 | bubblearray[i*6+VX]=0; |
MartinJohnson | 11:1b3dc5581b1b | 123 | bubblearray[i*6+VY]=0; |
MartinJohnson | 11:1b3dc5581b1b | 124 | bubblearray[i*6+CR]=bubblearray[i*6+R]; |
MartinJohnson | 11:1b3dc5581b1b | 125 | } |
MartinJohnson | 11:1b3dc5581b1b | 126 | while(1) { |
MartinJohnson | 11:1b3dc5581b1b | 127 | for(int i=0;i<NBUBBLES;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 128 | int col=(i%14)+1; |
MartinJohnson | 11:1b3dc5581b1b | 129 | if(col==7) col=6; |
MartinJohnson | 11:1b3dc5581b1b | 130 | gdiSetColour(col); |
MartinJohnson | 11:1b3dc5581b1b | 131 | gdiFilledCircle((u16)bubblearray[i*6+X],(u16)bubblearray[i*6+Y],(u16)bubblearray[i*6+CR],0); |
MartinJohnson | 11:1b3dc5581b1b | 132 | gdiSetColour(15); |
MartinJohnson | 11:1b3dc5581b1b | 133 | gdiCircle((u16)bubblearray[i*6+X],(u16)bubblearray[i*6+Y],(u16)bubblearray[i*6+CR],0); |
MartinJohnson | 11:1b3dc5581b1b | 134 | } |
MartinJohnson | 11:1b3dc5581b1b | 135 | waitForRefresh(); |
MartinJohnson | 11:1b3dc5581b1b | 136 | vidNextBuffer(); |
MartinJohnson | 11:1b3dc5581b1b | 137 | ReadAccelerometer(accel); |
MartinJohnson | 11:1b3dc5581b1b | 138 | bubbleUpdate(NBUBBLES,-1,VID_HSIZE,VID_VSIZE,0.005,accel[1]/320.0f,accel[0]/320.0f); |
MartinJohnson | 11:1b3dc5581b1b | 139 | if(buttonPress()) return; |
MartinJohnson | 11:1b3dc5581b1b | 140 | } |
MartinJohnson | 11:1b3dc5581b1b | 141 | |
MartinJohnson | 11:1b3dc5581b1b | 142 | } |
MartinJohnson | 11:1b3dc5581b1b | 143 | |
MartinJohnson | 11:1b3dc5581b1b | 144 | typedef struct {float x;float y;} vec2_t; |
MartinJohnson | 11:1b3dc5581b1b | 145 | |
MartinJohnson | 11:1b3dc5581b1b | 146 | typedef struct {float x;float y;float z;} vec3_t; |
MartinJohnson | 11:1b3dc5581b1b | 147 | |
MartinJohnson | 11:1b3dc5581b1b | 148 | #define TRANSLATE(v,a,b) {v.x+=a;v.y+=b;} |
MartinJohnson | 11:1b3dc5581b1b | 149 | #define SCALE(v,s) {v.x*=s;v.y*=s;} |
MartinJohnson | 11:1b3dc5581b1b | 150 | #define ROTATE(v,r) {float tx=v.x;v.x=v.x*cos(r)-v.y*sin(r);v.y=tx*sin(r)+v.y*cos(r);} |
MartinJohnson | 11:1b3dc5581b1b | 151 | |
MartinJohnson | 11:1b3dc5581b1b | 152 | extern const u8 gdiSystemFont[]; |
MartinJohnson | 11:1b3dc5581b1b | 153 | |
MartinJohnson | 11:1b3dc5581b1b | 154 | void rotozoom() { |
MartinJohnson | 11:1b3dc5581b1b | 155 | unsigned frame=0; |
MartinJohnson | 11:1b3dc5581b1b | 156 | vec2_t v[3]; |
MartinJohnson | 11:1b3dc5581b1b | 157 | float mx=1,my=1; |
MartinJohnson | 11:1b3dc5581b1b | 158 | while(!buttonPress()) { |
MartinJohnson | 11:1b3dc5581b1b | 159 | float s=sin(frame/63.0)/4+0.4f; |
MartinJohnson | 11:1b3dc5581b1b | 160 | float tx=cos(frame/59.0)*50; |
MartinJohnson | 11:1b3dc5581b1b | 161 | float ty=sin(frame/50.0)*50; |
MartinJohnson | 11:1b3dc5581b1b | 162 | v[0].x=-VID_HSIZE/2;v[0].y=-VID_VSIZE/2; |
MartinJohnson | 11:1b3dc5581b1b | 163 | v[1].x=VID_HSIZE/2;v[1].y=-VID_VSIZE/2; |
MartinJohnson | 11:1b3dc5581b1b | 164 | v[2].x=-VID_HSIZE/2;v[2].y=VID_VSIZE/2; |
MartinJohnson | 11:1b3dc5581b1b | 165 | for(int i=0;i<3;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 166 | SCALE(v[i],s); |
MartinJohnson | 11:1b3dc5581b1b | 167 | TRANSLATE(v[i],tx,ty); |
MartinJohnson | 11:1b3dc5581b1b | 168 | ROTATE(v[i],frame*.01f); |
MartinJohnson | 11:1b3dc5581b1b | 169 | } |
MartinJohnson | 11:1b3dc5581b1b | 170 | float xix=(v[1].x-v[0].x)*(1.0/VID_HSIZE); |
MartinJohnson | 11:1b3dc5581b1b | 171 | float xiy=(v[1].y-v[0].y)*(1.0/VID_HSIZE); |
MartinJohnson | 11:1b3dc5581b1b | 172 | for(int y=0;y<VID_VSIZE;y++) { |
MartinJohnson | 11:1b3dc5581b1b | 173 | float yr=(float)y/VID_VSIZE; |
MartinJohnson | 11:1b3dc5581b1b | 174 | float posx=v[0].x*(1-yr)+v[2].x*(yr); |
MartinJohnson | 11:1b3dc5581b1b | 175 | float posy=v[0].y*(1-yr)+v[2].y*(yr); |
MartinJohnson | 11:1b3dc5581b1b | 176 | for(int x=0;x<VID_HSIZE;x++) { |
MartinJohnson | 11:1b3dc5581b1b | 177 | fb[y][x]|=((unsigned)((int)posx)^(unsigned)((int)posy))<<4; |
MartinJohnson | 11:1b3dc5581b1b | 178 | // fb[y][x]|=((((unsigned)posx)%64)^((unsigned)posy))<<4; |
MartinJohnson | 11:1b3dc5581b1b | 179 | |
MartinJohnson | 11:1b3dc5581b1b | 180 | // fb[y][x]|=(gdiSystemFont[((unsigned)posx)%64+16]+((unsigned)posy))<<4; |
MartinJohnson | 11:1b3dc5581b1b | 181 | posx+=xix; |
MartinJohnson | 11:1b3dc5581b1b | 182 | posy+=xiy; |
MartinJohnson | 11:1b3dc5581b1b | 183 | } |
MartinJohnson | 11:1b3dc5581b1b | 184 | } |
MartinJohnson | 11:1b3dc5581b1b | 185 | waitForRefresh(); |
MartinJohnson | 11:1b3dc5581b1b | 186 | vidNextBuffer(); |
MartinJohnson | 11:1b3dc5581b1b | 187 | frame++; |
MartinJohnson | 11:1b3dc5581b1b | 188 | } |
MartinJohnson | 11:1b3dc5581b1b | 189 | } |
MartinJohnson | 11:1b3dc5581b1b | 190 | #define P 100 |
MartinJohnson | 11:1b3dc5581b1b | 191 | void cube_demo() { |
MartinJohnson | 11:1b3dc5581b1b | 192 | const int max=VID_HSIZE/6; |
MartinJohnson | 11:1b3dc5581b1b | 193 | |
MartinJohnson | 11:1b3dc5581b1b | 194 | vec3_t virtex[8]; |
MartinJohnson | 11:1b3dc5581b1b | 195 | |
MartinJohnson | 11:1b3dc5581b1b | 196 | for(int i=0;i<8;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 197 | virtex[i].x=(i&1)?max:-max; |
MartinJohnson | 11:1b3dc5581b1b | 198 | virtex[i].y=(i&2)?max:-max; |
MartinJohnson | 11:1b3dc5581b1b | 199 | virtex[i].z=(i&4)?max:-max; |
MartinJohnson | 11:1b3dc5581b1b | 200 | } |
MartinJohnson | 11:1b3dc5581b1b | 201 | int frame=0; |
MartinJohnson | 11:1b3dc5581b1b | 202 | float r=0.01,r1=0.016,r2=0.02; |
MartinJohnson | 11:1b3dc5581b1b | 203 | while(!buttonPress()) { |
MartinJohnson | 11:1b3dc5581b1b | 204 | for(int i=0;i<8;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 205 | float tx=virtex[i].x; |
MartinJohnson | 11:1b3dc5581b1b | 206 | virtex[i].x=virtex[i].x*cos(r)-virtex[i].y*sin(r); |
MartinJohnson | 11:1b3dc5581b1b | 207 | virtex[i].y=tx*sin(r)+virtex[i].y*cos(r); |
MartinJohnson | 11:1b3dc5581b1b | 208 | float ty=virtex[i].y; |
MartinJohnson | 11:1b3dc5581b1b | 209 | virtex[i].y=virtex[i].y*cos(r1)-virtex[i].z*sin(r1); |
MartinJohnson | 11:1b3dc5581b1b | 210 | virtex[i].z=ty*sin(r1)+virtex[i].z*cos(r1); |
MartinJohnson | 11:1b3dc5581b1b | 211 | tx=virtex[i].x; |
MartinJohnson | 11:1b3dc5581b1b | 212 | virtex[i].x=virtex[i].x*cos(r2)-virtex[i].z*sin(r2); |
MartinJohnson | 11:1b3dc5581b1b | 213 | virtex[i].z=tx*sin(r2)+virtex[i].z*cos(r2); |
MartinJohnson | 11:1b3dc5581b1b | 214 | } |
MartinJohnson | 11:1b3dc5581b1b | 215 | int max=0; |
MartinJohnson | 11:1b3dc5581b1b | 216 | for(int i=1;i<8;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 217 | if(virtex[i].z>virtex[max].z) { |
MartinJohnson | 11:1b3dc5581b1b | 218 | max=i; |
MartinJohnson | 11:1b3dc5581b1b | 219 | } |
MartinJohnson | 11:1b3dc5581b1b | 220 | } |
MartinJohnson | 11:1b3dc5581b1b | 221 | gdiSetColour(7); |
MartinJohnson | 11:1b3dc5581b1b | 222 | gdiDrawTextEx(75, VID_VSIZE-32, "Cube Demo", GDI_ROP_COPY); |
MartinJohnson | 11:1b3dc5581b1b | 223 | gdiSetColour(6); |
MartinJohnson | 11:1b3dc5581b1b | 224 | for(int i=0;i<8;i++) { |
MartinJohnson | 11:1b3dc5581b1b | 225 | for(int j=i+1;j<8;j++) { |
MartinJohnson | 11:1b3dc5581b1b | 226 | int ij=i^j; |
MartinJohnson | 11:1b3dc5581b1b | 227 | if((ij==1 || ij==2 || ij==4)) { |
MartinJohnson | 11:1b3dc5581b1b | 228 | gdiLine(0, VID_HSIZE/2+virtex[i].x+(virtex[i].x*virtex[i].z)/P, VID_VSIZE/2+virtex[i].y+(virtex[i].y*virtex[i].z)/P , |
MartinJohnson | 11:1b3dc5581b1b | 229 | VID_HSIZE/2+virtex[j].x+(virtex[j].x*virtex[j].z)/P, VID_VSIZE/2+virtex[j].y+(virtex[j].y*virtex[j].z)/P, 0); |
MartinJohnson | 11:1b3dc5581b1b | 230 | } |
MartinJohnson | 11:1b3dc5581b1b | 231 | } |
MartinJohnson | 11:1b3dc5581b1b | 232 | |
MartinJohnson | 11:1b3dc5581b1b | 233 | } |
MartinJohnson | 11:1b3dc5581b1b | 234 | waitForRefresh(); |
MartinJohnson | 11:1b3dc5581b1b | 235 | vidNextBuffer(); |
MartinJohnson | 11:1b3dc5581b1b | 236 | frame++; |
MartinJohnson | 11:1b3dc5581b1b | 237 | } |
MartinJohnson | 11:1b3dc5581b1b | 238 | |
MartinJohnson | 11:1b3dc5581b1b | 239 | } |