Revenge of the Mouse

Dependencies:   4DGL-uLCD-SE EthernetInterface Game_Synchronizer LCD_fonts MMA8452 SDFileSystem mbed-rtos mbed wave_player

Fork of 2035_Tanks_Shell by ECE2035 Spring 2015 TA

two_player.h

Committer:
jford38
Date:
2015-10-12
Revision:
3:3ddefff03cb2
Parent:
2:c358ad9aedc4
Child:
4:d8bd8b41468d

File content as of revision 3:3ddefff03cb2:

#ifndef TWO_PLAYER_H__
#define TWO_PLAYER_H__

#include <cmath>
#include "uLCD_4DGL.h"
#include "EthernetInterface.h"

#define PLAYER1 true
#define PLAYER2 false

Serial pc(USBTX, USBRX);

const char* PLAYER1_IP   = "192.168.2.1";
const char* PLAYER2_IP   = "192.168.2.2";
const int   SERVER_PORT = 7;

DigitalOut led(LED2);


class uLCD_2P
{

public :

    int p1_p2;

    enum Color
    {
        CLS_CMD,
        BG_COLOR_CMD,
        LINE_CMD,
        CIRCLE_CMD,
        FILLED_CIRCLE_CMD,
        TRI_CMD,
        RECT_CMD,
        FILLED_RECT_CMD,
        PIX_CMD,
        PEN_SZ_CMD
    };

    uLCD_2P(PinName tx, PinName rx, PinName rst, bool player) {
        p1_p2 = player;
        //LCD = new uLCD_4DGL (tx, rx, rst);        
    }
    
    void init() {
        
        buffer_idx = 0;
        memset(buttons, 0, sizeof(buttons));
        
        switch (p1_p2) {
            case PLAYER1:           // Client
                
                eth = new EthernetInterface();
                eth->init(PLAYER1_IP, "255.255.255.0", "0.0.0.0"); 
                eth->connect();
                
                sock = new TCPSocketConnection();
                while(sock->connect(PLAYER2_IP, SERVER_PORT) < 0) {
                    pc.printf("Trying to connect.\n");
                    //wait(1);
                }
                
                break;
            case PLAYER2:           // Server
                eth = new EthernetInterface();
                eth->init(PLAYER2_IP, "255.255.255.0", "0.0.0.0"); 
                eth->connect();

                server = new TCPSocketServer();
                server->bind(SERVER_PORT);
                server->listen();
                sock = new TCPSocketConnection();
                server->accept(*sock);
                sock->set_blocking(false, 1500);
                break;   
        }
        pc.printf("Ethernet Connected.\n");
    }
    
    // Yes, this sucks. If you're smart, find a good way to do variable args and show me!
    // Look into template metaprogramming!
    
    void  draw(int CMD) {_draw(CMD, 0,0,0,0,0,0,0, 0); }
    void  draw(int CMD, int a) { _draw(CMD, a, 0,0,0,0,0,0, 1); }
    void  draw(int CMD, int a, int b) { _draw(CMD, a, b, 0,0,0,0,0, 2); }
    void  draw(int CMD, int a, int b, int c) { _draw(CMD, a, b, c, 0,0,0,0, 3); }
    void  draw(int CMD, int a, int b, int c, int d) { _draw(CMD, a, b, c, d, 0,0,0, 4); }
    void  draw(int CMD, int a, int b, int c, int d, int e) { _draw(CMD, a, b, c, d, e, 0,0, 5); }
    void  draw(int CMD, int a, int b, int c, int d, int e, int f) { _draw(CMD, a, b, c, d, e, f, 0, 6); }
    void  draw(int CMD, int a, int b, int c, int d, int e, int f, int g) { _draw(CMD, a, b, c, d, e, f, g, 7); }
    
