cube

Dependencies:   mbed

Fork of manworm_tv_gpu by Jared DiCarlo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include <math.h>
00003 #include "main.h"
00004 #include "raster.h"
00005 
00006 #define TEXT_LEVEL 5
00007 
00008 #define TX 24  // number of characters in X
00009 #define TY 18  // number of characters in Y
00010 
00011 #define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
00012 #define MIN(a,b) (((a)<(b))?(a):(b))
00013 #define MAX(a,b) (((a)>(b))?(a):(b))
00014 
00015 #define N_COLOR 16
00016 
00017 // DAC stuff
00018 #define DAC_SYNC 2
00019 
00020 uint8_t char_col = 0;  // current column counter
00021 uint8_t char_row = 0;  // current row counter
00022 uint8_t text_buffer_counter = 0; // current index in text buffer counter
00023 char most_recent_char = '0';
00024 
00025 uint8_t line_intensity = 0;
00026 int8_t line_dir = 1;
00027 
00028 char text_buffer[TX*TY]; // input text buffer for lisp
00029 
00030 AnalogIn joy1(A1);
00031 AnalogIn joy2(A0);
00032 
00033 uint8_t want_gfx = 0;
00034 uint8_t vsync = 0;
00035 
00036 Serial pc(USBTX, USBRX);
00037 
00038 #include "vincent_data.h"
00039 
00040 DigitalOut sout(D8); //sync PA_9
00041 DigitalOut vout(D7); //video PA_8
00042 
00043 DigitalOut dac0(PA_4);
00044 DigitalOut dac1(PA_5);
00045 DigitalOut dac2(PA_6);
00046 DigitalOut dac3(PA_7);
00047 
00048 // trigger horizontal line draw
00049 Ticker t;
00050 
00051 uint8_t draw_line_inv = 0;
00052 
00053 uint8_t bl_line_s[H_RES]; //blank line sync buffer
00054 uint8_t bl_line_v[H_RES]; //blank line video buffer
00055 uint8_t vb_line_s[H_RES]; //vertical sync, sync buffer
00056 uint8_t vb_line_v[H_RES]; //vertical sync, video buffer
00057 uint8_t im_line_s[H_RES]; //image sync buffer
00058 uint8_t im_line_va_1[H_RES*V_RES];
00059 uint8_t* im_line_va; // active image buff
00060 
00061 uint16_t l=0; //current line of scan
00062 
00063 // positive or negative?
00064 int16_t sign(int16_t a)
00065 {
00066     if(a > 0) return 1;
00067     if(a < 0) return -1;
00068     return 0;
00069 }
00070 
00071 // clear the text buffer
00072 void clr_text_buff()
00073 {
00074     text_buffer_counter = 0;
00075     for(int i = 0; i < TX*TY; i++)
00076         text_buffer[i] = 0;
00077 }
00078 
00079 // clear the screen and the text buffer
00080 void clr()
00081 {
00082     for(int i = 0; i < H_RES; i++)
00083         for(int j = 0; j < V_RES; j++)
00084             im_line_va[i+j*H_RES] = 0;
00085             
00086     clr_text_buff();
00087     
00088 }
00089 
00090 // initialize video buffers
00091 void init_buffers()
00092 {
00093     clr(); // zero buffers
00094     for(int i = 0; i < H_RES; i++)
00095     {
00096         im_line_s[i] = DAC_SYNC;   
00097         bl_line_s[i] = DAC_SYNC;
00098         bl_line_v[i] = 0;
00099         vb_line_s[i] = 0;
00100         vb_line_v[i] = 0;
00101     }    
00102     im_line_s[0] = 0;
00103     im_line_s[1] = 0;
00104     im_line_s[2] = 0;
00105     im_line_s[3] = 0;
00106     
00107     for(int i = 0; i < 15; i++) im_line_s[i] = 0;
00108     
00109     bl_line_s[0] = 0;
00110     vb_line_s[0] = DAC_SYNC;
00111     bl_line_s[1] = 0;
00112     vb_line_s[1] = DAC_SYNC;
00113     
00114     bl_line_s[3] = 0;
00115     vb_line_s[3] = DAC_SYNC;
00116     bl_line_s[2] = 0;
00117     vb_line_s[2] = DAC_SYNC;
00118 }
00119 
00120 // video interrupt
00121 void isr()
00122 {
00123     uint8_t nop = 0; //use nops or use wait_us
00124     uint8_t* sptr; //pointer to sync buffer for line
00125     uint8_t* vptr; //pointer to video buffer for line
00126     if(l < V_RES){ vptr = im_line_va + ((l)*H_RES); sptr = im_line_s; nop = 1; vsync = 0;} //pick line buffers
00127     else if(l < 254){ vptr = bl_line_v; sptr = bl_line_s; nop = 0;  }
00128     else{ vptr = vb_line_v; sptr = vb_line_s; nop = 1; }
00129     uint16_t lmax = nop?H_RES:12; //number of columns
00130     for(uint16_t i = 0; i < lmax; i++) //loop over each column
00131     {
00132         nop = 1;
00133         GPIOA->ODR = (vptr[i] + sptr[i]) << 4;
00134 
00135         if(nop) //nop delay
00136         {
00137             asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
00138             asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
00139         }
00140         else {wait_us(1); if(i > 2) i+=1;} //wait delay 
00141     }
00142     //move to next line
00143     l++;
00144     if(l == V_RES) vsync = 1;
00145     if(l > 255) l = 0;
00146 }
00147 
00148 // draw vertical line
00149 void draw_vert(int16_t y0, int16_t y1, int16_t x0)
00150 {
00151     for(int16_t i = y0; i < y1; i++)
00152         im_line_va[H_RES*i + x0] = line_intensity;
00153 }
00154 
00155 // draw horizonal line
00156 void draw_horiz(int16_t x0, int16_t x1, int16_t y0)
00157 {
00158     for(int16_t i = x0; i < x1; i++)
00159         im_line_va[H_RES*y0 + i] = line_intensity;
00160 }
00161 
00162 // draw line between points
00163 void draw_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
00164 {
00165     if(x0 > x1){ x0 = x0 ^ x1; x1 = x1^x0; x0 = x0^x1;y0 = y0 ^ y1; y1 = y1^y0; y0 = y0^y1; }
00166     if(x0 == x1){draw_vert(y0,y1,x0);}
00167     if(y0 == y1){draw_horiz(x0,x1,y0);}
00168     int16_t dx = x1 - x0;
00169     int16_t dy = y1 - y0;
00170     float derr = fabs((float)(dy)/(float)(dx));
00171     float err = 0.f;
00172     int16_t y = y0;
00173     for(int16_t x = x0; x < x1; x++)
00174     {
00175         //plotxy
00176         im_line_va[H_RES*y + x] = (!draw_line_inv)?line_intensity:0;
00177         err += derr;
00178         while(err >= 0.5f)
00179         {
00180             y +=  sign(dy);
00181             im_line_va[H_RES*y + x] = (!draw_line_inv)?line_intensity:0;
00182             err -= 1.f;
00183         }   
00184     }
00185 }
00186 
00187 // draw letter
00188 void draw_vincent(uint16_t x0, uint16_t y0, uint8_t c)
00189 {
00190     if(c == 40) c = 41;
00191     else if(c == 41) c = 40;
00192     char* letter = vincent_data[c];
00193     for(uint16_t xp = 0; xp < 8; xp++)
00194     {
00195         for(uint16_t yp = 0; yp < 8; yp++)
00196         {
00197             im_line_va[H_RES*(yp+y0) + xp + x0] = CHECK_BIT(letter[yp],8-xp)?TEXT_LEVEL:0;
00198         }
00199     }
00200 }
00201 
00202 // go to new line
00203 void new_line()
00204 {
00205     char_col = 0;
00206     char_row++;
00207     if(char_row >= TY)
00208     {
00209         char_row = 0;
00210     }
00211 }
00212 
00213 // draw string
00214 void draw_vincent_string(char* str)
00215 {
00216     for(int i = 0; i < strlen(str); i++)
00217     {
00218         if(str[i] == 0) return;
00219         char_col++; 
00220     if(char_col >= TX)
00221     {
00222         char_col = 0;
00223         char_row++;
00224     }
00225     if(char_row >= TY)
00226     {
00227         char_row = 0;
00228     }
00229     
00230     draw_vincent(X0 +2 + 8*char_col, Y0 + 14 + 8*char_row, 
00231         str[i]);
00232     }
00233 }
00234 
00235 void set_status_string(char* str)
00236 {
00237     uint8_t char_col_backup = char_col;
00238     uint8_t char_row_backup = char_row;
00239     char_col = 0;
00240     char_row = TY - 1;
00241     
00242     draw_vincent_string(str);
00243     
00244     char_col = char_col_backup;
00245     char_row = char_row_backup;
00246 }
00247 
00248 //screen goes from -.5 to .5 on both axes
00249 void draw_gfx_line(float x0, float y0, float x1, float y1)
00250 {
00251     float x_width = (XL);
00252     float y_height = (YL);
00253     
00254     // want to rescale to 0 to 1
00255     x0 += 0.5f;
00256     y0 += 0.5f;
00257     
00258     x1 += 0.5f;
00259     y1 += 0.5f;
00260     //printf("x0: %.3f, y0: %.3f\r\n",x0,y0);
00261     int xx = x0 * x_width + X0;
00262     if(xx > (X0 + XL)) xx = (X0 + XL);
00263     if(xx < X0) xx = X0;
00264     int yy = y0 * y_height + Y0;
00265     if(yy > (Y0 + YL)) yy = (Y0 + YL);
00266     if(yy < Y0) yy = Y0;   
00267     
00268     int xx1 = x1 * x_width + X0;
00269     if(xx1 > (X0 + XL)) xx1 = (X0 + XL);
00270     if(xx1 < X0) xx1 = X0;
00271     int yy1 = y1 * y_height + Y0;
00272     if(yy1 > (Y0 + YL)) yy1 = (Y0 + YL);
00273     if(yy1 < Y0) yy1 = Y0;   
00274     
00275     draw_line(xx,yy,xx1,yy1);
00276 }
00277 
00278 int main()
00279 {
00280     im_line_va = im_line_va_1;
00281     //init serial
00282     pc.baud(115200);
00283     pc.printf("derp!\r\n");
00284  
00285     //init buffers
00286     init_buffers();
00287     //init timer
00288     t.attach_us(&isr,64);
00289     //clear zbuffer
00290     clear_zbuf();
00291         
00292     wait_us(200000);
00293     
00294     add_quad(-32, -32, -32, 32, -32, -32, 32, -32, 32, -32, -32, 32, 4);
00295     add_quad(32, -32, -32, 32, -32, 32, 32, 32, 32, 32, 32, -32, 2);
00296     add_quad(32, 32, -32, 32, 32, 32, -32, 32, 32, -32, 32, -32, 7);
00297     add_quad(-32, 32, -32, -32, 32, 32, -32, -32, 32, -32, -32, -32, 6);
00298     add_quad(-32, 32, -32, 32, 32, -32, 32, -32, -32, -32, -32, -32, 3);
00299     add_quad(-32, 32, 32, 32, 32, 32, 32, -32, 32, -32, -32, 32, 5);
00300     theta = 0.0f; phi = 0.0f; cx = 0; cy = 0; cz = 100;
00301 
00302     int num_iters;
00303     for(;;) 
00304     {
00305         if(!vsync) continue;
00306         
00307         clr();
00308         float j2 = joy1.read() - .5f;;
00309         float j1 = joy2.read() - .5f;
00310         
00311         num_iters++;
00312     
00313         if( (num_iters % 5) == 0)
00314         {
00315             if(line_dir == 1)
00316             {
00317                 line_intensity++;
00318                 if(line_intensity >= 8)
00319                     line_dir = -1;
00320             }
00321             else
00322             {
00323                 line_intensity--;
00324                 if(line_intensity == 0) line_dir = 1;
00325             }   
00326         }
00327         
00328         theta += j2 / 5.0f;
00329         phi += j1 / 5.0f;
00330         clear_zbuf();
00331         render_quads();
00332                 
00333         draw_line(X0, Y0, X0 + XL, Y0);
00334         draw_line(X0+XL,Y0,X0+XL,Y0+YL);
00335         draw_line(X0, Y0+YL, X0 +XL, Y0+YL);
00336         draw_line(X0,Y0,X0,Y0+YL);
00337         most_recent_char = '0';
00338 
00339         char joy_string[20];
00340         sprintf(joy_string,"1: %.2f 2: %.2f",joy1.read(),joy2.read());
00341         set_status_string(joy_string);
00342         
00343         vsync = 0;            
00344     }
00345 }
00346 
00347