Demo of low res colour vga video for stm32f3 discovery board

Dependencies:   STM32F3-Discovery-minimal

Fork of Space_Invaders_Demo by Martin Johnson

moredemos.c

Committer:
MartinJohnson
Date:
2019-04-03
Revision:
17:833f1b69e11d
Parent:
14:3035b3271395

File content as of revision 17:833f1b69e11d:

#include "stm32f30x.h"
#include "video.h"
#include <stdlib.h>
#include <math.h>
#include "sys.h"
#include "gdi.h"

typedef unsigned Unit;

#define cols VID_HSIZE
#define rows VID_VSIZE
#define bits 1

extern char *fb[VID_VSIZE];

void conway_demo() {
	vidClearScreen();
	for (int i=0;i<rows*cols/8;i=i+1)
	    fb[rand()%rows][rand()%cols]=(rand()%7)|1; 
	while(1) {
		for (int y=1;y<rows-2;y=y+1) {
	  		for (int x=1;x<cols-2;x=x+1) {
				int v=fb[y][x]&7;
				int count = (fb[y][x+1]&1)+(fb[y+1][x]&1)+
				(fb[y][x-1]&1)+(fb[y-1][x]&1)+
				(fb[y+1][x+1]&1)+(fb[y-1][x+1]&1) + 
				(fb[y-1][x-1]&1)+(fb[y+1][x-1]&1); 
				if (count==3 && v==0) v=(rand()%7)|1; 
				if ((count<2 || count>3) && v!=0) v=0;
				fb[y][x] = (fb[y][x] | (v<<4));
			}
	    }
	    waitForRefresh();
	    vidNextBuffer();
	    if(buttonPress()) return;
  	}
}
#define NBUBBLES 50
float bubblearray[NBUBBLES*6];
#define X 0
#define Y 1
#define VX 2
#define VY 3
#define R 4
#define CR 5
void bubbleUpdate(int nb,
                        int touched, int width,int height,float dt,float gx, float gy) {
    float *mBubbles = bubblearray;
    for (int i=0;i<nb*6;i+=6) {
        float *bubble=mBubbles+i;
        bubble[X]+=bubble[VX]*dt*100;
        bubble[Y]+=bubble[VY]*dt*100;
        if (bubble[Y] < bubble[R] || bubble[Y] > height-bubble[R]) {
            bubble[Y]-=bubble[VY]*dt*100;
            bubble[VY]=-bubble[VY];
        }
        if (bubble[X] < bubble[R] || bubble[X] > width-bubble[R]) {
            bubble[X]-=bubble[VX]*dt*100;
            bubble[VX]=-bubble[VX];
        }
        if(i!=touched) {
            bubble[VX] += dt * gx * 10;
            bubble[VY] += dt * gy * 10;
        }
    }
    float x,y,r,x1,y1,r1,d,d1;
    float *bubble,*bubble1;
    for (int i=0;i<nb*6;i+=6) {
        bubble=mBubbles+i;
        x=bubble[X];
        y=bubble[Y];
        r=bubble[R];
        bubble[CR]=r;
        for(int j=i+6;j<nb*6;j+=6) {
            bubble1=mBubbles+j;
            x1=bubble1[X];
            y1=bubble1[Y];
            r1=bubble1[R];
            d=(x1-x);
            d1=(y1-y);
            d=d*d+d1*d1;
            d1=(r1+r);
            d1=d1*d1;
            float bncy=0.99f;
            if(d<d1) {
                d = sqrt(d);
                float sz = d - bubble1[CR];
                if (sz < 4)
                    sz = 4;
                if (sz < bubble[CR])
                    bubble[CR] = sz;
                float dx = x1 - x;
                float dy = y1 - y;
                if(d!=0) {
                    dx = dx / d;
                    dy = dy / d;
                }
                float displacement = (r + r1) - d;
                if (i != touched) {
                    bubble[VX] = (bubble[VX] - bncy * dx * displacement) * 0.9f;
                    bubble[VY] = (bubble[VY] - bncy * dy * displacement) * 0.9f;
                }
                if (j != touched) {
                    bubble1[VX] = (bubble1[VX] + bncy * dx * displacement) * 0.9f;
                    bubble1[VY] = (bubble1[VY] + bncy * dy * displacement) * 0.9f;
                }
            }
        }

    }
}