    void _draw(int CMD, int a, int b, int c, int d, int e, int f, int g, char nArgs){
        
        // Deal with overflows
        // if(buffer_idx + nArgs > 256) {//flush();}
        
        if(nArgs > 7) { 
            pc.printf("Error in call to _draw(): nArgs > 7 not allowed!\n");
            return;
        }
        
        buffer[buffer_idx] = CMD;
        if(nArgs >= 1) buffer[buffer_idx+1] = a;
        if(nArgs >= 2) buffer[buffer_idx+2] = b;
        if(nArgs >= 3) buffer[buffer_idx+3] = c;
        if(nArgs >= 4) buffer[buffer_idx+4] = d;
        if(nArgs >= 5) buffer[buffer_idx+5] = e;
        if(nArgs >= 6) buffer[buffer_idx+6] = f;
        if(nArgs >= 7) buffer[buffer_idx+7] = g;
        // ERROR: nArgs > 7
        
        
        buffer_idx += nArgs+1;
    }
    
   
    void background_color(int color) { draw(BG_COLOR_CMD, color); }
    void line(int sx, int sy, int ex, int ey, int color) { draw(LINE_CMD, sx, sy, ex, ey, color); }
    void circle(int x , int y , int radius, int color) { draw(CIRCLE_CMD, x, y, radius, color); }
    void filled_circle(int x , int y , int radius, int color) { draw(FILLED_CIRCLE_CMD, x, y, radius, color); }
    void triangle(int a, int b, int c, int d , int e, int f, int col) { draw(TRI_CMD, a, b, c, d, e, f, col); }
    void rectangle(int a, int b, int c, int d, int col) { draw(RECT_CMD, a, b, c, d, col); }
    void filled_rectangle(int a, int b, int c, int d, int col) { draw(FILLED_RECT_CMD, a, b, c, d, col); }
    void pixel(int a, int b, int col) { draw(PIX_CMD, a, b, col); }
    void cls(void) { draw(CLS_CMD); }
    
    void pen_size(char sz) { draw(PEN_SZ_CMD, sz); }
    /*void BLIT(int x1, int y1, int x2, int y2, int *colors) {
        int size = abs((x1-x2)*(y1-y2));
        // pad to a multiple of 4 and memset buffer...
        // I'll get to it later.
    }*/

    // Reads don't need to be done on the slave side. Hopefully both sides match!
    int  read_pixel(int x, int y) { return LCD->read_pixel(x, y); }
    
    void set_button_state(int a, int b, int c, int d, int e) { 
        buttons[0] = a; buttons[1] = b; buttons[2] = c; 
        buttons[3] = d; buttons[4] = e;   
    }
    
    int* get_button_state() {
        return buttons;
    }
    
    void update() {
        sock->set_blocking(true, 100);
        if(p1_p2 == PLAYER1) {
            sock->send_all((char*)buffer, (buffer_idx+1)*sizeof(buffer[0]));
            buffer_idx = 0;
 
            int n = sock->receive((char*)buttons, sizeof(buttons));
            if(n < 0) {pc.printf("RECEIVE ERROR.\n");}          
        
        }else if(p1_p2 == PLAYER2) {    
            int n = sock->receive((char*)buffer, sizeof(buffer));  
            if(n < 0) {pc.printf("RECEIVE ERROR.\n");}
            buffer[n] = '\0';   
            sock->send_all((char*)buttons, sizeof(buttons));          
        }
        
        int i = 0;        
        while(buffer[i] != '\0') {
            pc.printf("%d ", buffer[i]);
            i++;
        }
        pc.printf("\n");
        
        int idx = 0;
        while(buffer[idx] != '\0') {
            char cmd = buffer[idx];
            idx++;
            
            switch(cmd) {
                case BG_COLOR_CMD:
                    //LCD->background_color(buffer[idx+1]);
                    pc.printf("Change the background to %x\n", buffer[idx]);
                    idx += 1;
                    break;
                case LINE_CMD:
                    pc.printf("LINE: (%d, %d) - (%d, %d) COLOR: %X\n", buffer[idx], buffer[idx+1], buffer[idx+2], buffer[idx+3], buffer[idx+4]);
                    idx += 5;
                    break;
                case CLS_CMD:
                    //LCD->cls();
                    pc.printf("Clear the screen!\n");
                    break;
                case CIRCLE_CMD:
                    //LCD->cls();
                    pc.printf("CIRCLE: (%d, %d), r=%d\n", buffer[idx], buffer[idx+1], buffer[idx+2]);
                    idx += 3;
                    break;
                default:
                    pc.printf("UNKNOWN CMD %d: This could get ugly!\n", cmd);
                    idx += 0;
            }
        }
    }
    
    ~uLCD_2P() {            
        sock->close();
        eth->disconnect();  
        delete sock;
        delete server;
        delete eth; 
    }
 
    private:
        bool master_slave;
        
        int buffer[256];
        int  buffer_idx;
        
        TCPSocketServer* server;
        TCPSocketConnection*  sock;
        EthernetInterface* eth;
        
        uLCD_4DGL* LCD;
        
        int buttons[5];
};

#endif