Bayley Wang
/
manworm_tv_raster
cube
Fork of manworm_tv_gpu by
main.cpp
- Committer:
- bwang
- Date:
- 2018-05-04
- Revision:
- 13:9cf720873bf6
- Parent:
- 12:e99cc1e9d928
- Child:
- 14:cd89c3c9978a
File content as of revision 13:9cf720873bf6:
#include "mbed.h" #include <math.h> #include "main.h" #include "raster.h" #define TEXT_LEVEL 5 #define TX 24 // number of characters in X #define TY 18 // number of characters in Y #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #define N_COLOR 16 // DAC stuff #define DAC_SYNC 2 uint8_t char_col = 0; // current column counter uint8_t char_row = 0; // current row counter uint8_t text_buffer_counter = 0; // current index in text buffer counter char most_recent_char = '0'; uint8_t line_intensity = 0; int8_t line_dir = 1; char text_buffer[TX*TY]; // input text buffer for lisp AnalogIn joy1(A1); AnalogIn joy2(A0); uint8_t want_gfx = 0; uint8_t vsync = 0; Serial pc(USBTX, USBRX); #include "vincent_data.h" DigitalOut sout(D8); //sync PA_9 DigitalOut vout(D7); //video PA_8 DigitalOut dac0(PA_4); DigitalOut dac1(PA_5); DigitalOut dac2(PA_6); DigitalOut dac3(PA_7); // trigger horizontal line draw Ticker t; uint8_t draw_line_inv = 0; uint8_t bl_line_s[H_RES]; //blank line sync buffer uint8_t bl_line_v[H_RES]; //blank line video buffer uint8_t vb_line_s[H_RES]; //vertical sync, sync buffer uint8_t vb_line_v[H_RES]; //vertical sync, video buffer uint8_t im_line_s[H_RES]; //image sync buffer uint8_t im_line_va_1[H_RES*V_RES]; uint8_t* im_line_va; // active image buff uint16_t l=0; //current line of scan // positive or negative? int16_t sign(int16_t a) { if(a > 0) return 1; if(a < 0) return -1; return 0; } // clear the text buffer void clr_text_buff() { text_buffer_counter = 0; for(int i = 0; i < TX*TY; i++) text_buffer[i] = 0; } // clear the screen and the text buffer 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; clr_text_buff(); } // initialize video buffers void init_buffers() { clr(); // zero buffers for(int i = 0; i < H_RES; i++) { im_line_s[i] = DAC_SYNC; bl_line_s[i] = DAC_SYNC; 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; im_line_s[3] = 0; for(int i = 0; i < 15; i++) im_line_s[i] = 0; bl_line_s[0] = 0; vb_line_s[0] = DAC_SYNC; bl_line_s[1] = 0; vb_line_s[1] = DAC_SYNC; bl_line_s[3] = 0; vb_line_s[3] = DAC_SYNC; bl_line_s[2] = 0; vb_line_s[2] = DAC_SYNC; } // video interrupt 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)*H_RES); sptr = im_line_s; nop = 1; vsync = 0;} //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; } uint16_t lmax = nop?H_RES:12; //number of columns for(uint16_t i = 0; i < lmax; i++) //loop over each column { nop = 1; GPIOA->ODR = (vptr[i] + sptr[i]) << 4; 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");asm("nop");//asm("nop");asm("nop");asm("nop");asm("nop"); } else {wait_us(1); if(i > 2) i+=1;} //wait delay } //move to next line l++; if(l == V_RES) vsync = 1; if(l > 255) l = 0; } // draw vertical line 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] = line_intensity; } // draw horizonal line 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] = line_intensity; } // draw line between points 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)?line_intensity:0; err += derr; while(err >= 0.5f) { y += sign(dy); im_line_va[H_RES*y + x] = (!draw_line_inv)?line_intensity:0; err -= 1.f; } } } // draw letter void draw_vincent(uint16_t x0, uint16_t y0, uint8_t c) { if(c == 40) c = 41; else if(c == 41) c = 40; char* letter = vincent_data[c]; for(uint16_t xp = 0; xp < 8; xp++) { for(uint16_t yp = 0; yp < 8; yp++) { im_line_va[H_RES*(yp+y0) + xp + x0] = CHECK_BIT(letter[yp],8-xp)?TEXT_LEVEL:0; } } } // go to new line void new_line() { char_col = 0; char_row++; if(char_row >= TY) { char_row = 0; } } // draw string void draw_vincent_string(char* str) { for(int i = 0; i < strlen(str); i++) { if(str[i] == 0) return; char_col++; if(char_col >= TX) { char_col = 0; char_row++; } if(char_row >= TY) { char_row = 0; } draw_vincent(X0 +2 + 8*char_col, Y0 + 14 + 8*char_row, str[i]); } } void set_status_string(char* str) { uint8_t char_col_backup = char_col; uint8_t char_row_backup = char_row; char_col = 0; char_row = TY - 1; draw_vincent_string(str); char_col = char_col_backup; char_row = char_row_backup; } //screen goes from -.5 to .5 on both axes void draw_gfx_line(float x0, float y0, float x1, float y1) { float x_width = (XL); float y_height = (YL); // want to rescale to 0 to 1 x0 += 0.5f; y0 += 0.5f; x1 += 0.5f; y1 += 0.5f; //printf("x0: %.3f, y0: %.3f\r\n",x0,y0); int xx = x0 * x_width + X0; if(xx > (X0 + XL)) xx = (X0 + XL); if(xx < X0) xx = X0; int yy = y0 * y_height + Y0; if(yy > (Y0 + YL)) yy = (Y0 + YL); if(yy < Y0) yy = Y0; int xx1 = x1 * x_width + X0; if(xx1 > (X0 + XL)) xx1 = (X0 + XL); if(xx1 < X0) xx1 = X0; int yy1 = y1 * y_height + Y0; if(yy1 > (Y0 + YL)) yy1 = (Y0 + YL); if(yy1 < Y0) yy1 = Y0; draw_line(xx,yy,xx1,yy1); } int main() { im_line_va = im_line_va_1; //init serial pc.baud(115200); pc.printf("derp!\r\n"); //init buffers init_buffers(); //init timer t.attach_us(&isr,64); //clear zbuffer clear_zbuf(); wait_us(200000); add_quad(-32, -32, -32, 32, -32, -32, 32, -32, 32, -32, -32, 32, 4); add_quad(32, -32, -32, 32, -32, 32, 32, 32, 32, 32, 32, -32, 2); add_quad(32, 32, -32, 32, 32, 32, -32, 32, 32, -32, 32, -32, 7); add_quad(-32, 32, -32, -32, 32, 32, -32, -32, 32, -32, -32, -32, 6); add_quad(-32, 32, -32, 32, 32, -32, 32, -32, -32, -32, -32, -32, 3); add_quad(-32, 32, 32, 32, 32, 32, 32, -32, 32, -32, -32, 32, 5); theta = 0.0f; phi = 0.0f; cx = 0; cy = 0; cz = 100; int num_iters; for(;;) { if(!vsync) continue; clr(); float j2 = joy1.read() - .5f;; float j1 = joy2.read() - .5f; num_iters++; if( (num_iters % 5) == 0) { if(line_dir == 1) { line_intensity++; if(line_intensity >= 8) line_dir = -1; } else { line_intensity--; if(line_intensity == 0) line_dir = 1; } } theta += j2 / 5.0f; phi += j1 / 5.0f; clear_zbuf(); render_quads(); draw_line(X0, Y0, X0 + XL, Y0); draw_line(X0+XL,Y0,X0+XL,Y0+YL); draw_line(X0, Y0+YL, X0 +XL, Y0+YL); draw_line(X0,Y0,X0,Y0+YL); most_recent_char = '0'; char joy_string[20]; sprintf(joy_string,"1: %.2f 2: %.2f",joy1.read(),joy2.read()); set_status_string(joy_string); vsync = 0; } }