Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of manworm_ticker_tv by
main.cpp
- Committer:
- bwang
- Date:
- 2017-11-20
- Revision:
- 5:2859a892497f
- Parent:
- 4:02e3ae7a3aea
- Child:
- 6:0a34891a82c7
File content as of revision 5:2859a892497f:
#include "mbed.h" #define V_RES 220 #define H_RES 100 #include <math.h> #define X_MIN 24 #define X_MAX (76+18) #define Y_MIN 7 #define Y_MAX (V_RES/4 - 15) #define SX_MIN 30 #define SX_MAX 95 #define SY_MIN 10 #define SY_MAX 48 #define Y_0 ( (Y_MIN + Y_MAX)/2 ) #define X_0 ( (X_MIN + X_MAX)/2 ) #define SIDE 8 #define HSIDE 8 #define SIN_V (0.03) #define COS_V (0.99955f) #define BX_0 30 #define BY_0 (V_RES/4 - 15) #define BX 42 #define BY 15 #define BY2 9 #define DEMO_LENGTH 600 DigitalOut sout(D8); //sync DigitalOut vout(D7); //video Ticker t; uint8_t draw_line_inv = 0; //9x42 uint8_t miters[] = { 1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0, 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0, 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,0,0, 1,1,1,1,1,0,1,0,0,1,1,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,1,1,0,0,0,1,1,1,1,1, 1,0,1,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1,0,1, 1,0,1,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,1,0,1,0,0,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1, 1,0,1,0,1,0,0,1,1,0,1,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1, }; uint8_t tv[] = { 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0}; uint8_t chr_A[] = { 0,0,1,1,0,0, 0,1,0,0,1,0, 1,0,0,0,0,1, 1,1,1,1,1,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1,}; uint8_t chr_D[] = { 1,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,0,}; uint8_t chr_F[] = { 1,1,1,1,1,1, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,1,1, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0,}; uint8_t chr_G[] = { 0,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,0, 1,0,0,1,1,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 0,1,1,1,1,0,}; uint8_t chr_H[] = { 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1,}; uint8_t chr_M[] = { 1,0,0,0,0,1, 1,1,0,0,1,1, 1,0,1,1,0,1, 1,0,1,1,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1,}; uint8_t chr_N[] = { 1,0,0,0,0,1, 1,1,0,0,0,1, 1,0,1,0,0,1, 1,0,0,1,0,1, 1,0,0,0,1,1, 1,0,0,0,0,1, 1,0,0,0,0,1,}; uint8_t chr_O[] = { 0,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 0,1,1,1,1,0,}; uint8_t chr_P[] = { 1,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,1,1,1,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0,}; uint8_t chr_R[] = { 1,1,1,1,1,0, 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,1,0, 1,0,0,1,0,0, 1,0,0,0,1,0, 1,0,0,0,0,1,}; uint8_t chr_S[] = { 0,1,1,1,1,1, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,1,1,1,1,0, 0,0,0,0,0,1, 0,0,0,0,0,1, 1,1,1,1,1,0,}; uint8_t chr_V[] = { 1,0,0,0,0,1, 1,0,0,0,0,1, 1,0,0,0,0,1, 0,1,0,0,1,0, 0,1,0,0,1,0, 0,1,0,0,1,0, 0,0,1,1,0,0,}; uint8_t sprite_tree[] = { 0,0,0,1,0,0,0, 0,0,1,1,1,0,0, 0,1,1,1,1,1,0, 1,1,1,1,1,1,1, 0,1,1,1,1,1,0, 1,1,1,1,1,1,1, 0,0,0,1,0,0,0, 0,0,0,1,0,0,0,}; uint8_t sprite_man[] = { 0,0,0,1,0,0,0, 0,0,1,1,1,0,0, 0,0,0,1,0,0,1, 0,1,1,1,1,1,0, 1,0,1,1,1,0,0, 0,0,1,1,1,0,0, 0,1,0,0,0,1,0, 0,1,0,0,0,1,0}; uint16_t l=0; //current line of scan uint8_t im_line_s[H_RES]; //image sync buffer uint8_t bl_line_s[H_RES]; //lower 1/4 of screen sync buffer uint8_t bl_line_v[H_RES]; //lower 1/4 of screen video buffer uint8_t vb_line_s[H_RES]; //vertical sync, sync buffer uint8_t vb_line_v[H_RES]; //vertical sync, video buffer float cube_a[3] = {15.f, 0.f, 0.f}; float cube_pts[8][3] = { {SIDE,SIDE,HSIDE}, {-SIDE,SIDE,HSIDE}, {-SIDE,-SIDE,HSIDE}, {SIDE,-SIDE,HSIDE}, {SIDE,-SIDE,-HSIDE}, {-SIDE,-SIDE,-HSIDE}, {-SIDE,SIDE,-HSIDE}, {SIDE,SIDE,-HSIDE} }; float x_rot[3][3] = { {1.f, 0.f, 0.f}, {0.f, COS_V, -SIN_V}, {0.f, SIN_V, COS_V} }; float y_rot[3][3] = { {COS_V, 0.f, SIN_V}, {0.f, 1.f, 0.f}, {-SIN_V, 0, COS_V} }; float z_rot[3][3] = { {COS_V, -SIN_V, 0.f}, {SIN_V, COS_V, 0.f}, {0.f, 0.f, 1.f} }; uint8_t im_line_va[H_RES*V_RES]; //image buffer //pong variables #define PADDLE_LEN 10 float p1 = (SY_MIN+SY_MAX)/2-PADDLE_LEN/2, p2 = (SY_MIN+SY_MAX)/2-PADDLE_LEN/2; float p1v = 0.1, p2v = -0.1; float bx = (SX_MIN+SX_MAX)/2, by = (SY_MIN+SY_MAX)/2; float bxv = 0.03, byv = 0.03; int s1 = 0, s2 = 0; //fish variables #define FDEATH_RESET 30000 float fx = (SX_MAX+SX_MIN)/2.f, fy = (SY_MIN+SY_MAX)/2.f, fv = 0.02f, ftheta = 0.0, fa = 0.002; float uv = 0.005; float ux[8] = {53,70,78,78,70,53,45,45}; float uy[8] = {10,10,20,35,50,50,35,20}; float uvx[8] = {-1,1,1,1,1,-1,-1,-1}; float uvy[8] = {1,1,1,-1,-1,-1,-1,1}; int ulive[8] = {1,1,1,1,1,1,1,1}; //tunnel variables #define TUN_LEN (SY_MAX - SY_MIN) uint8_t tunnel[TUN_LEN]; float tunnp = 50; int tundir = 1; int fdeath_ticker = FDEATH_RESET; float fs = 0; DigitalIn p1_in(A1); DigitalIn p2_in(A0); void make_checkerboard() { for(int i = 0; i < H_RES; i++) for(int j = 0; j < V_RES; j++) im_line_va[i+j*H_RES] = 0*((i > 20) && (i < 98)) && ((j%2) ^ (i%2)); //checkerboard } void clr() { for(int i = 0; i < H_RES; i++) for(int j = 0; j < V_RES; j++) im_line_va[i+j*H_RES] = 0; } void init_buffers() { clr(); for(int i = 0; i < H_RES; i++) { im_line_s[i] = 1; bl_line_s[i] = 1; bl_line_v[i] = 0; vb_line_s[i] = 0; vb_line_v[i] = 0; } im_line_s[0] = 0; im_line_s[1] = 0; im_line_s[2] = 0; bl_line_s[0] = 0; vb_line_s[0] = 1; bl_line_s[1] = 0; vb_line_s[1] = 1; } void isr() { uint8_t nop = 0; //use nops or use wait_us uint8_t* sptr; //pointer to sync buffer for line uint8_t* vptr; //pointer to video buffer for line if(l < V_RES){ vptr = im_line_va + ((l/4)*H_RES); sptr = im_line_s; nop = 1; } //pick line buffers else if(l < 254){ vptr = bl_line_v; sptr = bl_line_s; nop = 0; } else{ vptr = vb_line_v; sptr = vb_line_s; nop = 1;} uint8_t lmax = nop?H_RES:12; //number of columns for(uint8_t i = 0; i < lmax; i++) //loop over each column { vout = vptr[i]; //set output pins sout = sptr[i]; if(nop) //nop delay { asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");//asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); } else {wait_us(1); if(i > 2) i++;} //wait delay } //move to next line l++; if(l > 255) l = 0; } //coordinates for bouncing ball int k = 0; uint16_t px = X_0*10; uint16_t py = Y_0*10; uint16_t vx = 10; uint16_t vy = 10; uint16_t px2 = X_0*10 + 80; uint16_t py2 = Y_0*10 - 40; uint16_t vx2 = 3; uint16_t vy2 = -4; int16_t sign(int16_t a) { if(a > 0) return 1; if(a < 0) return -1; return 0; } void draw_vert(int16_t y0, int16_t y1, int16_t x0) { for(int16_t i = y0; i < y1; i++) im_line_va[H_RES*i + x0] = 1; } void draw_horiz(int16_t x0, int16_t x1, int16_t y0) { for(int16_t i = x0; i < x1; i++) im_line_va[H_RES*y0 + i] = 1; } int16_t imin(int16_t a, int16_t b) { if(a<b) return a; return b; } int16_t imax(int16_t a, int16_t b) { if(a>b) return a; return b; } void draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1) { if(x0 > x1){ x0 = x0 ^ x1; x1 = x1^x0; x0 = x0^x1;y0 = y0 ^ y1; y1 = y1^y0; y0 = y0^y1; } if(x0 == x1){draw_vert(y0,y1,x0);} if(y0 == y1){draw_horiz(x0,x1,y0);} int16_t dx = x1 - x0; int16_t dy = y1 - y0; float derr = fabs((float)(dy)/(float)(dx)); float err = 0.f; int16_t y = y0; for(int16_t x = x0; x < x1; x++) { //plotxy im_line_va[H_RES*y + x] = !draw_line_inv; err += derr; while(err >= 0.5f) { y += sign(dy); im_line_va[H_RES*y + x] = !draw_line_inv; err -= 1.f; } } } void draw_cube(float cp[][3]) { for(uint8_t i = 0; i < 7; i++) { draw_line((int16_t)cp[i][0]+cube_a[0]+X_0,(int16_t)cp[i][1]+cube_a[1]+Y_0,(int16_t)cp[i+1][0]+cube_a[0]+X_0,(int16_t)cp[i+1][1]+cube_a[1]+Y_0); } draw_line((int16_t)cp[0][0]+cube_a[0]+X_0,(int16_t)cp[0][1]+cube_a[1]+Y_0,(int16_t)cp[3][0]+cube_a[0]+X_0,(int16_t)cp[3][1]+cube_a[1]+Y_0); draw_line((int16_t)cp[4][0]+cube_a[0]+X_0,(int16_t)cp[4][1]+cube_a[1]+Y_0,(int16_t)cp[7][0]+cube_a[0]+X_0,(int16_t)cp[7][1]+cube_a[1]+Y_0); draw_line((int16_t)cp[0][0]+cube_a[0]+X_0,(int16_t)cp[0][1]+cube_a[1]+Y_0,(int16_t)cp[7][0]+cube_a[0]+X_0,(int16_t)cp[7][1]+cube_a[1]+Y_0); draw_line((int16_t)cp[1][0]+cube_a[0]+X_0,(int16_t)cp[1][1]+cube_a[1]+Y_0,(int16_t)cp[6][0]+cube_a[0]+X_0,(int16_t)cp[6][1]+cube_a[1]+Y_0); draw_line((int16_t)cp[2][0]+cube_a[0]+X_0,(int16_t)cp[2][1]+cube_a[1]+Y_0,(int16_t)cp[5][0]+cube_a[0]+X_0,(int16_t)cp[5][1]+cube_a[1]+Y_0); } void apply_rot(float cp[][3], float r[][3]) { for(uint8_t pti = 0; pti < 8; pti++) { float* cpt = cp[pti]; float xn = r[0][0] * cpt[0] + r[0][1] * cpt[1] + r[0][2] * cpt[2]; float yn = r[1][0] * cpt[0] + r[1][1] * cpt[1] + r[1][2] * cpt[2]; float zn = r[2][0] * cpt[0] + r[2][1] * cpt[1] + r[2][2] * cpt[2]; cpt[0] = xn; cpt[1] = yn; cpt[2] = zn; } } void apply_xf_rot(float cpt[], float r[][3]) { float xn = r[0][0] * cpt[0] + r[0][1] * cpt[1] + r[0][2] * cpt[2]; float yn = r[1][0] * cpt[0] + r[1][1] * cpt[1] + r[1][2] * cpt[2]; float zn = r[2][0] * cpt[0] + r[2][1] * cpt[1] + r[2][2] * cpt[2]; cpt[0] = xn; cpt[1] = yn; cpt[2] = zn; } void draw_v_check(int8_t r,uint8_t tt) { for(int i = 0; i < H_RES; i++) for(int j = 0; j < V_RES; j++) im_line_va[i+j*H_RES] = (((i > 20) && (i < 98)) && ( tt ^(((j%(r*2))>=r) ^ ((i%(r*2)))>=r))); //checkerboard } int jjj = 0; int f_count = DEMO_LENGTH + 10; void draw_cube_spin(int kkkk); //update bouncing balls void draw_blank() { for(uint16_t h = X_MIN; h < X_MAX; h++) { for(uint16_t v = Y_MIN; v < Y_MAX+15; v++) { im_line_va[v*H_RES + h] = 0; } } } void wipe(); void update_image() { //delay k++; if(k%4000) return; f_count++; if(f_count < DEMO_LENGTH/2) { draw_cube_spin(0); } else if(f_count < DEMO_LENGTH) { draw_cube_spin(0); } else if(f_count < DEMO_LENGTH * 1.22) { for(int k = 1; k < 10; k++) //for(int kk = 1; kk < 3; kk++) { draw_v_check(k,1); draw_v_check(k,1); draw_v_check(k,0); draw_v_check(k,0); } draw_v_check(1,0); wipe(); f_count = 0; } } void wipe() { for(int v = Y_MIN; v < Y_MAX+15; v++) { for(uint16_t h = X_MIN; h < X_MAX; h++) { im_line_va[v*H_RES+h] = 1; } wait(.01); } for(int v = Y_MAX+15; v > Y_MIN; v--) { for(uint16_t h = X_MIN; h < X_MAX; h++) { im_line_va[v*H_RES+h] = 0; } wait(.005); } for(uint16_t h = X_MIN; h < X_MAX; h++) { for(uint16_t v = Y_MIN; v < Y_MAX+15; v++) { im_line_va[v*H_RES + h] = 1; } wait(.005); } for(uint16_t h = X_MIN; h < X_MAX; h++) { for(uint16_t v = Y_MIN; v < Y_MAX+15; v++) { im_line_va[v*H_RES + h] = 0; } wait(.005); } for(int v = Y_MIN; v < Y_MAX+15; v++) { for(uint16_t h = X_MIN; h < X_MAX; h++) { im_line_va[v*H_RES+h] = 0; } } } void draw_cube_spin(int kkkk) { draw_line_inv = kkkk; //blank for(uint16_t h = X_MIN; h < X_MAX; h++) { for(uint16_t v = Y_MIN; v < Y_MAX; v++) { if( (h > 22) && (h < 76+18)) im_line_va[v*H_RES + h] = kkkk; } } apply_xf_rot(cube_a,y_rot); apply_xf_rot(cube_a,y_rot); apply_rot(cube_pts,x_rot); apply_rot(cube_pts,x_rot); apply_rot(cube_pts,y_rot); apply_rot(cube_pts,y_rot); apply_rot(cube_pts,z_rot); //draw ball im_line_va[(py/10)*H_RES + (px/10)] = 1; draw_line(X_0,Y_0,(px/10),(py/10)); draw_cube(cube_pts); //update position/check for bounces px += vx; py += vy; px2 += vx2; py2 += vy2; if(px/10 > (X_MAX-2) || px/10 < (X_MIN+1)) vx = -vx; if(py/10 > (Y_MAX-2) || py/10 < (Y_MIN+1)) vy = -vy; if(px2/10 > (X_MAX-2) || px2/10 < (X_MIN+1)) vx2 = -vx2; if(py2/10 > (Y_MAX-2) || py2/10 < (Y_MIN+1)) vy2 = -vy2; if(k%(8000*50)) return; jjj = !jjj; int bmi = 0; for(int y = BY_0; y < BY_0 + BY; y++) { for(int x = BX_0; x < BX_0 + BX; x++) { im_line_va[H_RES*y + x] = kkkk^(miters[bmi]*jjj + (!jjj)*tv[bmi]); bmi++; } } } int flappy_pong() { //clear frame for(int y = 0; y < PADDLE_LEN; y++) { im_line_va[H_RES*(y+(int)p1)+SX_MIN] = 0; im_line_va[H_RES*(y+(int)p2)+SX_MAX] = 0; } im_line_va[H_RES*(int)by+(int)bx] = 0; //read inputs int cmd1 = p1_in.read(); int cmd2 = p2_in.read(); if (cmd1 == 0) p1v = 0.1; else p1v = -0.1f; if (cmd2 == 0) p2v = 0.1; else p2v = -0.1f; p1 += p1v; p2 += p2v; bx += bxv; by += byv; if (p1 < SY_MIN) p1 = SY_MIN; if (p1 > SY_MAX-PADDLE_LEN) p1 = SY_MAX-PADDLE_LEN; if (p2 < SY_MIN) p2 = SY_MIN; if (p2 > SY_MAX-PADDLE_LEN) p2 = SY_MAX-PADDLE_LEN; if (bx < SX_MIN) { bxv = -bxv; bx = SX_MIN; if (by < p1 - 3 || by > p1 + PADDLE_LEN + 3) { im_line_va[H_RES*(SY_MIN-2)+2*s1+SX_MIN] = 1; bx = (SX_MIN+SX_MAX)/2, by = (SY_MIN+SY_MAX)/2; s1++; if (s1>14) return 0; } } if (bx > SX_MAX) { bxv = -bxv; bx = SX_MAX; if (by < p2 - 3 || by > p2 + PADDLE_LEN + 3) { im_line_va[H_RES*(SY_MAX+2)+2*s2+SX_MIN] = 1; bx = (SX_MIN+SX_MAX)/2, by = (SY_MIN+SY_MAX)/2; s2++; if (s2>14) return 0; } } if (by < SY_MIN) {byv = -byv; by = SY_MIN;} if (by > SY_MAX) {byv = -byv; by = SY_MAX;} for(int y = 0; y < PADDLE_LEN; y++) { im_line_va[H_RES*(y+(int)p1)+SX_MIN] = 1; im_line_va[H_RES*(y+(int)p2)+SX_MAX] = 1; } im_line_va[H_RES*(int)by+(int)bx] = 1; wait(1/1200.0f); return 1; } int fishy() { uint16_t xstart, ystart, xend, yend; float s = sinf(ftheta); float c = cosf(ftheta); xstart = (uint16_t) fx; ystart = (uint16_t) fy; for(int x = xstart-5; x < xstart + 5; x++) { for (int y = ystart - 5; y < ystart + 5; y++) { im_line_va[H_RES*y+x] = 0; } } for (int i = 0; i < 8; i++) { int index = H_RES*(int)uy[i]+(int)ux[i]; im_line_va[index] = 0; } float fx_old = fx, fy_old = fy; fx += fv * s; fy += fv * c; int cmd = p1_in.read(); if (cmd) ftheta += fa; else ftheta -= fa; if (ftheta >= 2 * 3.1415926) ftheta -= 2 * 3.1415926; if (ftheta < 0) ftheta += 2 * 3.1415926; s = sinf(ftheta); c = cosf(ftheta); xstart = (uint16_t)fx; ystart = (uint16_t)fy; xend = (uint16_t)(fx+s*4); yend = (uint16_t)(fy+c*4); if (xstart < SX_MIN || xstart > SX_MAX || ystart < SY_MIN || ystart > SY_MAX || xend < SX_MIN || xend > SX_MAX || yend < SY_MIN || yend > SY_MAX) { fx = fx_old; fy = fy_old; xstart = (uint16_t)fx; ystart = (uint16_t)fy; xend = (uint16_t)(fx+s*4); yend = (uint16_t)(fy+c*4); } draw_line(xstart, ystart, xend, yend); for (int i = 0; i < 8; i++) { if (!ulive[i]) continue; if (xstart == (int)ux[i] && ystart == (int)uy[i]) { fdeath_ticker = FDEATH_RESET; fs+=1; ulive[i] = 0; } ux[i]+= uv*uvx[i]; uy[i]+= uv*uvy[i]; if (ux[i] < SX_MIN) {ux[i] = SX_MIN; uvx[i] = -uvx[i];} if (ux[i] > SX_MAX) {ux[i] = SX_MAX; uvx[i] = -uvx[i];} if (uy[i] < SY_MIN) {uy[i] = SY_MIN; uvy[i] = -uvy[i];} if (uy[i] > SY_MAX) {uy[i] = SY_MAX; uvy[i] = -uvy[i];} int index = H_RES*(int)uy[i]+(int)ux[i]; im_line_va[index] = 1; } for (int i = 0; i < 8; i++) { im_line_va[H_RES*(SY_MAX+6)+2*(int)i+SX_MIN] = 0; } for (int i = 0; i < fs; i++) { im_line_va[H_RES*(SY_MAX+6)+2*(int)i+SX_MIN] = 1; } fdeath_ticker--; if (fdeath_ticker < 0) fs -= 0.0001f; if (fs < 0) fs = 0; return 1; } void dispchr(int x0, int y0, uint8_t* chr) { int bmi = 0; for(int y = SY_MIN + y0; y < SY_MIN + y0 + 7; y++) { for(int x = SX_MIN + x0; x < SX_MIN + x0 + 6; x++) { im_line_va[H_RES*y + x] = chr[bmi]; bmi++; } } } void dispsprite(int x0, int y0, uint8_t* chr) { int bmi = 0; for(int y = SY_MIN + y0; y < SY_MIN + y0 + 8; y++) { for(int x = SX_MIN + x0; x < SX_MIN + x0 + 7; x++) { if (chr[bmi]) im_line_va[H_RES*y + x] = chr[bmi]; bmi++; } } } void disp_tunnel() { for (int y = SY_MIN; y < SY_MAX; y++) { int tunw = 30 * (y) / TUN_LEN; int yy = SY_MAX-(SY_MAX-y)*3/4; for (int x = SX_MIN; x < SX_MIN + tunnel[y - SY_MIN]; x++) im_line_va[H_RES*yy+x] = (x&1)^(y&1); for (int x = SX_MIN + tunnel[y - SY_MIN]; x < SX_MIN + tunnel[y - SY_MIN] + tunw; x++) im_line_va[H_RES*yy+x] = 0; for (int x = SX_MIN + tunnel[y - SY_MIN] + tunw; x < SX_MAX; x++) im_line_va[H_RES*yy+x] = (x&1)^(y&1); } } void init_tunnel() { for (int i = 0; i < TUN_LEN; i++) tunnel[i] = 20; disp_tunnel(); int bmi = 0; for(int y = SY_MIN; y < SY_MIN + BY; y++) { for(int x = SX_MIN; x < SX_MIN + BX; x++) { im_line_va[H_RES*y + x + 10] = tv[bmi]; bmi++; } } dispsprite(1,2,sprite_tree); dispsprite(50,2,sprite_tree); dispsprite(11,2,sprite_tree); } void update_tunnel() { for (int j = TUN_LEN-1; j > 0; j--) tunnel[j] = tunnel[j-1]; int x = rand() % 48; if (x == 0) tundir = -tundir; if (x > 24) tunnel[0] = tunnel[0]+tundir; if (tunnel[0] < 1) { tunnel[0] = 1; tundir = 1; } if (SX_MIN + tunnel[0] + 30 + 1 > SX_MAX) { tunnel[0] = SX_MAX-SX_MIN-30-1; tundir = -1; } disp_tunnel(); int cmd1 = p1_in.read(); int cmd2 = p2_in.read(); if (cmd1) tunnp+=1.0f; if (cmd2) tunnp-=1.0f; if (tunnp<SX_MIN+8) tunnp = SX_MIN+8; if (tunnp>SX_MAX-8) tunnp = SX_MAX-8; dispsprite((int)(tunnp-SX_MIN), 31, sprite_man); wait(0.01); } int main() { potato: init_buffers(); t.attach_us(&isr,63); int bmi = 0; for(int y = SY_MIN; y < SY_MIN + BY2; y++) { for(int x = SX_MIN; x < SX_MIN + BX; x++) { im_line_va[H_RES*y + x] = miters[bmi]; bmi++; } } dispchr(4, BY2+1, chr_P); dispchr(11, BY2+1, chr_A); dispchr(18, BY2+1, chr_N); dispchr(25, BY2+1, chr_G); dispchr(4, BY2+9, chr_F); dispchr(11, BY2+9, chr_A); dispchr(18, BY2+9, chr_S); dispchr(25, BY2+9, chr_H); dispchr(4, BY2+17, chr_D); dispchr(11, BY2+17, chr_A); dispchr(18, BY2+17, chr_M); dispchr(25, BY2+17, chr_O); dispchr(4, BY2+25, chr_D); dispchr(11, BY2+25, chr_R); dispchr(18, BY2+25, chr_A); dispchr(25, BY2+25, chr_V); int cursor_pos = 0; for (;;) { int cmd1 = p1_in.read(); int cmd2 = p2_in.read(); int cursor_x = SX_MIN; int cursor_y = SY_MIN + 8*cursor_pos + BY2 + 5; if (cmd1 || cmd2) im_line_va[H_RES*cursor_y+cursor_x] = 0; if (!cmd1) cursor_pos++; if (!cmd2) cursor_pos--; if (!cmd1 && !cmd2) break; if (cursor_pos < 0) cursor_pos = 0; if (cursor_pos > 3) cursor_pos = 3; cursor_x = SX_MIN; cursor_y = SY_MIN + 8*cursor_pos + BY2 + 5; im_line_va[H_RES*cursor_y+cursor_x] = 1; wait(0.1); } init_buffers(); if (cursor_pos == 0) { for (;;) { if (!flappy_pong()) break; } } else if (cursor_pos == 1) { for (;;) fishy(); } else if (cursor_pos == 2) { for (;;) update_image(); } else { init_tunnel(); for (;;) { update_tunnel(); } } goto potato; }