Bayley Wang
/
manworm_tv_raster
cube
Fork of manworm_tv_gpu by
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Sun Jul 24 2022 19:17:32 by 1.7.2