gameboy wormboy manboy gameworm gameman wormgame mangame manworm

Dependencies:   mbed SDFileSystem2

Revision:
14:5ee7843f2805
Parent:
13:9cf720873bf6
Child:
16:1f728d08b3a7
--- a/main.cpp	Fri May 04 19:18:18 2018 +0000
+++ b/main.cpp	Sun Sep 30 18:03:58 2018 +0000
@@ -1,64 +1,62 @@
 #include "mbed.h"
 #include <math.h>
 #include "main.h"
-#include "raster.h"
+#include "face.h"
+#include "SDFileSystem.h"
 
 #define TEXT_LEVEL 5
 
 #define TX 24  // number of characters in X
-#define TY 18  // number of characters in Y
+#define TY 10  // 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 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);
 
+DigitalOut user_led(PB_14);
+int led_state = 1;
+
 // 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
+
+//buffers
+uint8_t current_frame[YL][XL / 2];
 uint8_t im_line_va_1[H_RES*V_RES];
-uint8_t* im_line_va; // active image buff
+uint8_t im_line_va_2[H_RES*V_RES];
+
+//double buffered drawing
+uint8_t* im_line_va;
+uint8_t* im_back;
 
 uint16_t l=0; //current line of scan
+uint32_t tics = 0; //timer
 
 // positive or negative?
 int16_t sign(int16_t a)
@@ -68,23 +66,12 @@
     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();
-    
+            im_line_va[i+j*H_RES] = 0;    
 }
 
 // initialize video buffers
@@ -120,69 +107,69 @@
 // video interrupt
 void isr()
 {
-    uint8_t nop = 0; //use nops or use wait_us
+    uint8_t nop = 0, img = 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
-    {
+    uint8_t* pptr; //porch
+    
+    if (l < V_PORCH_SIZE) {
+        vptr = bl_line_v; 
+        sptr = im_line_s;
+        nop = 1;
+        vsync = 0;
+    }
+    else if (l < YL + V_PORCH_SIZE) {
+        vptr = im_line_va + (l - 30) * H_RES; 
+        sptr = im_line_s;
+        nop = 1;
+        img = 1;
+        vsync = 0;
+    }
+    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;
-        GPIOA->ODR = (vptr[i] + sptr[i]) << 4;
-
-        if(nop) //nop delay
+    }
+    
+    pptr = img ? bl_line_v : vptr;
+    
+    if (nop) {
+        for (uint16_t i = 0; i < H_PORCH_SIZE; i++) {
+            GPIOA->ODR = (pptr[i] + sptr[i]) << 4;
+    
+            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");
+        }
+        
+        for (uint16_t i = 0; i < H_RES; i++) //loop over each column
         {
-            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");
+            GPIOA->ODR = (vptr[i] + sptr[i]) << 4;
+    
+            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 
+    } else {
+        for(uint16_t i = 0; i < 12; i++) //loop over each column
+        {
+            GPIOA->ODR = sptr[i] << 4;
+    
+            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");
+        }
     }
+    
     //move to next line
     l++;
+    tics++;
     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)
 {
@@ -198,17 +185,6 @@
     }
 }
 
-// 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)
 {
@@ -244,39 +220,12 @@
     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()
 {
+    uint8_t *buf_swap_tmp;
     im_line_va = im_line_va_1;
+    im_back = im_line_va_2;
+    
     //init serial
     pc.baud(115200);
     pc.printf("derp!\r\n");
@@ -285,59 +234,57 @@
     init_buffers();
     //init timer
     t.attach_us(&isr,64);
-    //clear zbuffer
-    clear_zbuf();
-        
-    wait_us(200000);
+    
+    /*init SD card, wait for card insertion*/ 
+    SDFileSystem sd(DI, DO, SCK, CS, "sd");
+    while (sd.disk_status()) {
+        sd.disk_initialize();
+        wait(0.5);
+    }
+    
+    FILE *fp;
     
-    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(;;) 
+    //test code - write an image to the SD card
+    //fp = fopen("/sd/man.worm", "wb");
+    //for(int x = 0; x < XL; x += 2)
+    //{
+    //    for(int y = 0; y < YL; y++)
+    //    {
+    //       current_frame[y][x / 2] = (splash[y][x] & 0xf0) + (splash[y][x + 1] >> 4);
+    //    }
+    //}
+    //fwrite(current_frame, 1, VIDEO_FRAME_SIZE, fp);
+    //fclose(fp);
+    
+    fp = fopen("/sd/man.worm", "rb");
+            
+    uint32_t old_tics = tics;
+    for(;;)
     {
         if(!vsync) continue;
         
-        clr();
-        float j2 = joy1.read() - .5f;;
-        float j1 = joy2.read() - .5f;
-        
-        num_iters++;
-    
-        if( (num_iters % 5) == 0)
+        //rewind(fp);
+        fread(current_frame, 1, VIDEO_FRAME_SIZE, fp);
+        for(int x = 0; x < XL; x += 2)
         {
-            if(line_dir == 1)
+            for(int y = 0; y < YL; y++)
             {
-                line_intensity++;
-                if(line_intensity >= 8)
-                    line_dir = -1;
+               im_back[H_RES*(y+Y0) + x + X0] = current_frame[YL - y][x >> 1] >> 4;
+               im_back[H_RES*(y+Y0) + x + 1 + X0] = current_frame[YL - y][x >> 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';
+        buf_swap_tmp = im_line_va;
+        im_line_va = im_back;
+        im_back = buf_swap_tmp;
+        
+        led_state = !led_state;
+        user_led = led_state; 
 
-        char joy_string[20];
-        sprintf(joy_string,"1: %.2f 2: %.2f",joy1.read(),joy2.read());
-        set_status_string(joy_string);
+        char status_string[20];
+        sprintf(status_string, "%.1f", 15625.f / (float)(tics - old_tics));
+        old_tics = tics;
+        set_status_string(status_string);
         
         vsync = 0;            
     }