void bubble_demo() {
	int16_t accel[3];
    MemsConfig();
	vidClearScreen();
	for(int i=0;i<NBUBBLES;i++) {
		int r=rand()%10+4;
		bubblearray[i*6+X]=rand()%(VID_HSIZE-2*r)+r;
		bubblearray[i*6+Y]=rand()%(VID_VSIZE-2*r)+r;
		bubblearray[i*6+R]=r;
		bubblearray[i*6+VX]=0;
		bubblearray[i*6+VY]=0;
		bubblearray[i*6+CR]=bubblearray[i*6+R];
	}
	while(1) {
		for(int i=0;i<NBUBBLES;i++) {
			int col=(i%14)+1;
			if(col==7) col=6;
			gdiSetColour(col);
			gdiFilledCircle((u16)bubblearray[i*6+X],(u16)bubblearray[i*6+Y],(u16)bubblearray[i*6+CR],0);
			gdiSetColour(15);
			gdiCircle((u16)bubblearray[i*6+X],(u16)bubblearray[i*6+Y],(u16)bubblearray[i*6+CR],0);
		}
		waitForRefresh();
	    vidNextBuffer();
	    ReadAccelerometer(accel);
		bubbleUpdate(NBUBBLES,-1,VID_HSIZE,VID_VSIZE,0.005,accel[1]/320.0f,accel[0]/320.0f);
		if(buttonPress()) return;
	}
	
}

typedef struct {float x;float y;} vec2_t;

typedef struct {float x;float y;float z;} vec3_t;

#define TRANSLATE(v,a,b) {v.x+=a;v.y+=b;}
#define SCALE(v,s) {v.x*=s;v.y*=s;}
#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);}

extern const u8 gdiSystemFont[];

void rotozoom() {
	unsigned frame=0;
	vec2_t v[3];
	float mx=1,my=1;
	while(!buttonPress()) {
		float s=sin(frame/63.0)/4+0.4f;
		float tx=cos(frame/59.0)*50;
		float ty=sin(frame/50.0)*50;
		v[0].x=-VID_HSIZE/2;v[0].y=-VID_VSIZE/2;
		v[1].x=VID_HSIZE/2;v[1].y=-VID_VSIZE/2;
		v[2].x=-VID_HSIZE/2;v[2].y=VID_VSIZE/2;
		for(int i=0;i<3;i++) {
			SCALE(v[i],s);
			TRANSLATE(v[i],tx,ty);
			ROTATE(v[i],frame*.01f);
		}
		float xix=(v[1].x-v[0].x)*(1.0/VID_HSIZE);
		float xiy=(v[1].y-v[0].y)*(1.0/VID_HSIZE);
		for(int y=0;y<VID_VSIZE;y++) {
			float yr=(float)y/VID_VSIZE;
			float posx=v[0].x*(1-yr)+v[2].x*(yr);
			float posy=v[0].y*(1-yr)+v[2].y*(yr);
			for(int x=0;x<VID_HSIZE;x++) {
				fb[y][x]|=((unsigned)((int)posx)^(unsigned)((int)posy))<<4;
		//		fb[y][x]|=((((unsigned)posx)%64)^((unsigned)posy))<<4;

//				fb[y][x]|=(gdiSystemFont[((unsigned)posx)%64+16]+((unsigned)posy))<<4;
				posx+=xix;
				posy+=xiy;
			}
		}
		waitForRefresh();
	    vidNextBuffer();
	    frame++;
	}
}
#define P 100
void cube_demo() {
	const int max=VID_HSIZE/6;
	
	vec3_t virtex[8];
	
	for(int i=0;i<8;i++) {
		virtex[i].x=(i&1)?max:-max;
		virtex[i].y=(i&2)?max:-max;
		virtex[i].z=(i&4)?max:-max;
	}
	int frame=0;
	float r=0.01,r1=0.016,r2=0.02;
	while(!buttonPress()) {
		for(int i=0;i<8;i++) {
			float tx=virtex[i].x;
			virtex[i].x=virtex[i].x*cos(r)-virtex[i].y*sin(r);
			virtex[i].y=tx*sin(r)+virtex[i].y*cos(r);
			float ty=virtex[i].y;
			virtex[i].y=virtex[i].y*cos(r1)-virtex[i].z*sin(r1);
			virtex[i].z=ty*sin(r1)+virtex[i].z*cos(r1);
			tx=virtex[i].x;
			virtex[i].x=virtex[i].x*cos(r2)-virtex[i].z*sin(r2);
			virtex[i].z=tx*sin(r2)+virtex[i].z*cos(r2);
		}
		int max=0;
		for(int i=1;i<8;i++) {
			if(virtex[i].z>virtex[max].z) {
				max=i;
			}
		}
		gdiSetColour(7);
		gdiDrawTextEx(75, VID_VSIZE-32, "Cube Demo", GDI_ROP_COPY);
		gdiSetColour(6);
		for(int i=0;i<8;i++) {
				for(int j=i+1;j<8;j++) {
					int ij=i^j;
					if((ij==1 || ij==2 || ij==4)) {
						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 ,
						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);
					}
				}
			
		}
		waitForRefresh();
	    vidNextBuffer();
	    frame++;
	}
	
}