// Black and white NTSC video game generation with fixed point animation // Design Project by Lu Liu and Xu Chen // Referenced from Mega644 version by Shane Pryor // mod by brl4@cornell.edu: // for mega1284 // for resolution 160 horizontal x 200 vertical #include <avr/io.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <util/delay.h> #include <avr/sleep.h> #include "uart.h" // optional, if preferred/// #define begin { #define end } //////////////////////////// // ADC int Ain1, Ain2, Ain3 ,Ain4 ; //raw A to D number /////////////////////////// // UART file descriptor // putchar and getchar are in uart.c FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); //cycles = 63.625 * 16 Note NTSC is 63.55 //but this line duration makes each frame exactly 1/60 sec //which is nice for keeping a realtime clock // video timing #define LINE_TIME 1018 // 20 MHz 1271 #define SLEEP_TIME 999 // 20 MHz 1250 #define bytes_per_line 20 #define screen_width (bytes_per_line*8) #define screen_height 200 #define screen_array_size screen_width*screen_height/8 #define ScreenTop 30 #define ScreenBot (ScreenTop+screen_height) //sync char syncON, syncOFF; //current line number in the current frame volatile int LineCount; //160h x 160v - screen buffer and pointer char screen[screen_array_size]; int* screenindex; //One bit masks char pos[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //=== fixed conversion macros ========================================= #define int2fix(a) (((int)(a))<<8) //Convert char to fix. a is a char #define fix2int(a) ((signed char)((a)>>8)) //Convert fix to int. a is an int #define float2fix(a) ((int)((a)*256.0)) //Convert float to fix. a is a float #define fix2float(a) (((float)(a))/256.0) //Convert fix to float. a is an int // Car Variable unsigned int vcar_unit[] = {float2fix(0.03), float2fix(0.06),float2fix(0.1)}; // car move distance in unit time unsigned int fix_minus_1 = int2fix(-1); unsigned int fix_zero = int2fix(0); unsigned int fix_200 = int2fix(200); unsigned int fix_160 = int2fix(160); unsigned int fix_1_30 = float2fix(1.0/30); unsigned int fix_2_30 = float2fix(2.0/30); unsigned int fix_3_30 = float2fix(3.0/30); unsigned int fix_20 = int2fix(20); unsigned int fix_0_coord = int2fix(0-128); unsigned int fix_160_coord = int2fix(160-128); int angle_state = 54; int angle_state_2 = 18; int car_gas = 0; int car_gas_flt[] = {0, 0.05, 0.10, 0.15}; int last_wheel_angle, car_angle = 0; int wheel_angle, rela_car_angle, last_abs_wheel_angle; int angle_count = 0; int limit = 0; int reverse = 0; int car_width = 20; int car_length = 50; unsigned int x0_fix, x1_fix, y0_fix, y1_fix; // Driver Function int potentiometer(int voltage) begin // user define voltage reading int max_voltage = 255; int min_voltage = 0; int voltage_level_1 = 120; int voltage_level_2 = 180; if (voltage > max_voltage) { return 3; } else if (voltage < min_voltage) { return 0; } else { if (voltage > min_voltage && voltage < voltage_level_1) return 1; else if (voltage > voltage_level_1 && voltage < voltage_level_2) return 2; else if (voltage > voltage_level_2) return 3; } return 0; end // this function accepts two 0-255 adc accelerometer readings // returns an absolute angle of the steering wheel (0-359) int abs_wheel_angle (char acc_0, char acc_1, int prev_wheel_angle) begin int angle = 0; char acc_0_int = 0; char acc_1_int = 0; char acc = 0; // 0: 221 // 45: 200 // 90: 150 // 135: 95 // 180: 75 // 225: 95 // 270: 150 // 315: 200 int level_1 = 85; int level_2 = 122; int level_3 = 175; int level_4 = 210; // set acc_0 reading range if (acc_0 < level_1) acc_0_int = 0; // -1 else if (acc_0 >= level_1 && acc_0 < level_2) acc_0_int = 1; // -0.7 else if (acc_0 >= level_2 && acc_0 < level_3) acc_0_int = 2; // 0 else if (acc_0 >= level_3 && acc_0 < level_4) acc_0_int = 3; // 0.7 else //if (acc_0 >= level_4) acc_0_int = 4; // 1 // set acc_1 reading range if (acc_1 < level_1) acc_1_int = 0; // -1 else if (acc_1 >= level_1 && acc_1 < level_2) acc_1_int = 1; // -0.7 else if (acc_1 >= level_2 && acc_1 < level_3) acc_1_int = 2; // 0 else if (acc_1 >= level_3 && acc_1 < level_4) acc_1_int = 3; // 0.7 else //if (acc_1 > level_4) acc_1_int = 4; // 1 acc = acc_1_int * 10 + acc_0_int; switch (acc) begin case 42: angle = 0; break; case 33: angle = 45; break; case 24: angle = 90; break; case 13: angle = 135; break; case 2: angle = 180; break; case 11: angle = 225; break; case 20: angle = 270; break; case 31: angle = 315; break; default : angle = prev_wheel_angle; break; end return angle; end // this function receives an initial absolute angle of the steering wheel // returns a relative wheel angle (btw -360 to +360) int relative_wheel_angle (int init_angle, int acc_0, int acc_1) begin int relative_angle;//, temp; relative_angle = abs_wheel_angle(acc_0, acc_1, init_angle) - init_angle; if (relative_angle == 315) relative_angle = -45; if (relative_angle == -315) relative_angle = 45; if (relative_angle == 270) relative_angle = -90; if (relative_angle == -270) relative_angle = 90; if (relative_angle >= 360 || relative_angle <= -360) relative_angle = 0; return relative_angle; end int car_angle_compute (int wheel_angle) begin int car_angle; car_angle = 0.1 * wheel_angle; if(car_angle>45) car_angle=45; if(car_angle<-45) car_angle=-45; return car_angle; end //================================ //3x5 font numbers, then letters //packed two per definition for fast //copy to the screen at x-position divisible by 4 prog_char smallbitmap[39][5] = { //0 0b11101110, 0b10101010, 0b10101010, 0b10101010, 0b11101110, //1 0b01000100, 0b11001100, 0b01000100, 0b01000100, 0b11101110, //2 0b11101110, 0b00100010, 0b11101110, 0b10001000, 0b11101110, //3 0b11101110, 0b00100010, 0b11101110, 0b00100010, 0b11101110, //4 0b10101010, 0b10101010, 0b11101110, 0b00100010, 0b00100010, //5 0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110, //6 0b11001100, 0b10001000, 0b11101110, 0b10101010, 0b11101110, //7 0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b10001000, //8 0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b11101110, //9 0b11101110, 0b10101010, 0b11101110, 0b00100010, 0b01100110, //: 0b00000000, 0b01000100, 0b00000000, 0b01000100, 0b00000000, //= 0b00000000, 0b11101110, 0b00000000, 0b11101110, 0b00000000, //blank 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //A 0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b10101010, //B 0b11001100, 0b10101010, 0b11101110, 0b10101010, 0b11001100, //C 0b11101110, 0b10001000, 0b10001000, 0b10001000, 0b11101110, //D 0b11001100, 0b10101010, 0b10101010, 0b10101010, 0b11001100, //E 0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b11101110, //F 0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b10001000, //G 0b11101110, 0b10001000, 0b10001000, 0b10101010, 0b11101110, //H 0b10101010, 0b10101010, 0b11101110, 0b10101010, 0b10101010, //I 0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b11101110, //J 0b00100010, 0b00100010, 0b00100010, 0b10101010, 0b11101110, //K 0b10001000, 0b10101010, 0b11001100, 0b11001100, 0b10101010, //L 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b11101110, //M 0b10101010, 0b11101110, 0b11101110, 0b10101010, 0b10101010, //N 0b00000000, 0b11001100, 0b10101010, 0b10101010, 0b10101010, //O 0b01000100, 0b10101010, 0b10101010, 0b10101010, 0b01000100, //P 0b11101110, 0b10101010, 0b11101110, 0b10001000, 0b10001000, //Q 0b01000100, 0b10101010, 0b10101010, 0b11101110, 0b01100110, //R 0b11101110, 0b10101010, 0b11001100, 0b11101110, 0b10101010, //S 0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110, //T 0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b01000100, //U 0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b11101110, //V 0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b01000100, //W 0b10101010, 0b10101010, 0b11101110, 0b11101110, 0b10101010, //X 0b00000000, 0b10101010, 0b01000100, 0b01000100, 0b10101010, //Y 0b10101010, 0b10101010, 0b01000100, 0b01000100, 0b01000100, //Z 0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b11101110 }; //=============================================== // Full ascii 5x7 char set // Designed by: David Perez de la Cruz,and Ed Lau // see: http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2005/dp93/index.html prog_char ascii[128][7] = { //0 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //1 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //2 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //3 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //4 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //5 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //6 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //7 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //8 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //9 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //10 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //11 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //12 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //13 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //14 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //15 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //16 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //17 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //18 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //19 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //20 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //21 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //22 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //23 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //24 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //25 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //26 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //27 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //28 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //29 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //30 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //31 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //32 Space 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //33 Exclamation ! 0b01100000, 0b01100000, 0b01100000, 0b01100000, 0b00000000, 0b00000000, 0b01100000, //34 Quotes " 0b01010000, 0b01010000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //35 Number # 0b00000000, 0b01010000, 0b11111000, 0b01010000, 0b11111000, 0b01010000, 0b00000000, //36 Dollars $ 0b01110000, 0b10100000, 0b10100000, 0b01110000, 0b00101000, 0b00101000, 0b01110000, //37 Percent % 0b01000000, 0b10101000, 0b01010000, 0b00100000, 0b01010000, 0b10101000, 0b00010000, //38 Ampersand & 0b00100000, 0b01010000, 0b10100000, 0b01000000, 0b10101000, 0b10010000, 0b01101000, //39 Single Quote ' 0b01000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //40 Left Parenthesis ( 0b00010000, 0b00100000, 0b01000000, 0b01000000, 0b01000000, 0b00100000, 0b00010000, //41 Right Parenthesis ) 0b01000000, 0b00100000, 0b00010000, 0b00010000, 0b00010000, 0b00100000, 0b01000000, //42 Star * 0b00010000, 0b00111000, 0b00010000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //43 Plus + 0b00000000, 0b00100000, 0b00100000, 0b11111000, 0b00100000, 0b00100000, 0b00000000, //44 Comma , 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b00010000, //45 Minus - 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111000, 0b00000000, 0b00000000, //46 Period . 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, // 47 Backslash / 0b00000000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000, 0b00000000, // 48 Zero 0b01110000, 0b10001000, 0b10011000, 0b10101000, 0b11001000, 0b10001000, 0b01110000, //49 One 0b00100000, 0b01100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b01110000, //50 two 0b01110000, 0b10001000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b11111000, //51 Three 0b11111000, 0b00010000, 0b00100000, 0b00010000, 0b00001000, 0b10001000, 0b01110000, //52 Four 0b00010000, 0b00110000, 0b01010000, 0b10010000, 0b11111000, 0b00010000, 0b00010000, //53 Five 0b11111000, 0b10000000, 0b11110000, 0b00001000, 0b00001000, 0b10001000, 0b01110000, //54 Six 0b01000000, 0b10000000, 0b10000000, 0b11110000, 0b10001000, 0b10001000, 0b01110000, //55 Seven 0b11111000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000, 0b10000000, //56 Eight 0b01110000, 0b10001000, 0b10001000, 0b01110000, 0b10001000, 0b10001000, 0b01110000, //57 Nine 0b01110000, 0b10001000, 0b10001000, 0b01111000, 0b00001000, 0b00001000, 0b00010000, //58 : 0b00000000, 0b00000000, 0b00100000, 0b00000000, 0b00000000, 0b00000000, 0b00100000, //59 ; 0b00000000, 0b00000000, 0b00100000, 0b00000000, 0b00000000, 0b00100000, 0b00100000, //60 < 0b00000000, 0b00011000, 0b01100000, 0b10000000, 0b01100000, 0b00011000, 0b00000000, //61 = 0b00000000, 0b00000000, 0b01111000, 0b00000000, 0b01111000, 0b00000000, 0b00000000, //62 > 0b00000000, 0b11000000, 0b00110000, 0b00001000, 0b00110000, 0b11000000, 0b00000000, //63 ? 0b00110000, 0b01001000, 0b00010000, 0b00100000, 0b00100000, 0b00000000, 0b00100000, //64 @ 0b01110000, 0b10001000, 0b10111000, 0b10101000, 0b10010000, 0b10001000, 0b01110000, //65 A 0b01110000, 0b10001000, 0b10001000, 0b10001000, 0b11111000, 0b10001000, 0b10001000, //B 0b11110000, 0b10001000, 0b10001000, 0b11110000, 0b10001000, 0b10001000, 0b11110000, //C 0b01110000, 0b10001000, 0b10000000, 0b10000000, 0b10000000, 0b10001000, 0b01110000, //D 0b11110000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b11110000, //E 0b11111000, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b11111000, //F 0b11111000, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, //G 0b01110000, 0b10001000, 0b10000000, 0b10011000, 0b10001000, 0b10001000, 0b01110000, //H 0b10001000, 0b10001000, 0b10001000, 0b11111000, 0b10001000, 0b10001000, 0b10001000, //I 0b01110000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b01110000, //J 0b00111000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b10010000, 0b01100000, //K 0b10001000, 0b10010000, 0b10100000, 0b11000000, 0b10100000, 0b10010000, 0b10001000, //L 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11111000, //M 0b10001000, 0b11011000, 0b10101000, 0b10101000, 0b10001000, 0b10001000, 0b10001000, //N 0b10001000, 0b10001000, 0b11001000, 0b10101000, 0b10011000, 0b10001000, 0b10001000, //O 0b01110000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b01110000, //P 0b11110000, 0b10001000, 0b10001000, 0b11110000, 0b10000000, 0b10000000, 0b10000000, //Q 0b01110000, 0b10001000, 0b10001000, 0b10001000, 0b10101000, 0b10010000, 0b01101000, //R 0b11110000, 0b10001000, 0b10001000, 0b11110000, 0b10100000, 0b10010000, 0b10001000, //S 0b01111000, 0b10000000, 0b10000000, 0b01110000, 0b00001000, 0b00001000, 0b11110000, //T 0b11111000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, //U 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b01110000, //V 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b01010000, 0b00100000, //W 0b10001000, 0b10001000, 0b10001000, 0b10101000, 0b10101000, 0b10101000, 0b01010000, //X 0b10001000, 0b10001000, 0b01010000, 0b00100000, 0b01010000, 0b10001000, 0b10001000, //Y 0b10001000, 0b10001000, 0b10001000, 0b01010000, 0b00100000, 0b00100000, 0b00100000, //Z 0b11111000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000, 0b11111000, //91 [ 0b11100000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11100000, //92 (backslash) 0b00000000, 0b10000000, 0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000000, //93 ] 0b00111000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00111000, //94 ^ 0b00100000, 0b01010000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //95 _ 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111000, //96 ` 0b10000000, 0b01000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //97 a 0b00000000, 0b01100000, 0b00010000, 0b01110000, 0b10010000, 0b01100000, 0b00000000, //98 b 0b10000000, 0b10000000, 0b11100000, 0b10010000, 0b10010000, 0b11100000, 0b00000000, //99 c 0b00000000, 0b00000000, 0b01110000, 0b10000000, 0b10000000, 0b01110000, 0b00000000, // 100 d 0b00010000, 0b00010000, 0b01110000, 0b10010000, 0b10010000, 0b01110000, 0b00000000, //101 e 0b00000000, 0b01100000, 0b10010000, 0b11110000, 0b10000000, 0b01110000, 0b00000000, //102 f 0b00110000, 0b01000000, 0b11100000, 0b01000000, 0b01000000, 0b01000000, 0b00000000, //103 g 0b00000000, 0b01100000, 0b10010000, 0b01110000, 0b00010000, 0b00010000, 0b01100000, //104 h 0b10000000, 0b10000000, 0b11100000, 0b10010000, 0b10010000, 0b10010000, 0b00000000, //105 i 0b00000000, 0b00100000, 0b00000000, 0b00100000, 0b00100000, 0b00100000, 0b00000000, //106 j 0b00000000, 0b00010000, 0b00000000, 0b00010000, 0b00010000, 0b00010000, 0b01100000, //107 k 0b10000000, 0b10010000, 0b10100000, 0b11000000, 0b10100000, 0b10010000, 0b00000000, //108 l 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00000000, //109 m 0b00000000, 0b00000000, 0b01010000, 0b10101000, 0b10101000, 0b10101000, 0b00000000, //110 n 0b00000000, 0b00000000, 0b01100000, 0b10010000, 0b10010000, 0b10010000, 0b00000000, //111 o 0b00000000, 0b00000000, 0b01100000, 0b10010000, 0b10010000, 0b01100000, 0b00000000, //112 p 0b00000000, 0b00000000, 0b01100000, 0b10010000, 0b11110000, 0b10000000, 0b10000000, //113 q 0b00000000, 0b00000000, 0b01100000, 0b10010000, 0b11110000, 0b00010000, 0b00010000, //114 r 0b00000000, 0b00000000, 0b10111000, 0b01000000, 0b01000000, 0b01000000, 0b00000000, //115 s 0b00000000, 0b00000000, 0b01110000, 0b01000000, 0b00010000, 0b01110000, 0b00000000, //116 t 0b01000000, 0b01000000, 0b11100000, 0b01000000, 0b01000000, 0b01000000, 0b00000000, // 117u 0b00000000, 0b00000000, 0b10010000, 0b10010000, 0b10010000, 0b01100000, 0b00000000, //118 v 0b00000000, 0b00000000, 0b10001000, 0b10001000, 0b01010000, 0b00100000, 0b00000000, //119 w 0b00000000, 0b00000000, 0b10101000, 0b10101000, 0b01010000, 0b01010000, 0b00000000, //120 x 0b00000000, 0b00000000, 0b10010000, 0b01100000, 0b01100000, 0b10010000, 0b00000000, //121 y 0b00000000, 0b00000000, 0b10010000, 0b10010000, 0b01100000, 0b01000000, 0b10000000, //122 z 0b00000000, 0b00000000, 0b11110000, 0b00100000, 0b01000000, 0b11110000, 0b00000000, //123 { 0b00100000, 0b01000000, 0b01000000, 0b10000000, 0b01000000, 0b01000000, 0b00100000, //124 | 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, //125 } 0b00100000, 0b00010000, 0b00010000, 0b00001000, 0b00010000, 0b00010000, 0b00100000, //126 ~ 0b00000000, 0b00000000, 0b01000000, 0b10101000, 0b00010000, 0b00000000, 0b00000000, //127 DEL 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }; unsigned int forward_matrix[2][72] = { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 2231, 2214, 2180, 2130, 2063, 1981, 1884, 1772, 1647, 1509, 1360, 1200, 1031, 855, 672, 483, 292, 97, 0, -292, -483, -672, -855, -1031, -1200, -1360, -1509, -1647, -1772, -1884, -1981, -2063, -2130, -2180, -2214, -2231, -2231, -2214, -2180, -2130, -2063, -1981, -1884, -1772, -1647, -1509, -1360, -1200, -1031, -855, -672, -483, -292, -97, 0, 292, 483, 672, 855, 1031, 1200, 1360, 1509, 1647, 1772, 1884, 1981, 2063, 2130, 2180, 2214, 2231, 0, -292, -483, -672, -855, -1031, -1200, -1360, -1509, -1647, -1772, -1884, -1981, -2063, -2130, -2180, -2214, -2231, -2231, -2214, -2180, -2130, -2063, -1981, -1884, -1772, -1647, -1509, -1360, -1200, -1031, -855, -672, -483, -292, -97, 0, 292, 483, 672, 855, 1031, 1200, 1360, 1509, 1647, 1772, 1884, 1981, 2063, 2130, 2180, 2214, 2231, 2231, 2214, 2180, 2130, 2063, 1981, 1884, 1772, 1647, 1509, 1360, 1200, 1031, 855, 672, 483, 292, 97}; unsigned int circle_matrix_30_in[2][72] = { 669, 664, 654, 639, 619, 594, 565, 532, 494, 453, 408, 360, 309, 256, 201, 145, 87, 29, -29, -87, -145, -201, -256, -309, -360, -408, -453, -494, -532, -565, -594, -619, -639, -654, -664, -669, -669, -664, -654, -639, -619, -594, -565, -532, -494, -453, -408, -360, -309, -256, -201, -145, -87, -29, 29, 87, 145, 201, 256, 309, 360, 408, 453, 494, 532, 565, 594, 619, 639, 654, 664, 669, -29, -87, -145, -201, -256, -309, -360, -408, -453, -494, -532, -565, -594, -619, -639, -654, -664, -669, -669, -664, -654, -639, -619, -594, -565, -532, -494, -453, -408, -360, -309, -256, -201, -145, -87, -29, 29, 87, 145, 201, 256, 309, 360, 408, 453, 494, 532, 565, 594, 619, 639, 654, 664, 669, 669, 664, 654, 639, 619, 594, 565, 532, 494, 453, 408, 360, 309, 256, 201, 145, 87, 29}; unsigned int circle_matrix_30_out[2][72] = { //outside 1045, 1037, 1021, 998, 967, 928, 882, 830, 771, 707, 637, 562, 483, 400, 315, 226, 137, 46, -46, -137, -226, -315, -400, -483, -562, -637, -707, -771, -830, -882, -928, -967, -998, -1021, -1037, -1045, -1045, -1037, -1021, -998, -967, -928, -882, -830, -771, -707, -637, -562, -483, -400, -315, -226, -137, -46, 46, 137, 226, 315, 400, 483, 562, 637, 707, 771, 830, 882, 928, 967, 998, 1021, 1037, 1045, -46, -137, -226, -315, -400, -483, -562, -637, -707, -771, -830, -882, -928, -967, -998, -1021, -1037, -1045, -1045, -1037, -1021, -998, -967, -928, -882, -830, -771, -707, -637, -562, -483, -400, -315, -226, -137, -46, 46, 137, 226, 315, 400, 483, 562, 637, 707, 771, 830, 882, 928, 967, 998, 1021, 1037, 1045, 1045, 1037, 1021, 998, 967, 928, 882, 830, 771, 707, 637, 562, 483, 400, 315, 226, 137, 46}; unsigned int circle_matrix_40_in[2][72] = { 892, 886, 872, 852, 825, 792, 753, 709, 659, 604, 544, 480, 412, 342, 269, 193, 117, 39, -39, -117, -193, -269, -342, -412, -480, -544, -604, -659, -709, -753, -792, -825, -852, -872, -886, -892, -892, -886, -872, -852, -825, -792, -753, -709, -659, -604, -544, -480, -412, -342, -269, -193, -117, -39, 39, 117, 193, 269, 342, 412, 480, 544, 604, 659, 709, 753, 792, 825, 852, 872, 886, 892, -39, -117, -193, -269, -342, -412, -480, -544, -604, -659, -709, -753, -792, -825, -852, -872, -886, -892, -892, -886, -872, -852, -825, -792, -753, -709, -659, -604, -544, -480, -412, -342, -269, -193, -117, -39, 39, 117, 193, 269, 342, 412, 480, 544, 604, 659, 709, 753, 792, 825, 852, 872, 886, 892, 892, 886, 872, 852, 825, 792, 753, 709, 659, 604, 544, 480, 412, 342, 269, 193, 117, 39}; unsigned int circle_matrix_40_out[2][72] = { 1298, 1288, 1269, 1239, 1201, 1153, 1096, 1031, 958, 878, 791, 698, 600, 497, 391, 281, 170, 57, -57, -170, -281, -391, -497, -600, -698, -791, -878, -958, -1031, -1096, -1153, -1201, -1239, -1269, -1288, -1298, -1298, -1288, -1269, -1239, -1201, -1153, -1096, -1031, -958, -878, -791, -698, -600, -497, -391, -281, -170, -57, 57, 170, 281, 391, 497, 600, 698, 791, 878, 958, 1031, 1096, 1153, 1201, 1239, 1269, 1288, 1298, -57, -170, -281, -391, -497, -600, -698, -791, -878, -958, -1031, -1096, -1153, -1201, -1239, -1269, -1288, -1298, -1298, -1288, -1269, -1239, -1201, -1153, -1096, -1031, -958, -878, -791, -698, -600, -497, -391, -281, -170, -57, 57, 170, 281, 391, 497, 600, 698, 791, 878, 958, 1031, 1096, 1153, 1201, 1239, 1269, 1288, 1298, 1298, 1288, 1269, 1239, 1201, 1153, 1096, 1031, 958, 878, 791, 698, 600, 497, 391, 281, 170, 57}; unsigned int circle_matrix_60_in[2][72] = { 1339, 1329, 1308, 1278, 1238, 1189, 1130, 1063, 988, 905, 816, 720, 619, 513, 403, 290, 175, 58, -58, -175, -290, -403, -513, -619, -720, -816, -905, -988, -1063, -1130, -1189, -1238, -1278, -1308, -1329, -1339, -1339, -1329, -1308, -1278, -1238, -1189, -1130, -1063, -988, -905, -816, -720, -619, -513, -403, -290, -175, -58, 58, 175, 290, 403, 513, 619, 720, 816, 905, 988, 1063, 1130, 1189, 1238, 1278, 1308, 1329, 1339, -58, -175, -290, -403, -513, -619, -720, -816, -905, -988, -1063, -1130, -1189, -1238, -1278, -1308, -1329, -1339, -1339, -1329, -1308, -1278, -1238, -1189, -1130, -1063, -988, -905, -816, -720, -619, -513, -403, -290, -175, -58, 58, 175, 290, 403, 513, 619, 720, 816, 905, 988, 1063, 1130, 1189, 1238, 1278, 1308, 1329, 1339, 1339, 1329, 1308, 1278, 1238, 1189, 1130, 1063, 988, 905, 816, 720, 619, 513, 403, 290, 175, 58}; unsigned int circle_matrix_60_out[2][72] = { 1766, 1752, 1725, 1686, 1633, 1568, 1491, 1402, 1303, 1194, 1076, 950, 816, 676, 531, 383, 231, 77, -77, -231, -383, -531, -676, -816, -950, -1076, -1194, -1303, -1402, -1491, -1568, -1633, -1686, -1725, -1752, -1766, -1766, -1752, -1725, -1686, -1633, -1568, -1491, -1402, -1303, -1194, -1076, -950, -816, -676, -531, -383, -231, -77, 77, 231, 383, 531, 676, 816, 950, 1076, 1194, 1303, 1402, 1491, 1568, 1633, 1686, 1725, 1752, 1766, -77, -231, -383, -531, -676, -816, -950, -1076, -1194, -1303, -1402, -1491, -1568, -1633, -1686, -1725, -1752, -1766, -1766, -1752, -1725, -1686, -1633, -1568, -1491, -1402, -1303, -1194, -1076, -950, -816, -676, -531, -383, -231, -77, 77, 231, 383, 531, 676, 816, 950, 1076, 1194, 1303, 1402, 1491, 1568, 1633, 1686, 1725, 1752, 1766, 1766, 1752, 1725, 1686, 1633, 1568, 1491, 1402, 1303, 1194, 1076, 950, 816, 676, 531, 383, 231, 77}; unsigned int circle_matrix_80_in[2][72] = { 1785, 1771, 1744, 1704, 1651, 1585, 1507, 1417, 1317, 1207, 1088, 960, 825, 684, 537, 387, 233, 78, -78, -233, -387, -537, -684, -825, -960, -1088, -1207, -1317, -1417, -1507, -1585, -1651, -1704, -1744, -1771, -1785, -1785, -1771, -1744, -1704, -1651, -1585, -1507, -1417, -1317, -1207, -1088, -960, -825, -684, -537, -387, -233, -78, 78, 233, 387, 537, 684, 825, 960, 1088, 1207, 1317, 1417, 1507, 1585, 1651, 1704, 1744, 1771, 1785, -78, -233, -387, -537, -684, -825, -960, -1088, -1207, -1317, -1417, -1507, -1585, -1651, -1704, -1744, -1771, -1785, -1785, -1771, -1744, -1704, -1651, -1585, -1507, -1417, -1317, -1207, -1088, -960, -825, -684, -537, -387, -233, -78, 78, 233, 387, 537, 684, 825, 960, 1088, 1207, 1317, 1417, 1507, 1585, 1651, 1704, 1744, 1771, 1785, 1785, 1771, 1744, 1704, 1651, 1585, 1507, 1417, 1317, 1207, 1088, 960, 825, 684, 537, 387, 233, 78}; unsigned int circle_matrix_80_out[2][72] = { 2220, 2203, 2169, 2119, 2053, 1971, 1874, 1763, 1638, 1501, 1353, 1194, 1026, 850, 668, 481, 290, 97, -97, -290, -481, -668, -850, -1026, -1194, -1353, -1501, -1638, -1763, -1874, -1971, -2053, -2119, -2169, -2203, -2220, -2220, -2203, -2169, -2119, -2053, -1971, -1874, -1763, -1638, -1501, -1353, -1194, -1026, -850, -668, -481, -290, -97, 97, 290, 481, 668, 850, 1026, 1194, 1353, 1501, 1638, 1763, 1874, 1971, 2053, 2119, 2169, 2203, 2220, -97, -290, -481, -668, -850, -1026, -1194, -1353, -1501, -1638, -1763, -1874, -1971, -2053, -2119, -2169, -2203, -2220, -2220, -2203, -2169, -2119, -2053, -1971, -1874, -1763, -1638, -1501, -1353, -1194, -1026, -850, -668, -481, -290, -97, 97, 290, 481, 668, 850, 1026, 1194, 1353, 1501, 1638, 1763, 1874, 1971, 2053, 2119, 2169, 2203, 2220, 2220, 2203, 2169, 2119, 2053, 1971, 1874, 1763, 1638, 1501, 1353, 1194, 1026, 850, 668, 481, 290, 97}; int a[21] = {0, 3, 5, 8, 10, 13, 15, 18, 20, 23, 25, 28, 30, 33, 35, 38, 40, 43, 45, 48, 50}; int b[21] = {50, 50, 50, 49, 49, 48, 48, 47, 46, 45, 43, 42, 40, 38, 36, 33, 30, 26, 22, 16, 0}; int a1[17] = {0, 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 21}; int b1[17] = {21, 21, 21, 21, 21, 20, 20, 19, 18, 18, 17, 15, 14, 12, 10, 7, 0}; // put the MCU to sleep JUST before the CompA ISR goes off ISR(TIMER1_COMPB_vect, ISR_NAKED) { sei(); sleep_cpu(); reti(); } //================================== //This is the sync generator and raster generator. It MUST be entered from //sleep mode to get accurate timing of the sync pulses ISR (TIMER1_COMPA_vect) { int x, screenStart ; //start the Horizontal sync pulse PORTD = syncON; //update the current scanline number LineCount++; //begin inverted (Vertical) synch after line 247 if (LineCount==248) { syncON = 0b00000001; syncOFF = 0; } //back to regular sync after line 250 if (LineCount==251) { syncON = 0; syncOFF = 0b00000001; } //start new frame after line 262 if (LineCount==263) LineCount = 1; //adjust to make 5 us pulses _delay_us(3); //end sync pulse PORTD = syncOFF; if (LineCount < ScreenBot && LineCount >= ScreenTop) { //compute offset into screen array //screenindex = screen + ((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop) << 3); //compute offset into screen array //screenStart = ((LineCount - ScreenTop) << 4) + ((LineCount - ScreenTop) << 3) ; screenStart = (LineCount - ScreenTop) * bytes_per_line; //center image on screen _delay_us(7); //blast the data to the screen // We can load UDR twice because it is double-bufffered UDR0 = screen[screenStart] ; UCSR0B = _BV(TXEN0); UDR0 = screen[screenStart+1] ; for (x = 2; x < bytes_per_line; x++) begin while (!(UCSR0A & _BV(UDRE0))) ; UDR0 = screen[screenStart+x] ; end UCSR0B = 0 ; } } //================================== //plot one point //at x,y with color 1=white 0=black 2=invert void video_pt(char x, char y, char c) { //each line has 18 bytes //calculate i based upon this and x,y // the byte with the pixel in it //int i = (x >> 3) + ((int)y<<4) + ((int)y<<1); int i = (x >> 3) + (int)y * bytes_per_line ; if (c==1) screen[i] = screen[i] | pos[x & 7]; else if (c==0) screen[i] = screen[i] & ~pos[x & 7]; else screen[i] = screen[i] ^ pos[x & 7]; } //================================== //plot a line //at x1,y1 to x2,y2 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from David Rodgers, //"Procedural Elements of Computer Graphics",1985 void video_line(char x1, char y1, char x2, char y2, char c) { int e; signed int dx,dy,j, temp; signed char s1,s2, xchange; signed int x,y; x = x1; y = y1; //take absolute value if (x2 < x1) { dx = x1 - x2; s1 = -1; } else if (x2 == x1) { dx = 0; s1 = 0; } else { dx = x2 - x1; s1 = 1; } if (y2 < y1) { dy = y1 - y2; s2 = -1; } else if (y2 == y1) { dy = 0; s2 = 0; } else { dy = y2 - y1; s2 = 1; } xchange = 0; if (dy>dx) { temp = dx; dx = dy; dy = temp; xchange = 1; } e = ((int)dy<<1) - dx; for (j=0; j<=dx; j++) { video_pt(x,y,c); if (e>=0) { if (xchange==1) x = x + s1; else y = y + s2; e = e - ((int)dx<<1); } if (xchange==1) y = y + s2; else x = x + s1; e = e + ((int)dy<<1); } } //================================== // put a big character on the screen // c is index into bitmap void video_putchar(char x, char y, char c) { char i; char y_pos; uint8_t j; for (i=0;i<7;i++) { y_pos = y + i; j = pgm_read_byte(((uint32_t)(ascii)) + c*7 + i); video_pt(x, y_pos, (j & 0x80)==0x80); video_pt(x+1, y_pos, (j & 0x40)==0x40); video_pt(x+2, y_pos, (j & 0x20)==0x20); video_pt(x+3, y_pos, (j & 0x10)==0x10); video_pt(x+4, y_pos, (j & 0x08)==0x08); } } //================================== // put a string of big characters on the screen void video_puts(char x, char y, char *str) { char i; for (i=0; str[i]!=0; i++) { video_putchar(x,y,str[i]); x = x+6; } } //================================== // put a small character on the screen // x-coord must be on divisible by 4 // c is index into bitmap void video_smallchar(char x, char y, char c) { char mask; //int i=((int)x>>3) + ((int)y<<4) + ((int)y<<1); int i=((int)x>>3) + (int)y * bytes_per_line ; if (x == (x & 0xf8)) mask = 0x0f; //f8 else mask = 0xf0; uint8_t j = pgm_read_byte(((uint32_t)(smallbitmap)) + c*5); screen[i] = (screen[i] & mask) | (j & ~mask); j = pgm_read_byte(((uint32_t)(smallbitmap)) + c*5 + 1); screen[i+bytes_per_line] = (screen[i+bytes_per_line] & mask) | (j & ~mask); j = pgm_read_byte(((uint32_t)(smallbitmap)) + c*5 + 2); screen[i+bytes_per_line*2] = (screen[i+bytes_per_line*2] & mask) | (j & ~mask); j = pgm_read_byte(((uint32_t)(smallbitmap)) + c*5 + 3); screen[i+bytes_per_line*3] = (screen[i+bytes_per_line*3] & mask) | (j & ~mask); j = pgm_read_byte(((uint32_t)(smallbitmap)) + c*5 + 4); screen[i+bytes_per_line*4] = (screen[i+bytes_per_line*4] & mask) | (j & ~mask); } //================================== // put a string of small characters on the screen // x-cood must be on divisible by 4 void video_putsmalls(char x, char y, char *str) { char i; x = x & 0b11111100; //make it divisible by 4 for (i = 0; str[i] != 0; i++) { if (str[i] >= 0x30 && str[i] <= 0x3a) video_smallchar(x, y, str[i] - 0x30); else video_smallchar(x, y, str[i]-0x40+12); x += 4; } } //================================== //return the value of one point //at x,y with color 1=white 0=black 2=invert char video_set(char x, char y) { //The following construction //detects exactly one bit at the x,y location // int i = (x>>3) + ((int)y<<4) + ((int)y<<3); int i = (x>>3) + (int)y * bytes_per_line ; return (screen[i] & 1<<(7-(x & 0x7))); } //================================== //check a line at x1,y1 to x2,y2 //and return with color 1=white 0=black 2=invert //Code is from Lu Liu char video_line_set(char x1, char y1, char x2, char y2) { int e; signed int dx,dy,j, temp; signed char s1,s2, xchange; signed int x,y; char color = 0; int thresh = 0; x = x1; y = y1; //take absolute value if (x2 < x1) { dx = x1 - x2; s1 = -1; } else if (x2 == x1) { dx = 0; s1 = 0; } else { dx = x2 - x1; s1 = 1; } if (y2 < y1) { dy = y1 - y2; s2 = -1; } else if (y2 == y1) { dy = 0; s2 = 0; } else { dy = y2 - y1; s2 = 1; } xchange = 0; if (dy>dx) { temp = dx; dx = dy; dy = temp; xchange = 1; } e = ((int)dy<<1) - dx; for (j=0; j<=dx; j++) { color = video_set(x, y); if (color != 0) { thresh ++; } if (thresh > 4) break; if (e>=0) { if (xchange==1) x = x + s1; else y = y + s2; e = e - ((int)dx<<1); } if (xchange==1) y = y + s2; else x = x + s1; e = e + ((int)dy<<1); } return (thresh>4); } //================================== //plot a rectangle //at x0,y0 to x1,y1 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from Lu Liu int video_rectangle(int x0, int y0, int x1, int y1, float length, int *coord, int plot, char c) { int x2,x3,y2,y3; float temp; float length_sq = length * length; int dx10 = x1 - x0; int dy10 = y1 - y0; int dx10_sq = dx10 * dx10; int dy10_sq = dy10 * dy10; int idx = 0; // calculate the coordinate of (x2,y2), (x3,y3) if (x0 == x1) { if (y0 < y1) { x2 = x0 - length; y2 = y0; } else { x2 = x0 + length; y2 = y0; } } else if (y0 == y1) { if (x0 < x1) { x2 = x0; y2 = y0 + length; } else { x2 = x0; y2 = y0 - length; } } else { if (dy10 < -3 || dy10 > 3) { temp = sqrt((length_sq * dy10_sq) / (dy10_sq + dx10_sq)); if (dy10 < 0) x2 = temp + x0; else x2 = x0 - temp; y2 = (-1)*(x2-x0)*dx10 / dy10 + y0; } else if (dy10 >= -3 && dy10 <= 3) { if (length > 40) { if (dy10 < 0 && dx10 > 0) { idx = (-1)*dy10; x2 = x0 + a[idx]; y2 = y0 + b[idx]; } else if (dy10 < 0 && dx10 < 0) { idx = (-1)*dy10; x2 = x0 + a[idx]; y2 = y0 - b[idx]; } else if (dy10 > 0 && dx10 < 0) { idx = dy10; x2 = x0 - a[idx]; y2 = y0 - b[idx]; } else if (dy10 > 0 && dx10 > 0) { idx = dy10; x2 = x0 - a[idx]; y2 = y0 + b[idx]; } } else { if (dy10 < 0 && dx10 > 0) { idx = (-1)*dy10; x2 = x0 + a1[idx]; y2 = y0 + b1[idx]; } else if (dy10 < 0 && dx10 < 0) { idx = (-1)*dy10; x2 = x0 + a1[idx]; y2 = y0 - b1[idx]; } else if (dy10 > 0 && dx10 < 0) { idx = dy10; x2 = x0 - a1[idx]; y2 = y0 - b1[idx]; } else if (dy10 > 0 && dx10 > 0) { idx = dy10; x2 = x0 - a1[idx]; y2 = y0 + b1[idx]; } } } } x3 = x2 + dx10; y3 = y2 + dy10; // return coordinate coord[0] = x0; coord[1] = y0; coord[2] = x1; coord[3] = y1; coord[4] = x2; coord[5] = y2; coord[6] = x3; coord[7] = y3; if (x0 < 0 || x0 > 160 || x1 < 0 || x1 > 160 || x2 < 0 || x2 > 160 || x3 < 0 || x3 > 160 || y0 < 0 || y0 > 200 || y1 < 0 || y1 > 200 || y2 < 0 || y2 > 200 || y3 < 0 || y3 > 200 ) { /* fprintf(stdout, "rectangle_plot:\n"); fprintf(stdout, "%d, %d\n", x0, y0); fprintf(stdout, "%d, %d\n", x1, y1); fprintf(stdout, "%d, %d\n", x2, y2); fprintf(stdout, "%d, %d\n", x3, y3); */ return 1; } else { // plot the rectangle if instructed to do so if (plot == 1) { video_line(x0,y0,x1,y1,c); video_line(x0,y0,x2,y2,c); video_line(x2,y2,x3,y3,c); video_line(x1,y1,x3,y3,c); } return 0; } } //================================== //plot a rectangle with length as fix //at x0,y0 to x1,y1 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from Lu Liu void video_rectangle_fix(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int length, unsigned int *coord) { unsigned int x2,x3,y2,y3; float temp; unsigned int length_angle = 0; // calculate the coordinate of (x2,y2), (x3,y3) x2 = x0; x3 = x1; y2 = y0; y3 = y1; // if going forward/backward if (car_angle >= -5 && car_angle <= 5) { if (reverse == 0 && car_gas != 0) { x2 = x0 + multfix(forward_matrix[1][angle_state], length); y2 = y0 + multfix(forward_matrix[0][angle_state], length); x3 = x1 + multfix(forward_matrix[1][angle_state], length); y3 = y1 + multfix(forward_matrix[0][angle_state], length); } else if (reverse == 1 && car_gas != 0) { x2 = x0 - multfix(forward_matrix[1][angle_state], length); y2 = y0 - multfix(forward_matrix[0][angle_state], length); x3 = x1 - multfix(forward_matrix[1][angle_state], length); y3 = y1 - multfix(forward_matrix[0][angle_state], length); } } else if (car_gas != 0) { //temp = 1.0/limit; //length_angle = float2fix(temp); if (car_gas != 0) { switch (car_gas) begin case 1 : length_angle = fix_1_30; break; case 2 : length_angle = fix_2_30; break; case 3 : length_angle = fix_3_30; break; end } // if wheel angle is: if (car_angle > 5 && car_angle < 15) { if (reverse == 0) { x2 = x0 + multfix(circle_matrix_80_out[1][angle_state], length_angle); y2 = y0 + multfix(circle_matrix_80_out[0][angle_state], length_angle); x3 = x1 + multfix(circle_matrix_80_in[1][angle_state], length_angle); y3 = y1 + multfix(circle_matrix_80_in[0][angle_state], length_angle); } else { x2 = x0 - multfix(circle_matrix_80_out[1][angle_state], length_angle); y2 = y0 - multfix(circle_matrix_80_out[0][angle_state], length_angle); x3 = x1 - multfix(circle_matrix_80_in[1][angle_state], length_angle); y3 = y1 - multfix(circle_matrix_80_in[0][angle_state], length_angle); } } else if (car_angle >= 15 && car_angle < 25) { if (reverse == 0) { x2 = x0 + multfix(circle_matrix_60_out[1][angle_state], length_angle); y2 = y0 + multfix(circle_matrix_60_out[0][angle_state], length_angle); x3 = x1 + multfix(circle_matrix_60_in[1][angle_state], length_angle); y3 = y1 + multfix(circle_matrix_60_in[0][angle_state], length_angle); } else { x2 = x0 - multfix(circle_matrix_60_out[1][angle_state], length_angle); y2 = y0 - multfix(circle_matrix_60_out[0][angle_state], length_angle); x3 = x1 - multfix(circle_matrix_60_in[1][angle_state], length_angle); y3 = y1 - multfix(circle_matrix_60_in[0][angle_state], length_angle); } } else if (car_angle >= 25 && car_angle < 35) { if (reverse == 0) { x2 = x0 + multfix(circle_matrix_40_out[1][angle_state], length_angle); y2 = y0 + multfix(circle_matrix_40_out[0][angle_state], length_angle); x3 = x1 + multfix(circle_matrix_40_in[1][angle_state], length_angle); y3 = y1 + multfix(circle_matrix_40_in[0][angle_state], length_angle); } else { x2 = x0 - multfix(circle_matrix_40_out[1][angle_state], length_angle); y2 = y0 - multfix(circle_matrix_40_out[0][angle_state], length_angle); x3 = x1 - multfix(circle_matrix_40_in[1][angle_state], length_angle); y3 = y1 - multfix(circle_matrix_40_in[0][angle_state], length_angle); } } else if (car_angle >= 35 && car_angle <= 45) { if (reverse == 0) { x2 = x0 + multfix(circle_matrix_30_out[1][angle_state], length_angle); y2 = y0 + multfix(circle_matrix_30_out[0][angle_state], length_angle); x3 = x1 + multfix(circle_matrix_30_in[1][angle_state], length_angle); y3 = y1 + multfix(circle_matrix_30_in[0][angle_state], length_angle); } else { x2 = x0 - multfix(circle_matrix_30_out[1][angle_state], length_angle); y2 = y0 - multfix(circle_matrix_30_out[0][angle_state], length_angle); x3 = x1 - multfix(circle_matrix_30_in[1][angle_state], length_angle); y3 = y1 - multfix(circle_matrix_30_in[0][angle_state], length_angle); } // the other direction: } else if (car_angle < -5 && car_angle > -15) { if (reverse == 0) { x2 = x0 - multfix(circle_matrix_80_in[1][angle_state_2], length_angle); y2 = y0 - multfix(circle_matrix_80_in[0][angle_state_2], length_angle); x3 = x1 - multfix(circle_matrix_80_out[1][angle_state_2], length_angle); y3 = y1 - multfix(circle_matrix_80_out[0][angle_state_2], length_angle); } else { x2 = x0 + multfix(circle_matrix_80_in[1][angle_state_2], length_angle); y2 = y0 + multfix(circle_matrix_80_in[0][angle_state_2], length_angle); x3 = x1 + multfix(circle_matrix_80_out[1][angle_state_2], length_angle); y3 = y1 + multfix(circle_matrix_80_out[0][angle_state_2], length_angle); } } else if (car_angle <= -15 && car_angle > -25) { if (reverse == 0) { x2 = x0 - multfix(circle_matrix_60_in[1][angle_state_2], length_angle); y2 = y0 - multfix(circle_matrix_60_in[0][angle_state_2], length_angle); x3 = x1 - multfix(circle_matrix_60_out[1][angle_state_2], length_angle); y3 = y1 - multfix(circle_matrix_60_out[0][angle_state_2], length_angle); } else { x2 = x0 + multfix(circle_matrix_60_in[1][angle_state_2], length_angle); y2 = y0 + multfix(circle_matrix_60_in[0][angle_state_2], length_angle); x3 = x1 + multfix(circle_matrix_60_out[1][angle_state_2], length_angle); y3 = y1 + multfix(circle_matrix_60_out[0][angle_state_2], length_angle); } } else if (car_angle <= -25 && car_angle > -35) { if (reverse == 0) { x2 = x0 - multfix(circle_matrix_40_in[1][angle_state_2], length_angle); y2 = y0 - multfix(circle_matrix_40_in[0][angle_state_2], length_angle); x3 = x1 - multfix(circle_matrix_40_out[1][angle_state_2], length_angle); y3 = y1 - multfix(circle_matrix_40_out[0][angle_state_2], length_angle); } else { x2 = x0 + multfix(circle_matrix_40_in[1][angle_state_2], length_angle); y2 = y0 + multfix(circle_matrix_40_in[0][angle_state_2], length_angle); x3 = x1 + multfix(circle_matrix_40_out[1][angle_state_2], length_angle); y3 = y1 + multfix(circle_matrix_40_out[0][angle_state_2], length_angle); } } else if (car_angle <= -35 && car_angle >= -45) { if (reverse == 0) { x2 = x0 - multfix(circle_matrix_30_in[1][angle_state_2], length_angle); y2 = y0 - multfix(circle_matrix_30_in[0][angle_state_2], length_angle); x3 = x1 - multfix(circle_matrix_30_out[1][angle_state_2], length_angle); y3 = y1 - multfix(circle_matrix_30_out[0][angle_state_2], length_angle); } else { x2 = x0 + multfix(circle_matrix_30_in[1][angle_state_2], length_angle); y2 = y0 + multfix(circle_matrix_30_in[0][angle_state_2], length_angle); x3 = x1 + multfix(circle_matrix_30_out[1][angle_state_2], length_angle); y3 = y1 + multfix(circle_matrix_30_out[0][angle_state_2], length_angle); } } } // return coordinate coord[0] = x0; coord[1] = y0; coord[2] = x1; coord[3] = y1; coord[4] = x2; coord[5] = y2; coord[6] = x3; coord[7] = y3; } //================================== //plot a car //at x0,y0 to x1,y1 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from Lu Liu int video_car(int x0, int y0, int x1, int y1, int plot, char c) { int x2,y2; int x3,y3; int x4,y4; int x5,y5; int x6,y6; int x7,y7; int x8,y8; int x9,y9; int x10,y10; int x11,y11; int x12,y12; int x13,y13; int x14,y14; int x15,y15; int x16,y16; int x17,y17; int x18,y18; int x19,y19; int x20,y20; int x21,y21; int vec_1_dx = x1-x0; int vec_1_dy = y1-y0; int vec_2_dx; int vec_2_dy; //float length_vec_1 = sqrt(vec_1_dx*vec_1_dx + vec_1_dy*vec_1_dy); //float length_vec_2 = 2.5*length_vec_1; int length_vec_1 = car_width; int length_vec_2 = car_length; int coord_int[8]; int error; // calculate all the points x2 = x0 + (int)(0.3*vec_1_dx); y2 = y0 + (int)(0.3*vec_1_dy); x3 = x0 + (int)(0.7*vec_1_dx); y3 = y0 + (int)(0.7*vec_1_dy); error = video_rectangle(x0,y0,x1,y1,length_vec_2,&coord_int[0],0,0); if (error == 1) { return 1; } x4 = coord_int[4]; y4 = coord_int[5]; x5 = coord_int[6]; y5 = coord_int[7]; vec_2_dx = x4 - x0; vec_2_dy = y4 - y0; x6 = x0 + (int)(0.25*vec_2_dx); y6 = y0 + (int)(0.25*vec_2_dy); x7 = x1 + (int)(0.25*vec_2_dx); y7 = y1 + (int)(0.25*vec_2_dy); x8 = x0 + (int)(0.03125*vec_2_dx); y8 = y0 + (int)(0.03125*vec_2_dy); x9 = x1 + (int)(0.03125*vec_2_dx); y9 = y1 + (int)(0.03125*vec_2_dy); x10 = x0 + (int)(0.45*vec_2_dx); y10 = y0 + (int)(0.45*vec_2_dy); x11 = x1 + (int)(0.45*vec_2_dx); y11 = y1 + (int)(0.45*vec_2_dy); x12 = x10 + (int)(0.1*vec_1_dx); y12 = y10 + (int)(0.1*vec_1_dy); x13 = x11 - (int)(0.1*vec_1_dx); y13 = y11 - (int)(0.1*vec_1_dy); error = video_rectangle(x12,y12,x13,y13,0.425*length_vec_2,&coord_int[0],0,0); if (error == 1) { return 1; } x14 = coord_int[4]; y14 = coord_int[5]; x15 = coord_int[6]; y15 = coord_int[7]; x16 = x4 + (int)(0.4*vec_1_dx); y16 = y4 + (int)(0.4*vec_1_dy); x17 = x5 - (int)(0.4*vec_1_dx); y17 = y5 - (int)(0.4*vec_1_dy); x18 = x4 - (int)(0.03125*vec_2_dx); y18 = y4 - (int)(0.03125*vec_2_dy); x19 = x5 - (int)(0.03125*vec_2_dx); y19 = y5 - (int)(0.03125*vec_2_dy); x20 = x10 - (int)(0.1*vec_1_dx); y20 = y10 - (int)(0.1*vec_1_dy); x21 = x11 + (int)(0.1*vec_1_dx); y21 = y11 + (int)(0.1*vec_1_dy); /* coord[0] = x0; coord[1] = y0; coord[2] = x1; coord[3] = y1; coord[4] = x2; coord[5] = y2; coord[6] = x3; coord[7] = y3; coord[8] = x4; coord[9] = y4; coord[10] = x5; coord[11] = y5; coord[12] = x6; coord[13] = y6; coord[14] = x7; coord[15] = y7; coord[16] = x8; coord[17] = y8; coord[18] = x9; coord[19] = y9; coord[20] = x10; coord[21] = y10; coord[22] = x11; coord[23] = y11; coord[24] = x12; coord[25] = y12; coord[26] = x13; coord[27] = y13; coord[28] = x14; coord[29] = y14; coord[30] = x15; coord[31] = y15; coord[32] = x16; coord[33] = y16; coord[34] = x17; coord[35] = y17; coord[36] = x18; coord[37] = y18; coord[38] = x19; coord[39] = y19; coord[40] = x20; coord[41] = y20; coord[42] = x21; coord[43] = y21; */ // safe check: if (x0 < 0 || x0 > 160 || x1 < 0 || x1 > 160 || x2 < 0 || x2 > 160 || x3 < 0 || x3 > 160 || x4 < 0 || x4 > 160 || x5 < 0 || x5 > 160 || x6 < 0 || x6 > 160 || x7 < 0 || x7 > 160 || x8 < 0 || x8 > 160 || x9 < 0 || x9 > 160 || x10 < 0 || x10 > 160 || x11 < 0 || x11 > 160 || x12 < 0 || x12 > 160 || x13 < 0 || x13 > 160 || x14 < 0 || x14 > 160 || x15 < 0 || x15 > 160 || x16 < 0 || x16 > 160 || x17 < 0 || x17 > 160 || x18 < 0 || x18 > 160 || x19 < 0 || x19 > 160 || x20 < 0 || x20 > 160 || x21 < 0 || x21 > 160 || y0 < 0 || y0 > 200 || y1 < 0 || y1 > 200 || y2 < 0 || y2 > 200 || y3 < 0 || y3 > 200 || y4 < 0 || y4 > 200 || y5 < 0 || y5 > 200 || y6 < 0 || y6 > 200 || y7 < 0 || y7 > 200 || y8 < 0 || y8 > 200 || y9 < 0 || y9 > 200 || y10 < 0 || y10 > 200 || y11 < 0 || y11 > 200 || y12 < 0 || y12 > 200 || y13 < 0 || y13 > 200 || y14 < 0 || y14 > 200 || y15 < 0 || y15 > 200 || y16 < 0 || y16 > 200 || y17 < 0 || y17 > 200 || y18 < 0 || y18 > 200 || y19 < 0 || y19 > 200 || y20 < 0 || y20 > 200 || y21 < 0 || y21 > 200 ) { /* fprintf(stdout, "car_plot:\n"); fprintf(stdout, "length = %f\n", length_vec_2); fprintf(stdout, "0 %d, %d\n", x0, y0); fprintf(stdout, "1 %d, %d\n", x1, y1); fprintf(stdout, "2 %d, %d\n", x2, y2); fprintf(stdout, "3 %d, %d\n", x3, y3); fprintf(stdout, "4 %d, %d\n", x4, y4); fprintf(stdout, "5 %d, %d\n", x5, y5); fprintf(stdout, "6 %d, %d\n", x6, y6); fprintf(stdout, "7 %d, %d\n", x7, y7); fprintf(stdout, "8 %d, %d\n", x8, y8); fprintf(stdout, "9 %d, %d\n", x9, y9); fprintf(stdout, "10 %d, %d\n", x10, y10); fprintf(stdout, "11 %d, %d\n", x11, y11); fprintf(stdout, "12 %d, %d\n", x12, y12); fprintf(stdout, "13 %d, %d\n", x13, y13); fprintf(stdout, "14 %d, %d\n", x14, y14); fprintf(stdout, "15 %d, %d\n", x15, y15); fprintf(stdout, "16 %d, %d\n", x16, y16); fprintf(stdout, "17 %d, %d\n", x17, y17); fprintf(stdout, "18 %d, %d\n", x18, y18); fprintf(stdout, "19 %d, %d\n", x19, y19); fprintf(stdout, "20 %d, %d\n", x20, y20); fprintf(stdout, "21 %d, %d\n", x21, y21); */ return 1; } else { error = 0; } if (plot == 1) { // now plot them video_line(x2,y2,x3,y3,c); video_line(x0,y0,x4,y4,c); video_line(x1,y1,x5,y5,c); video_line(x16,y16,x17,y17,c); video_line(x12,y12,x13,y13,c); video_line(x12,y12,x14,y14,c); video_line(x14,y14,x15,y15,c); video_line(x13,y13,x15,y15,c); video_line(x2,y2,x8,y8,c); video_line(x3,y3,x9,y9,c); video_line(x6,y6,x7,y7,c); video_line(x6,y6,x12,y12,c); video_line(x7,y7,x13,y13,c); video_line(x14,y14,x4,y4,c); video_line(x15,y15,x5,y5,c); video_line(x16,y16,x18,y18,c); video_line(x17,y17,x19,y19,c); video_line(x6,y6,x20,y20,c); video_line(x7,y7,x21,y21,c); } return error; } //================================== //drive the current car forward by 1 unit //the current position of the car is //at x0,y0 to x1,y1 with color 1=white 0=black 2=invert //speed: 0: stop, 1: slow moving: 2: faster moving, 3: fastest //NOTE: this function requires signed chars //Code is from Lu Liu int start_car(unsigned int *x0, unsigned int *y0, unsigned int *x1, unsigned int *y1, int speed) { int error; unsigned int length; unsigned int coord[8]; int x0_int, x1_int, y0_int, y1_int; int x0_int2, x1_int2, y0_int2, y1_int2; x0_int = fix2int(*x0)+128; y0_int = fix2int(*y0)+128; x1_int = fix2int(*x1)+128; y1_int = fix2int(*y1)+128; switch (speed) begin case 0 : length = 0; break; case 1 : length = vcar_unit[0]; break; case 2 : length = vcar_unit[1]; break; case 3 : length = vcar_unit[2]; break; default : length = 0; end // this calculates the new coordinates of the car video_rectangle_fix(*x0, *y0, *x1, *y1, length, &coord[0]); x0_int2 = fix2int(coord[4])+128; y0_int2 = fix2int(coord[5])+128; x1_int2 = fix2int(coord[6])+128; y1_int2 = fix2int(coord[7])+128; // check if the new position is valid: error = video_car(x0_int2,y0_int2,x1_int2,y1_int2,0,0); // if valid if (error == 0) { // erase the car in current position error = video_car(x0_int,y0_int,x1_int,y1_int,1,0); // redraw the car in new position error = video_car(x0_int2,y0_int2,x1_int2,y1_int2,1,2); // update the current position *x0 = coord[4]; *y0 = coord[5]; *x1 = coord[6]; *y1 = coord[7]; } return error; } //================================== //plot parking lot type 0 //Code is from Lu Liu void plot_parking_lot_0(void) { int error; // plot parking lot lines: video_line(100, 0, 160, 0, 1); video_line(100, 40, 160, 40, 1); video_line(100, 80, 160, 80, 1); video_line(100, 120, 160, 120, 1); video_line(100, 160, 160, 160, 1); video_line(100, 199, 160, 199, 1); video_line(159, 0, 159, 199, 1); // plot cars: error = video_car(105,30,105,10,1,1); error = video_car(95,148,100,126,1,1); error = video_car(158,168,158,193,1,1); } //================================== //plot parking lot type 0 //Code is from Lu Liu void plot_parking_lot_1(void) { int error; // plot parking lot lines: video_line(79, 0, 79, 20, 1); video_line(79, 40, 79, 60, 1); video_line(79, 80, 79, 100, 1); video_line(79, 120, 79, 140, 1); video_line(79, 160, 79, 180, 1); video_line(5, 0, 5, 199, 1); video_line(5, 0, 30, 0, 1); video_line(5, 60, 30, 60, 1); video_line(5, 140, 10, 140, 1); video_line(5, 199, 30, 199, 1); video_line(154, 0, 130, 0, 1); video_line(154, 70, 130, 70, 1); video_line(154, 140, 130, 140, 1); video_line(154, 199, 130, 199, 1); video_line(154, 0, 154, 199, 1); video_line(159, 0, 159, 199, 1); video_line(130, 140, 154, 199, 1); video_line(154, 140, 130, 199, 1); // plot cars: error = video_car(30,53,10,53,1,1); error = video_car(28,189,8,189,1,1); error = video_car(130,5,150,5,1,1); error = video_car(128,73,150,76,1,1); } //===================================== // adjust idx and idx_2 (angle_state) // according to current car coordinate void adjust_angle_state(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int *idx, int *idx_2) { int x0_int = fix2int(x0) + 128; int y0_int = fix2int(y0) + 128; int x1_int = fix2int(x1) + 128; int y1_int = fix2int(y1) + 128; float temp; if (x0_int == x1_int) { if (y0_int < y1_int) { *idx = 54; *idx_2 = 18; } else if (y0_int > y1_int) { *idx = 18; *idx_2 = 54; } } else if (y0_int == y1_int) { if (x0_int < x1_int) { *idx = 36; *idx_2 = 0; } else if (x0_int > x1_int) { *idx = 0; *idx_2 = 36; } } else { temp = (1.0*(y1_int - y0_int)) / (x1_int - x0_int); // first quadrant if (x1_int > x0_int && y1_int > y0_int) { if ( temp < 0.043661) { *idx = 36; *idx_2 = 0; } else if ( temp > 0.043661 && temp < 0.131652) { *idx = 37; *idx_2 = 1; } else if ( temp > 0.131652 && temp < 0.221695) { *idx = 38; *idx_2 = 2; } else if ( temp > 0.221695 && temp < 0.315299) { *idx = 39; *idx_2 = 3; } else if ( temp > 0.315299 && temp < 0.414214) { *idx = 40; *idx_2 = 4; } else if ( temp > 0.414214 && temp < 0.520567) { *idx = 41; *idx_2 = 5; } else if ( temp > 0.520567 && temp < 0.637070) { *idx = 42; *idx_2 = 6; } else if ( temp > 0.637070 && temp < 0.767327) { *idx = 43; *idx_2 = 7; } else if ( temp > 0.767327 && temp < 0.916331) { *idx = 44; *idx_2 = 8; } else if ( temp > 0.916331 && temp < 1.091309) { *idx = 45; *idx_2 = 9; } else if ( temp > 1.091309 && temp < 1.303225) { *idx = 46; *idx_2 = 10; } else if ( temp > 1.303225 && temp < 1.569686) { *idx = 47; *idx_2 = 11; } else if ( temp > 1.569686 && temp < 1.920982) { *idx = 48; *idx_2 = 12; } else if ( temp > 1.920982 && temp < 2.414214) { *idx = 49; *idx_2 = 13; } else if ( temp > 2.414214 && temp < 3.171595) { *idx = 50; *idx_2 = 14; } else if ( temp > 3.171595 && temp < 4.510709) { *idx = 51; *idx_2 = 15; } else if ( temp > 4.510709 && temp < 7.595754) { *idx = 52; *idx_2 = 16; } else if ( temp > 7.595754 && temp < 22.903766) { *idx = 53; *idx_2 = 17; } else if (temp > 22.903766) { *idx = 54; *idx_2 = 18; } // second quadrant } else if (x1_int < x0_int && y1_int > y0_int) { if ( temp < -22.903766) { *idx = 54; *idx_2 = 18; } else if ( temp > -22.903766 && temp < -7.595754) { *idx = 55; *idx_2 = 19; } else if ( temp > -7.595754 && temp < -4.510709) { *idx = 56; *idx_2 = 20; } else if ( temp > -4.510709 && temp < -3.171595) { *idx = 57; *idx_2 = 21; } else if ( temp > -3.171595 && temp < -2.414214) { *idx = 58; *idx_2 = 22; } else if ( temp > -2.414214 && temp < -1.920982) { *idx = 59; *idx_2 = 23; } else if ( temp > -1.920982 && temp < -1.569686) { *idx = 60; *idx_2 = 24; } else if ( temp > -1.569686 && temp < -1.303225) { *idx = 61; *idx_2 = 25; } else if ( temp > -1.303225 && temp < -1.091309) { *idx = 62; *idx_2 = 26; } else if ( temp > -1.091309 && temp < -0.916331) { *idx = 63; *idx_2 = 27; } else if ( temp > -0.916331 && temp < -0.767327) { *idx = 64; *idx_2 = 28; } else if ( temp > -0.767327 && temp < -0.637070) { *idx = 65; *idx_2 = 29; } else if ( temp > -0.637070 && temp < -0.520567) { *idx = 66; *idx_2 = 30; } else if ( temp > -0.520567 && temp < -0.414214) { *idx = 67; *idx_2 = 31; } else if ( temp > -0.414214 && temp < -0.315299) { *idx = 68; *idx_2 = 32; } else if ( temp > -0.315299 && temp < -0.221695) { *idx = 69; *idx_2 = 33; } else if ( temp > -0.221695 && temp < -0.131652) { *idx = 70; *idx_2 = 34; } else if ( temp > -0.131652 && temp < -0.043661) { *idx = 71; *idx_2 = 35; } else if ( temp > -0.043661) { *idx = 0; *idx_2 = 36; } // third quadrant } else if (x1_int < x0_int && y1_int < y0_int) { if ( temp < 0.043661) { *idx = 0; *idx_2 = 36; } else if ( temp > 0.043661 && temp < 0.131652) { *idx = 1; *idx_2 = 37; } else if ( temp > 0.131652 && temp < 0.221695) { *idx = 2; *idx_2 = 38; } else if ( temp > 0.221695 && temp < 0.315299) { *idx = 3; *idx_2 = 39; } else if ( temp > 0.315299 && temp < 0.414214) { *idx = 4; *idx_2 = 40; } else if ( temp > 0.414214 && temp < 0.520567) { *idx = 5; *idx_2 = 41; } else if ( temp > 0.520567 && temp < 0.637070) { *idx = 6; *idx_2 = 42; } else if ( temp > 0.637070 && temp < 0.767327) { *idx = 7; *idx_2 = 43; } else if ( temp > 0.767327 && temp < 0.916331) { *idx = 8; *idx_2 = 44; } else if ( temp > 0.916331 && temp < 1.091309) { *idx = 9; *idx_2 = 45; } else if ( temp > 1.091309 && temp < 1.303225) { *idx = 10; *idx_2 = 46; } else if ( temp > 1.303225 && temp < 1.569686) { *idx = 11; *idx_2 = 47; } else if ( temp > 1.569686 && temp < 1.920982) { *idx = 12; *idx_2 = 48; } else if ( temp > 1.920982 && temp < 2.414214) { *idx = 13; *idx_2 = 49; } else if ( temp > 2.414214 && temp < 3.171595) { *idx = 14; *idx_2 = 50; } else if ( temp > 3.171595 && temp < 4.510709) { *idx = 15; *idx_2 = 51; } else if ( temp > 4.510709 && temp < 7.595754) { *idx = 16; *idx_2 = 52; } else if ( temp > 7.595754 && temp < 22.903766) { *idx = 17; *idx_2 = 53; } else if ( temp > 22.903766) { *idx = 18; *idx_2 = 54; } // fourth quadrant } else if (x1_int > x0_int && y1_int < y0_int) { if ( temp < -22.903766) { *idx = 18; *idx_2 = 54; } else if ( temp > -22.903766 && temp < -7.595754) { *idx = 19; *idx_2 = 55; } else if ( temp > -7.595754 && temp < -4.510709) { *idx = 20; *idx_2 = 56; } else if ( temp > -4.510709 && temp < -3.171595) { *idx = 21; *idx_2 = 57; } else if ( temp > -3.171595 && temp < -2.414214) { *idx = 22; *idx_2 = 58; } else if ( temp > -2.414214 && temp < -1.920982) { *idx = 23; *idx_2 = 59; } else if ( temp > -1.920982 && temp < -1.569686) { *idx = 24; *idx_2 = 60; } else if ( temp > -1.569686 && temp < -1.303225) { *idx = 25; *idx_2 = 61; } else if ( temp > -1.303225 && temp < -1.091309) { *idx = 26; *idx_2 = 62; } else if ( temp > -1.091309 && temp < -0.916331) { *idx = 27; *idx_2 = 63; } else if ( temp > -0.916331 && temp < -0.767327) { *idx = 28; *idx_2 = 64; } else if ( temp > -0.767327 && temp < -0.637070) { *idx = 29; *idx_2 = 65; } else if ( temp > -0.637070 && temp < -0.520567) { *idx = 30; *idx_2 = 66; } else if ( temp > -0.520567 && temp < -0.414214) { *idx = 31; *idx_2 = 67; } else if ( temp > -0.414214 && temp < -0.315299) { *idx = 32; *idx_2 = 68; } else if ( temp > -0.315299 && temp < -0.221695) { *idx = 33; *idx_2 = 69; } else if ( temp > -0.221695 && temp < -0.131652) { *idx = 34; *idx_2 = 70; } else if ( temp > -0.131652 && temp < -0.043661) { *idx = 35; *idx_2 = 71; } else if ( temp > -0.043661) { *idx = 36; *idx_2 = 0; } } } } //================================== //check if a car is fully plotted //return 1 if any point on the car is not plotted //Code is from Lu Liu int check_car(int x0, int y0, int x1, int y1) { int x2,y2; int x3,y3; int x4,y4; int x5,y5; int x6,y6; int x7,y7; int x8,y8; int x9,y9; int x10,y10; int x11,y11; int x12,y12; int x13,y13; int x14,y14; int x15,y15; int x16,y16; int x17,y17; int x18,y18; int x19,y19; int x20,y20; int x21,y21; int vec_1_dx = x1-x0; int vec_1_dy = y1-y0; int vec_2_dx; int vec_2_dy; //float length_vec_1 = sqrt(vec_1_dx*vec_1_dx + vec_1_dy*vec_1_dy); //float length_vec_2 = 2.5*length_vec_1; int length_vec_1 = car_width; int length_vec_2 = car_length; int coord_int[8]; int error; // calculate all the points x2 = x0 + (int)(0.3*vec_1_dx); y2 = y0 + (int)(0.3*vec_1_dy); x3 = x0 + (int)(0.7*vec_1_dx); y3 = y0 + (int)(0.7*vec_1_dy); error = video_rectangle(x0,y0,x1,y1,length_vec_2,&coord_int[0],0,0); if (error == 1) { return 1; } x4 = coord_int[4]; y4 = coord_int[5]; x5 = coord_int[6]; y5 = coord_int[7]; vec_2_dx = x4 - x0; vec_2_dy = y4 - y0; x6 = x0 + (int)(0.25*vec_2_dx); y6 = y0 + (int)(0.25*vec_2_dy); x7 = x1 + (int)(0.25*vec_2_dx); y7 = y1 + (int)(0.25*vec_2_dy); x8 = x0 + (int)(0.03125*vec_2_dx); y8 = y0 + (int)(0.03125*vec_2_dy); x9 = x1 + (int)(0.03125*vec_2_dx); y9 = y1 + (int)(0.03125*vec_2_dy); x10 = x0 + (int)(0.45*vec_2_dx); y10 = y0 + (int)(0.45*vec_2_dy); x11 = x1 + (int)(0.45*vec_2_dx); y11 = y1 + (int)(0.45*vec_2_dy); x12 = x10 + (int)(0.1*vec_1_dx); y12 = y10 + (int)(0.1*vec_1_dy); x13 = x11 - (int)(0.1*vec_1_dx); y13 = y11 - (int)(0.1*vec_1_dy); error = video_rectangle(x12,y12,x13,y13,0.425*length_vec_2,&coord_int[0],0,0); if (error == 1) { return 1; } x14 = coord_int[4]; y14 = coord_int[5]; x15 = coord_int[6]; y15 = coord_int[7]; x16 = x4 + (int)(0.4*vec_1_dx); y16 = y4 + (int)(0.4*vec_1_dy); x17 = x5 - (int)(0.4*vec_1_dx); y17 = y5 - (int)(0.4*vec_1_dy); x18 = x4 - (int)(0.03125*vec_2_dx); y18 = y4 - (int)(0.03125*vec_2_dy); x19 = x5 - (int)(0.03125*vec_2_dx); y19 = y5 - (int)(0.03125*vec_2_dy); x20 = x10 - (int)(0.1*vec_1_dx); y20 = y10 - (int)(0.1*vec_1_dy); x21 = x11 + (int)(0.1*vec_1_dx); y21 = y11 + (int)(0.1*vec_1_dy); // safe check: if (x0 > 0 && x0 < 160 && x1 > 0 && x1 < 160 && x2 > 0 && x2 < 160 && x3 > 0 && x3 < 160 && x4 > 0 && x4 < 160 && x5 > 0 && x5 < 160 && x6 > 0 && x6 < 160 && x7 > 0 && x7 < 160 && x8 > 0 && x8 < 160 && x9 > 0 && x9 < 160 && x10 > 0 && x10 < 160 && x11 > 0 && x11 < 160 && x12 > 0 && x12 < 160 && x13 > 0 && x13 < 160 && x14 > 0 && x14 < 160 && x15 > 0 && x15 < 160 && x16 > 0 && x16 < 160 && x17 > 0 && x17 < 160 && x18 > 0 && x18 < 160 && x19 > 0 && x19 < 160 && x20 > 0 && x20 < 160 && x21 > 0 && x21 < 160 && y0 > 0 && y0 < 200 && y1 > 0 && y1 < 200 && y2 > 0 && y2 < 200 && y3 > 0 && y3 < 200 && y4 > 0 && y4 < 200 && y5 > 0 && y5 < 200 && y6 > 0 && y6 < 200 && y7 > 0 && y7 < 200 && y8 > 0 && y8 < 200 && y9 > 0 && y9 < 200 && y10 > 0 && y10 < 200 && y11 > 0 && y11 < 200 && y12 > 0 && y12 < 200 && y13 > 0 && y13 < 200 && y14 > 0 && y14 < 200 && y15 > 0 && y15 < 200 && y16 > 0 && y16 < 200 && y17 > 0 && y17 < 200 && y18 > 0 && y18 < 200 && y19 > 0 && y19 < 200 && y20 > 0 && y20 < 200 && y21 > 0 && y21 < 200 ) { // now xor and check all the lines video_line(x2,y2,x3,y3,2); error = error | video_line_set(x2,y2,x3,y3); video_line(x0,y0,x4,y4,2); error = error | video_line_set(x0,y0,x4,y4); video_line(x1,y1,x5,y5,2); error = error | video_line_set(x1,y1,x5,y5); video_line(x16,y16,x17,y17,2); error = error | video_line_set(x16,y16,x17,y17); video_line(x12,y12,x13,y13,2); error = error | video_line_set(x12,y12,x13,y13); video_line(x12,y12,x14,y14,2); error = error | video_line_set(x12,y12,x14,y14); video_line(x14,y14,x15,y15,2); error = error | video_line_set(x14,y14,x15,y15); video_line(x13,y13,x15,y15,2); error = error | video_line_set(x13,y13,x15,y15); video_line(x2,y2,x8,y8,2); error = error | video_line_set(x2,y2,x8,y8); video_line(x3,y3,x9,y9,2); error = error | video_line_set(x3,y3,x9,y9); video_line(x6,y6,x7,y7,2); error = error | video_line_set(x6,y6,x7,y7); video_line(x6,y6,x12,y12,2); error = error | video_line_set(x6,y6,x12,y12); video_line(x7,y7,x13,y13,2); error = error | video_line_set(x7,y7,x13,y13); video_line(x14,y14,x4,y4,2); error = error | video_line_set(x14,y14,x4,y4); video_line(x15,y15,x5,y5,2); error = error | video_line_set(x15,y15,x5,y5); video_line(x16,y16,x18,y18,2); error = error | video_line_set(x16,y16,x18,y18); video_line(x17,y17,x19,y19,2); error = error | video_line_set(x17,y17,x19,y19); video_line(x6,y6,x20,y20,2); error = error | video_line_set(x6,y6,x20,y20); video_line(x7,y7,x21,y21,2); error = error | video_line_set(x7,y7,x21,y21); if (error == 0) { // erase those points video_line(x2,y2,x3,y3,0); video_line(x0,y0,x4,y4,0); video_line(x1,y1,x5,y5,0); video_line(x16,y16,x17,y17,0); video_line(x12,y12,x13,y13,0); video_line(x12,y12,x14,y14,0); video_line(x14,y14,x15,y15,0); video_line(x13,y13,x15,y15,0); video_line(x2,y2,x8,y8,0); video_line(x3,y3,x9,y9,0); video_line(x6,y6,x7,y7,0); video_line(x6,y6,x12,y12,0); video_line(x7,y7,x13,y13,0); video_line(x14,y14,x4,y4,0); video_line(x15,y15,x5,y5,0); video_line(x16,y16,x18,y18,0); video_line(x17,y17,x19,y19,0); video_line(x6,y6,x20,y20,0); video_line(x7,y7,x21,y21,0); } } return error; } // this function checks if the car is parked correctly between two parking lines // returns 0 if passed // note: the lines must be parallel to x/y axis int check_parking (unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int x0_line, int y0_line, int x1_line, int y1_line) { int x0_int = fix2int(x0)+128; int y0_int = fix2int(y0)+128; int x1_int = fix2int(x1)+128; int y1_int = fix2int(y1)+128; int error = 0; int coord[8]; // find all car four points video_rectangle(x0_int, y0_int, x1_int, y1_int, car_length, &coord[0], 0, 0); // check if all the four points on the car is within the two parking line if (x0_line < x1_line) { error = error | (x0_line > coord[0]); error = error | (x0_line > coord[2]); error = error | (x0_line > coord[4]); error = error | (x0_line > coord[6]); error = error | (x1_line < coord[0]); error = error | (x1_line < coord[2]); error = error | (x1_line < coord[4]); error = error | (x1_line < coord[6]); } else { error = error | (x1_line > coord[0]); error = error | (x1_line > coord[2]); error = error | (x1_line > coord[4]); error = error | (x1_line > coord[6]); error = error | (x0_line < coord[0]); error = error | (x0_line < coord[2]); error = error | (x0_line < coord[4]); error = error | (x0_line < coord[6]); } if (y0_line < y1_line) { error = error | (y0_line > coord[1]); error = error | (y0_line > coord[3]); error = error | (y0_line > coord[5]); error = error | (y0_line > coord[7]); error = error | (y1_line < coord[1]); error = error | (y1_line < coord[3]); error = error | (y1_line < coord[5]); error = error | (y1_line < coord[7]); } else { error = error | (y1_line > coord[1]); error = error | (y1_line > coord[3]); error = error | (y1_line > coord[5]); error = error | (y1_line > coord[7]); error = error | (y0_line < coord[1]); error = error | (y0_line < coord[3]); error = error | (y0_line < coord[5]); error = error | (y0_line < coord[7]); } return error; } // this function checks car parking result in parking lot 0 // returns 0 if passed int check_parking_lot_0 (void) { int error = 0; int temp = 0; // check if all the cars in the lot are intact error = error | check_car(105,30,105,10); error = error | check_car(95,148,100,126); error = error | check_car(158,168,158,193); // check if the car is parked at the correct place temp = check_parking (x0_fix, y0_fix, x1_fix, y1_fix, 100, 40, 160, 80); temp = temp & check_parking (x0_fix, y0_fix, x1_fix, y1_fix, 100, 80, 160, 120); temp = temp << 1; return error | temp; } // this function checks car parking result in parking lot 1 // returns 0 if passed int check_parking_lot_1 (void) { int error = 0; int temp = 0; // check if all the cars in the lot are intact error = error | check_car(30,53,10,53); error = error | check_car(28,189,8,189); error = error | check_car(130,5,150,5); error = error | check_car(128,73,150,76); // check if the car is parked at the correct place temp = check_parking (x0_fix, y0_fix, x1_fix, y1_fix, 5, 60, 35, 140); temp = temp << 1; return error | temp; } // this function checks if a line is crossed by another rectangle // returns 1 if it is // note: the line must be parallel to x/y axis int check_line (int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int line_x0, int line_y0, int line_x1, int line_y1) { int cross = 0; int less = 0; int greater = 0; // vertical line if (line_x0 == line_x1) { less = less | (x0 < line_x0); less = less | (x1 < line_x0); less = less | (x2 < line_x0); less = less | (x3 < line_x0); greater = greater | (x0 > line_x0); greater = greater | (x1 > line_x0); greater = greater | (x2 > line_x0); greater = greater | (x3 > line_x0); if (less & greater) { if (line_y0 < line_y1) { cross = cross | ((line_y0 < y0) & (line_y1 > y0)); cross = cross | ((line_y0 < y1) & (line_y1 > y1)); cross = cross | ((line_y0 < y2) & (line_y1 > y2)); cross = cross | ((line_y0 < y3) & (line_y1 > y3)); } else { cross = cross | ((line_y1 < y0) & (line_y0 > y0)); cross = cross | ((line_y1 < y1) & (line_y0 > y1)); cross = cross | ((line_y1 < y2) & (line_y0 > y2)); cross = cross | ((line_y1 < y3) & (line_y0 > y3)); } } // horizontal line } else { less = less | (y0 < line_y0); less = less | (y1 < line_y0); less = less | (y2 < line_y0); less = less | (y3 < line_y0); greater = greater | (y0 > line_y0); greater = greater | (y1 > line_y0); greater = greater | (y2 > line_y0); greater = greater | (y3 > line_y0); if (less & greater) { if (line_x0 < line_x1) { cross = cross | ((line_x0 < x0) & (line_x1 > x0)); cross = cross | ((line_x0 < x1) & (line_x1 > x1)); cross = cross | ((line_x0 < x2) & (line_x1 > x2)); cross = cross | ((line_x0 < x3) & (line_x1 > x3)); } else { cross = cross | ((line_x1 < x0) & (line_x0 > x0)); cross = cross | ((line_x1 < x1) & (line_x0 > x1)); cross = cross | ((line_x1 < x2) & (line_x0 > x2)); cross = cross | ((line_x1 < x3) & (line_x0 > x3)); } } } return cross; } // this function checks if a line in parking lot 0 is crossed by the car and save the status // if it is crossed, set the idx // if it is not crossed but previously crossed, redraw the line // if it is not crossed and not previously crossed, do nothing void redraw_a_line_parking_lot_0 (int *cross, int *prev_cross) { int x0_int = fix2int(x0_fix)+128; int y0_int = fix2int(y0_fix)+128; int x1_int = fix2int(x1_fix)+128; int y1_int = fix2int(y1_fix)+128; int coord[8]; // store the previous status prev_cross[0] = cross[0]; prev_cross[1] = cross[1]; prev_cross[2] = cross[2]; // find all car four points video_rectangle(x0_int, y0_int, x1_int, y1_int, car_length, &coord[0], 0, 0); // check if each line in this parking lot is crossed by the car cross[0] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 100, 40, 160, 40); cross[1] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 100, 80, 160, 80); cross[2] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 100, 120, 160, 120); // redraw the line if the line is previously crossed but not currently crossed if (cross[0] == 0 && prev_cross[0] == 1) video_line(100, 40, 160, 40, 1); if (cross[1] == 0 && prev_cross[1] == 1) video_line(100, 80, 160, 80, 1); if (cross[2] == 0 && prev_cross[2] == 1) video_line(100, 120, 160, 120, 1); } // this function checks if a line in parking lot 1 is crossed by the car and save the status // if it is crossed, set the idx // if it is not crossed but previously crossed, redraw the line // if it is not crossed and not previously crossed, do nothing void redraw_a_line_parking_lot_1 (int *cross, int *prev_cross) { int x0_int = fix2int(x0_fix)+128; int y0_int = fix2int(y0_fix)+128; int x1_int = fix2int(x1_fix)+128; int y1_int = fix2int(y1_fix)+128; int coord[8]; // store the previous status prev_cross[0] = cross[0]; prev_cross[1] = cross[1]; prev_cross[2] = cross[2]; prev_cross[3] = cross[3]; prev_cross[4] = cross[4]; prev_cross[5] = cross[5]; prev_cross[6] = cross[6]; // find all car four points video_rectangle(x0_int, y0_int, x1_int, y1_int, car_length, &coord[0], 0, 0); // check if each line in this parking lot is crossed by the car cross[0] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 79, 0, 79, 20); cross[1] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 79, 40, 79, 60); cross[2] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 79, 80, 79, 100); cross[3] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 79, 120, 79, 140); cross[4] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 79, 160, 79, 180); cross[5] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 5, 60, 30, 60); cross[6] = check_line(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5], coord[6], coord[7], 5, 60, 5, 140); // redraw the line if the line is previously crossed but not currently crossed if (cross[0] == 0 && prev_cross[0] == 1) video_line(79, 0, 79, 20, 1); if (cross[1] == 0 && prev_cross[1] == 1) video_line(79, 40, 79, 60, 1); if (cross[2] == 0 && prev_cross[2] == 1) video_line(79, 80, 79, 100, 1); if (cross[3] == 0 && prev_cross[3] == 1) video_line(79, 120, 79, 140, 1); if (cross[4] == 0 && prev_cross[4] == 1) video_line(79, 160, 79, 180, 1); if (cross[5] == 0 && prev_cross[5] == 1) video_line(5, 60, 30, 60, 1); if (cross[6] == 0 && prev_cross[6] == 1) video_line(5, 60, 5, 140, 1); } // this function erase the whole screen void erase_screen (void) { int line = 0; for (line = 0; line <= 160; line ++) video_line(line,0,line,199,0); } // this function adjust the car size to its origin // NOTE: for this project, this function shall only be called when the car is parallel to y-axis void adjust_car_size(unsigned int *x0, unsigned int *y0, unsigned int *x1, unsigned int *y1) { int x0_int = (fix2int(*x0)+128); int x1_int = (fix2int(*x1)+128); int y0_int = (fix2int(*y0)+128); int y1_int = (fix2int(*y1)+128); int dx = x1_int - x0_int; unsigned int new_x; // erase the current car video_car(x0_int, y0_int, x1_int, y1_int, 1, 0); if (dx > 0) { new_x = x0_int + 20; if (new_x >= 160) { x0_int = x1_int - 20; *x0 = int2fix(x0_int-128); } else { x1_int = new_x; *x1 = int2fix(x1_int-128); } } else { new_x = x1_int + 20; if (new_x >= 160) { x0_int = new_x; *x0 = int2fix(x0_int-128); } else { x1_int = x0_int - 20; *x1 = int2fix(x1_int-128); } } // redraw the new car video_car(x0_int, y0_int, x1_int, y1_int, 1, 2); } //=== animation stuff ================================================== char str0[] = "0"; char str1[] = "1"; char str_print[6]; int temp0; int temp1; char color; int prev_lines[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int lines[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int stage; char check_str0[] = "You Hit A Car!"; char check_str1[] = "You Parked Out of Bound!"; int coord[8]; int adjust_size = 1; /////////////// //================================== // set up the ports and timers int main() { int error = 0; //********************************************************* // INITIALIZATION - begin //********************************************************* // interrupts enabled TCCR1B = _BV(WGM12) | _BV(CS10); OCR1A = LINE_TIME; // time for one NTSC line OCR1B = SLEEP_TIME; // time to go to sleep TIMSK1 = _BV(OCIE1B) | _BV(OCIE1A); //init ports DDRD = 0x03; //video out // USART in MSPIM mode, transmitter enabled, frequency fosc/4 UCSR0B = _BV(TXEN0); UCSR0C = _BV(UMSEL01) | _BV(UMSEL00); UBRR0 = 1 ; // ADC //init the A to D converter //channel zero/ left adj /INTERNAL Aref=Vcc ADMUX = (1<<ADLAR) | (1<<REFS0) ; //enable ADC and set prescaler to 1/128*16MHz=125,000 //and clear interupt enable //and start a conversion ADCSRA = (1<<ADEN) | (1<<ADSC) + 7 ; //To get the initial setting while (ADCSRA & (1<<ADSC) ); //get the sample Ain1 = ADCH; //start another conversion ADMUX = (1<<ADLAR) | (1<<REFS0) + 2; ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain2 = ADCH; last_abs_wheel_angle = abs_wheel_angle(Ain1,Ain2, last_abs_wheel_angle); last_wheel_angle =last_abs_wheel_angle; // set the reverse PORTB = 0x94; PORTD = 0x20; //init the UART -- uart_init() is in uart.c uart_init(); stdout = stdin = stderr = &uart_str; fprintf(stdout, "hello\n"); //initialize synch constants LineCount = 1; syncON = 0b00000000; syncOFF = 0b00000001; //side lines #define width screen_width-1 #define height screen_height-1 // Set up single video line timing sei(); set_sleep_mode(SLEEP_MODE_IDLE); sleep_enable(); //********************************************************* // INITIALIZATION - end //********************************************************* //********************************************************* // VIDEO GAME INITIALIZATION- begin //********************************************************* RESTART: // print 'speed' at the end of the screen str_print[0] = 'S'; str_print[1] = 'P'; str_print[2] = 'E'; str_print[3] = 'E'; str_print[4] = 'D'; str_print[5] = ':'; video_putsmalls(4, 190, str_print); // initialize car parameter car_gas = 0; car_angle = 0; reverse = 0; // select stage stage = ~PIND & 0x20; // draw parking lot and car init position if (stage) { plot_parking_lot_1(); x0_fix = int2fix(60-128); y0_fix = int2fix(60-128); x1_fix = int2fix(40-128); y1_fix = int2fix(60-128); angle_state = 0; angle_state_2 = 36; } else { plot_parking_lot_0(); x0_fix = int2fix(10-128); y0_fix = int2fix(5-128); x1_fix = int2fix(30-128); y1_fix = int2fix(5-128); angle_state = 36; angle_state_2 = 0; } //********************************************************* // VIDEO GAME INITIALIZATION- end //********************************************************* // The following loop executes the if-block // when the screen refresh is done // then does all of the frame-end processing while(1) { if (LineCount == ScreenBot) { //********************************************************* // SENSOR READINGS- begin //********************************************************* // acc0 ADMUX = (1<<ADLAR) | (1<<REFS0) ; //start another conversion ADCSRA |= (1<<ADSC) ; //get the sample while(ADCSRA & (1<<ADSC) ) Ain1 = ADCH; ADCSRA |= (1<<ADSC) ; while(ADCSRA & (1<<ADSC) ) Ain1 = ADCH; ADCSRA |= (1<<ADSC) ; while(ADCSRA & (1<<ADSC) ) Ain1 = ADCH; // brake pedal ADMUX = (1<<ADLAR) | (1<<REFS0)+7 ; //start another conversion ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain3 = ADCH; ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain3 = ADCH; // gear pedal ADMUX = (1<<ADLAR) | (1<<REFS0)+5 ; //start another conversion ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain4 = ADCH; ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain4 = ADCH; // speed car_gas = potentiometer(Ain4); if (Ain3 > 150) { car_gas = 0; } // forward/backward if (~PINB & 0x04) { reverse = 0; } else { reverse = 1; } // acc1 //start another conversion ADMUX = (1<<ADLAR) | (1<<REFS0) + 2; ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain2 = ADCH; ADCSRA |= (1<<ADSC) ; while (ADCSRA & (1<<ADSC) ); //get the sample Ain2 = ADCH; // steering wheel angle wheel_angle = relative_wheel_angle(last_abs_wheel_angle,Ain1,Ain2); last_abs_wheel_angle=abs_wheel_angle(Ain1,Ain2,last_abs_wheel_angle); last_wheel_angle = last_wheel_angle + wheel_angle; if (last_wheel_angle<-450) last_wheel_angle = -450; if (last_wheel_angle>450) last_wheel_angle = 450; car_angle = car_angle_compute(last_wheel_angle); //********************************************************* // SENSOR READINGS- end //********************************************************* //********************************************************* // CAR POSITION UPDATE- begin //********************************************************* error = start_car(&x0_fix, &y0_fix, &x1_fix, &y1_fix, car_gas); //********************************************************* // CAR POSITION UPDATE- end //********************************************************* //********************************************************* // CAR VARIABLE UPDATE- begin //********************************************************* limit = 30; if (car_gas != 0) { switch (car_gas) begin case 1 : limit = 45; break; case 2 : limit = 23; break; case 3 : limit = 15; break; end } //********************************************************* // CAR VARIABLE UPDATE- end //********************************************************* //********************************************************* // CAR STATUS DISPLAY- begin //********************************************************* // DISPLAY: // speed itoa(car_gas, str_print, 10); video_putsmalls(28, 190, str_print); // forward/backward str_print[0] = '\0'; if (reverse == 0) { str_print[0] = 'D'; video_putsmalls(36, 190, str_print); } else { str_print[0] = 'R'; video_putsmalls(36, 190, str_print); } str_print[0] = 'blank'; video_putsmalls(40, 190, str_print); // steering wheel angle if (car_angle > 0) { str_print[0] = '\0'; str_print[0] = 'P'; video_putsmalls(44, 190, str_print); temp0 = car_angle; } else { str_print[0] = '\0'; str_print[0] = 'N'; video_putsmalls(44, 190, str_print); temp0 = (-1)*car_angle; } str_print[2] = '\0'; itoa(temp0, str_print, 10); if (temp0 < 10) { str_print[1] = str_print[0]; str_print[0] = 'blank'; } video_putsmalls(48, 190, str_print); // angle index str_print[0] = '\0'; str_print[0] = 'A'; video_putsmalls(60, 190, str_print); itoa(angle_state, str_print, 10); if (angle_state < 10) { str_print[1] = str_print[0]; str_print[0] = 'blank'; } video_putsmalls(64, 190, str_print); str_print[0] = 'blank'; video_putsmalls(72, 190, str_print); itoa(angle_state_2, str_print, 10); if (angle_state_2 < 10) { str_print[1] = str_print[0]; str_print[0] = 'blank'; } video_putsmalls(76, 190, str_print); // error str_print[0] = 'blank'; video_putsmalls(84, 190, str_print); str_print[0] = 'E'; video_putsmalls(88, 190, str_print); itoa(error, str_print, 10); video_putsmalls(92, 190, str_print); //********************************************************* // CAR STATUS DISPLAY- end //********************************************************* //********************************************************* // ADJUSTMENT- begin //********************************************************* if (error == 0 && car_gas != 0) adjust_angle_state(x0_fix, y0_fix, x1_fix, y1_fix, &angle_state, &angle_state_2); if (stage) redraw_a_line_parking_lot_1(&lines[0], &prev_lines[0]); else redraw_a_line_parking_lot_0(&lines[0], &prev_lines[0]); if ((angle_state == 0 || angle_state == 36) && adjust_size == 1) { adjust_car_size(&x0_fix, &y0_fix, &x1_fix, &y1_fix); adjust_size = 0; } else if (angle_state != 0 && angle_state != 36) { adjust_size = 1; } //********************************************************* // ADJUSTMENT- end //********************************************************* // check when done if ((~PINB & 0x10) == 0x10) { break; } ///////////////////////////////////////// // add this line to execute code exactly once per frame // comment it out for max execution speed while (LineCount != ScreenTop) ; } // if } //while(1) car_gas = 0; //********************************************************* // CHECK PARKING RESULT- begin //********************************************************* str_print[0] = '\0'; if (stage) { error = check_parking_lot_1(); if (error) { // FAIL str_print[0] = 'F'; str_print[1] = 'A'; str_print[2] = 'I'; str_print[3] = 'L'; str_print[4] = '!'; str_print[5] = '\0'; } else { // PASS str_print[0] = 'P'; str_print[1] = 'A'; str_print[2] = 'S'; str_print[3] = 'S'; str_print[4] = '!'; str_print[5] = '\0'; } } else { error = check_parking_lot_0(); if (error) { // FAIL str_print[0] = 'F'; str_print[1] = 'A'; str_print[2] = 'I'; str_print[3] = 'L'; str_print[4] = '!'; str_print[5] = '\0'; } else { // PASS str_print[0] = 'P'; str_print[1] = 'A'; str_print[2] = 'S'; str_print[3] = 'S'; str_print[4] = '!'; str_print[5] = '\0'; } } // display result video_puts(60, 100, str_print); if (error == 1) { video_puts(10, 130, check_str0); } else if (error == 2) { video_puts(10, 130, check_str1); } else if (error == 3) { video_puts(10, 130, check_str0); video_puts(10, 160, check_str1); } //********************************************************* // CHECK PARKING RESULT- begin //********************************************************* while ((~PINB & 0x80) != 0x80); // wait until restart erase_screen(); goto RESTART; // check the result } //main