Advertisement
Nuppiz

Derp.c

Jan 23rd, 2022 (edited)
530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.15 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dos.h>
  4. #include <math.h>
  5. #include <stdint.h>
  6.  
  7. #define VIDEO_INT           0x10      /* the BIOS video interrupt. */
  8. #define SET_MODE            0x00      /* BIOS func to set the video mode. */
  9. #define VGA_256_COLOR_MODE  0x13      /* use to set 256-color mode. */
  10. #define TEXT_MODE           0x03      /* use to set 80x25 text mode. */
  11.  
  12. #define SCREEN_WIDTH        320       /* width in pixels of mode 0x13 */
  13. #define SCREEN_HEIGHT       200       /* height in pixels of mode 0x13 */
  14. #define NUM_COLORS          256       /* number of colors in mode 0x13 */
  15.  
  16. #define SET_PIXEL(x,y,color)      screen_buf[(y)*SCREEN_WIDTH + (x)] = color
  17.  
  18. #define KB_ARRAY_LENGTH     256
  19. #define KB_QUEUE_LENGTH     256
  20.  
  21. #define KEY_HIT_FLAG        1
  22. #define KEY_PRESSED_FLAG    2
  23. #define KEY_RELEASED_FLAG   0x80 // 128, MSB
  24. #define KEY_SPECIAL_CODE    0xE0 // 224
  25. #define KEY_IS_PRESSED(k)   (g_Keyboard[k] & KEY_PRESSED_FLAG)
  26. #define KEY_WAS_HIT(k)      (g_Keyboard[k] & KEY_HIT_FLAG)
  27. #define KEY_WAS_RELEASED(k) (g_Keyboard[k] & KEY_RELEASED_FLAG)
  28. #define KEY_WAS_TOGGLED(k)  (g_Keyboard[k] & (KEY_HIT_FLAG|KEY_RELEASED_FLAG))
  29. #define KEY_LEFT            75
  30. #define KEY_RIGHT           77
  31. #define KEY_UP              72
  32. #define KEY_DOWN            80
  33. #define KEY_F10             68
  34.  
  35. #define X_AXIS              1
  36. #define Y_AXIS              2
  37.  
  38. #define SQUARE_SIZE         20
  39. #define SCREEN_SIZE         64000
  40. #define degToRad(degree)    (degree * (M_PI / 180.0))
  41.  
  42. #define player              object_array[0]
  43.  
  44. enum Objects
  45. {
  46.     Circle1,
  47.     Circle2,
  48.     Circle3,
  49.     Num_Objects
  50. };
  51.  
  52. typedef struct
  53. {
  54.     float x, y;
  55. } Vec2;
  56.  
  57. typedef struct
  58. {
  59.     int x, y;
  60. } Vec2_int;
  61.  
  62. typedef struct
  63. {
  64.     Vec2 position;
  65.     Vec2 d_vector; // direction
  66.     Vec2 v_vector; // direction of velocity
  67.     float magnitude; // magnitude of velocity
  68.     int radius; // circle radius
  69.     uint8_t color;
  70. } Object;
  71.  
  72. // array which holds all objects (circles in this case)
  73. Object object_array[Num_Objects] = {
  74. //    pos_x  pos_y     d_vector    v_vector   magnitude     radius  colour
  75.     {{120.0, 40.0,},  {0.0, 0.0}, {0.0, 0.0}, 0.0,          8,      14},
  76.     {{40.0,  110.0,}, {0.0, 0.0}, {0.0, 0.0}, 0.0,          8,       3},
  77.     {{120.0, 110.0,}, {0.0, 0.0}, {0.0, 0.0}, 0.0,          8,      12}
  78. };
  79.  
  80. // array which determines the colour of each square on the grid
  81. uint8_t grid_array [] = {7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7,
  82.                          7, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0,  7,
  83.                          7,  0, 7,  7, 7, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 7,
  84.                          7, 15, 7, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0,  7,
  85.                          7,  0, 7, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 7,
  86.                          7, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0,  7,
  87.                          7,  0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 7,
  88.                          7, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0,  7,
  89.                          7,  0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 7,
  90.                          7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7, 7,  7
  91. };
  92.  
  93. Vec2_int pl_grid; // vector to hold the player's grid location
  94.  
  95. struct Input
  96. {
  97.     uint8_t kb_array[KB_ARRAY_LENGTH];
  98.     uint8_t kb_queue[KB_QUEUE_LENGTH];
  99.     uint8_t kb_head;
  100.     uint8_t kb_tail;
  101. };
  102.  
  103. typedef struct Input Input_t;
  104.  
  105. uint8_t *VGA=(uint8_t *)0xA0000000L;        /* this points to video memory. */
  106. uint8_t far screen_buf [64000];
  107.  
  108. Input_t Input = {0};
  109. Input_t* g_Input = &Input;
  110. uint8_t* g_Keyboard = Input.kb_array;
  111.  
  112. static void interrupt (far *old_keyhandler)(void);
  113.  
  114. int running = 1;
  115. float drag = 1.05;
  116. float thrust = 0.3;
  117. int direction = 0; // current direction in degrees
  118. float radians = 0.0; // current direction in radians, as that's what the math functions use
  119.  
  120. void set_mode(uint8_t mode)
  121. {
  122.     union REGS regs;
  123.  
  124.     regs.h.ah = SET_MODE;
  125.     regs.h.al = mode;
  126.     int86(VIDEO_INT, &regs, &regs);
  127. }
  128.  
  129. // keyboard handling stuff until line 229
  130. void interrupt far keyhandler()
  131. {
  132.     uint8_t key_scan = 0;
  133.     static uint8_t key_scan_last = 0;
  134.     static uint8_t key_special = 0;
  135.     static uint8_t key_special_last = 0;
  136.     // obtain scancode
  137.     asm {
  138.         cli // clear interrupt flag; prevent other external interrupts
  139.         in  al, 0x60
  140.         mov key_scan, al
  141.         in  al, 0x61 // get keyboard status
  142.         mov bl, al
  143.         or  al, 0x80 // MSB set
  144.         out 0x61, al // write (ACK)
  145.         mov al, bl   // MSB clear
  146.         out 0x61, al // write
  147.     }
  148.     // remember the last special key code
  149.     if (key_scan_last == KEY_SPECIAL_CODE)
  150.         key_special = key_scan;
  151.     else if (key_scan != KEY_SPECIAL_CODE)
  152.         key_special = 0;
  153.     // place scancode on queue unless it's the same as the previous one
  154.     if (key_scan != key_scan_last && (key_special != key_special_last || key_special_last == 0))
  155.     {
  156.         g_Input->kb_queue[g_Input->kb_tail] = key_scan;
  157.         if (g_Input->kb_tail+1 != g_Input->kb_head)
  158.             g_Input->kb_tail++;
  159.     }
  160.     key_scan_last = key_scan;
  161.     key_special_last = key_special;
  162.     // PIC 8259 reset
  163.     asm {
  164.         mov al, 0x20
  165.         out 0x20, al
  166.         sti // set interrupt flag; allow external interrupts again
  167.     }
  168. }
  169.  
  170. void init_keyboard()
  171. {
  172.     uint8_t far *bios_key_state;
  173.     asm cli
  174.     // save address of current keyhandler interrupt function
  175.     old_keyhandler = _dos_getvect(9);
  176.     // caps lock & num lock off
  177.     bios_key_state = MK_FP(0x040, 0x017);
  178.     *bios_key_state &= (~(32|64));
  179.     old_keyhandler();
  180.     // replace old keyhandler with new keyhandler function
  181.     _dos_setvect(9, keyhandler);
  182.     asm sti
  183. }
  184.  
  185. void deinit_keyboard()
  186. {
  187.     // restore old keyhandler
  188.     asm cli
  189.     _dos_setvect(9, old_keyhandler);
  190.     asm sti
  191.  
  192.     g_Input = NULL;
  193. }
  194.  
  195. void get_keyboard()
  196. {
  197.     int i;
  198.     uint8_t key_scan;
  199.     uint8_t extended = 0;
  200.     uint8_t released = 0;
  201.  
  202.     while (g_Input->kb_head != g_Input->kb_tail)
  203.     {
  204.         key_scan = g_Input->kb_queue[g_Input->kb_head++];
  205.         /* handle special keys, but only if a second scancode follows*/
  206.         if (key_scan == KEY_SPECIAL_CODE)
  207.                 extended = 128;
  208.         /* remember the release flag before clearing it*/
  209.         released = key_scan & KEY_RELEASED_FLAG;
  210.         key_scan &= ~KEY_RELEASED_FLAG;
  211.         if (released)
  212.         {
  213.             g_Input->kb_array[key_scan+extended] &= KEY_HIT_FLAG;
  214.             g_Input->kb_array[key_scan+extended] |= KEY_RELEASED_FLAG;
  215.         }
  216.         else
  217.             g_Input->kb_array[key_scan+extended] |= (KEY_HIT_FLAG|KEY_PRESSED_FLAG);
  218.  
  219.         extended = 0;
  220.     }
  221. }
  222.  
  223. void clear_keys()
  224. {
  225.     int i;
  226.     for (i = 0; i < KB_ARRAY_LENGTH; i++)
  227.         g_Input->kb_array[i] &= KEY_PRESSED_FLAG;
  228. }
  229.  
  230. void control_ingame()
  231. {
  232.     player.d_vector.x = cos(radians); // calculate directional x-vector
  233.     player.d_vector.y = sin(radians); // calculate directional y-vector
  234.    
  235.     if (KEY_IS_PRESSED(KEY_UP) && player.magnitude <= 10.0)
  236.     {
  237.         player.v_vector.x += player.d_vector.x * thrust;
  238.         player.v_vector.y += player.d_vector.y * thrust;
  239.         // calculate the player's current movement
  240.         player.magnitude = sqrt((player.v_vector.x * player.v_vector.x) + (player.v_vector.y * player.v_vector.y));
  241.     }
  242.     if (KEY_IS_PRESSED(KEY_DOWN))
  243.     {
  244.         // reduce player velocity
  245.         player.v_vector.x *= 0.9;
  246.         player.v_vector.y *= 0.9;
  247.             // if player has slowed down to a crawl, stop them entirely
  248.             if (fabs(player.v_vector.x) < 0.2)
  249.             {
  250.                 player.v_vector.x = 0.0;
  251.             }
  252.             if  (fabs(player.v_vector.y) < 0.2)
  253.             {
  254.                 player.v_vector.y = 0.0;
  255.             }
  256.     }
  257.     if (KEY_IS_PRESSED(KEY_LEFT))
  258.     {
  259.         direction -= 5;
  260.         if (direction < 0)
  261.             direction = 360;
  262.     }
  263.     if (KEY_IS_PRESSED(KEY_RIGHT))
  264.     {
  265.         direction += 5;
  266.         if (direction > 360)
  267.             direction = 0;
  268.     }
  269. }
  270.  
  271. void process_input()
  272. {
  273.     get_keyboard();
  274.  
  275.     control_ingame();
  276.    
  277.     // F10 always exits, wherever you are
  278.     if (KEY_WAS_HIT(KEY_F10))
  279.         running = 0;
  280.  
  281.     clear_keys();
  282. }
  283.  
  284. void draw_circle(Vec2* position, int radius, uint8_t color)
  285. {
  286.     int offset_x;
  287.     int offset_y;
  288.    
  289.     int center_x = position->x;
  290.     int center_y = position->y;
  291.  
  292.     offset_y = 0;
  293.     do
  294.     {
  295.         offset_x = sqrt((float)radius*radius - (float)offset_y*offset_y);
  296.         SET_PIXEL(center_x + offset_x, center_y + offset_y, color); // lower right octant
  297.         SET_PIXEL(center_x - offset_x, center_y + offset_y, color); // lower left octant
  298.         SET_PIXEL(center_x + offset_x, center_y - offset_y, color); // upper right octant
  299.         SET_PIXEL(center_x - offset_x, center_y - offset_y, color); // upper left octant
  300.         SET_PIXEL(center_x + offset_y, center_y + offset_x, color); // bottom right octant
  301.         SET_PIXEL(center_x - offset_y, center_y + offset_x, color); // bottom left octant
  302.         SET_PIXEL(center_x + offset_y, center_y - offset_x, color); // top right octant
  303.         SET_PIXEL(center_x - offset_y, center_y - offset_x, color); // top left octant
  304.  
  305.         offset_y++;
  306.     }
  307.     while (offset_y < offset_x);
  308. }
  309.  
  310. void draw_square(int x, int y, uint8_t colour)
  311. {
  312.     int index_y = 0;
  313.  
  314.     for (index_y=0;index_y<SQUARE_SIZE;index_y++)
  315.     {
  316.         //memsetting the entire row is faster than drawing it pixel by pixel
  317.         memset(screen_buf + (y * SCREEN_WIDTH + x), colour, SQUARE_SIZE);
  318.         y++;
  319.     }
  320. }
  321.  
  322. void player_grid_loc() // player circle's location on the grid
  323. {  
  324.     // calculated by dividing the player's x/y location by square size
  325.     pl_grid.x = player.position.x / SQUARE_SIZE;
  326.     pl_grid.y = player.position.y / SQUARE_SIZE;
  327. }
  328.  
  329. void draw_stuff()
  330. {
  331.     int i = 0; // object array "index"
  332.     int a = 0; // square drawing "index"
  333.     int x;
  334.     int y;
  335.    
  336.     int offset_y;
  337.     int offset_x;
  338.    
  339.     // draw 160 20x20 squares (maximum that can fit on the 320x200 screen)
  340.     while (a < 160)
  341.     {
  342.         for (y = 0; y < SCREEN_HEIGHT; y += SQUARE_SIZE)
  343.         {
  344.             for(x = 0; x < SCREEN_WIDTH; x += SQUARE_SIZE)
  345.             {
  346.                 draw_square(x, y, grid_array[a]);
  347.                 a++;
  348.             }
  349.         }
  350.     }
  351.    
  352.     player_grid_loc(); // check where the player circle is
  353.     draw_square(pl_grid.x * SQUARE_SIZE, pl_grid.y * SQUARE_SIZE, 64); // change that square to a lovely peach colour
  354.    
  355.     while (i < Num_Objects)
  356.     {
  357.         // draw all circles in their current locations
  358.         draw_circle(&object_array[i].position, object_array[i].radius, object_array[i].color);
  359.         i++;
  360.     }
  361.    
  362.     // directional dot's offsets from the center of the circle
  363.     offset_y = (sin(radians)) * player.radius;
  364.     offset_x = (cos(radians)) * player.radius;
  365.     // center of the circle has to be cast into int, otherwise the draw function doesn't work
  366.     SET_PIXEL((int)player.position.x + offset_x, (int)player.position.y + offset_y, 40);
  367.    
  368.     // copy off-screen buffer to VGA memory
  369.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  370.    
  371.     // clear off-screen buffer so the screen updates properly
  372.     _fmemset(screen_buf, 0, SCREEN_SIZE);
  373. }
  374.  
  375. int tile_detect(Vec2 pos)
  376. {
  377.     int object_tile; // tile which the object is on (or attempting to be), i.e. array index number from grid_array
  378.     uint8_t tile_colour;
  379.    
  380.     // calculate current grid position
  381.     pos.x /= SQUARE_SIZE;
  382.     pos.y /= SQUARE_SIZE;
  383.    
  384.     // check which grid_array index it corresponds to
  385.     object_tile = (int)pos.y * 16 + (int)pos.x;
  386.    
  387.     tile_colour = grid_array[object_tile]; // check which colour is at that index
  388.    
  389.     return tile_colour; // return said colour
  390. }
  391.  
  392. void edge_detect()
  393. {
  394.     int i = 0;
  395.     while (i < Num_Objects)
  396.     {
  397.         if (object_array[i].position.x - object_array[i].radius <= 0) // left edge
  398.         {
  399.             object_array[i].position.x = 0 + object_array[i].radius;
  400.             object_array[i].v_vector.x = 0.0;
  401.         }
  402.        
  403.         if (object_array[i].position.y - object_array[i].radius <= 0) // top edge
  404.         {
  405.             object_array[i].position.y = 0 + object_array[i].radius;
  406.             object_array[i].v_vector.y = 0.0;
  407.         }
  408.        
  409.         if (object_array[i].position.x + object_array[i].radius >= (SCREEN_WIDTH - 1)) // right edge
  410.         {
  411.             object_array[i].position.x = (SCREEN_WIDTH - 1) - object_array[i].radius;
  412.             object_array[i].v_vector.x = 0.0;
  413.         }
  414.        
  415.         if (object_array[i].position.y + object_array[i].radius >= (SCREEN_HEIGHT - 1)) // bottom edge
  416.         {
  417.             object_array[i].position.y = (SCREEN_HEIGHT - 1) - object_array[i].radius;
  418.             object_array[i].v_vector.y = 0.0;
  419.         }
  420.         i++;
  421.     }
  422. }
  423.  
  424. void move_circle(Object* obj, Vec2 movement)
  425. {
  426.     // collision box around the object
  427.     Vec2 test_point_a;
  428.     Vec2 test_point_b;
  429.    
  430.     if (movement.x > 0) // if moving to the right
  431.     {
  432.         obj->position.x += movement.x; // temporarily move the object
  433.         // test_point_a = top right corner
  434.         test_point_a.x = obj->position.x + obj->radius;
  435.         test_point_a.y = obj->position.y - obj->radius;
  436.         // test_point_b = bottom right corner
  437.         test_point_b.x = obj->position.x + obj->radius;
  438.         test_point_b.y = obj->position.y + obj->radius;
  439.        
  440.         // if the movement would result in the object moving inside of a wall...
  441.         if (tile_detect(test_point_a) == 7 || tile_detect(test_point_b) == 7)
  442.         {
  443.             // ...cancel movement
  444.             obj->position.x -= movement.x;
  445.         }
  446.     }
  447.     else if (movement.x < 0) // if moving to the left
  448.     {
  449.         obj->position.x += movement.x;
  450.         // test_point_a = top left corner
  451.         test_point_a.x = obj->position.x - obj->radius;
  452.         test_point_a.y = obj->position.y - obj->radius;
  453.         // test_point_b = bottom left corner
  454.         test_point_b.x = obj->position.x - obj->radius;
  455.         test_point_b.y = obj->position.y + obj->radius;
  456.        
  457.         if (tile_detect(test_point_a) == 7 || tile_detect(test_point_b) == 7)
  458.         {
  459.             obj->position.x -= movement.x;
  460.         }
  461.     }
  462.  
  463.     if (movement.y < 0) // if moving towards the top
  464.     {
  465.         obj->position.y += movement.y;
  466.         // test_point_a = top right corner
  467.         test_point_a.x = obj->position.x + obj->radius;
  468.         test_point_a.y = obj->position.y - obj->radius;
  469.         // test_point_ba = top left corner
  470.         test_point_b.x = obj->position.x - obj->radius;
  471.         test_point_b.y = obj->position.y - obj->radius;
  472.        
  473.         if (tile_detect(test_point_a) == 7 || tile_detect(test_point_b) == 7)
  474.         {
  475.             obj->position.y -= movement.y;
  476.         }
  477.     }
  478.     else if (movement.y > 0) // if moving towards the bottom
  479.     {
  480.         obj->position.y += movement.y;
  481.         // test_point_a = bottom right corner
  482.         test_point_a.x = obj->position.x + obj->radius;
  483.         test_point_a.y = obj->position.y + obj->radius;
  484.         // test_point_b = bottom left corner
  485.         test_point_b.x = obj->position.x - obj->radius;
  486.         test_point_b.y = obj->position.y + obj->radius;
  487.        
  488.         if (tile_detect(test_point_a) == 7 || tile_detect(test_point_b) == 7)
  489.         {
  490.             obj->position.y -= movement.y;
  491.         }
  492.     }
  493. }
  494.  
  495. void calculate_movement()
  496. {
  497.     int i = 0;
  498.    
  499.     // iterate through the object array
  500.     while (i < Num_Objects)
  501.     {
  502.         move_circle(&object_array[i], object_array[i].v_vector); // check each circle for wall collisions
  503.         // reduce object velocity with aerial drag
  504.         object_array[i].v_vector.y /= drag;
  505.         object_array[i].v_vector.x /= drag;
  506.         i++;
  507.     }
  508. }
  509.  
  510. void chase(Object* object_a, Object* object_b)
  511. {
  512.     float ai_radians;
  513.    
  514.     float distance_x = object_a->position.x - object_b->position.x; // x-distance between the two objects
  515.     float distance_y = object_a->position.y - object_b->position.y; // y-distance between the two objects
  516.     // simplified total distance calculation (without sqrt)
  517.     float distance_squared = distance_x * distance_x + distance_y * distance_y;
  518.    
  519.     // calculate angle between the two objects - atan2 allows for both positive and negative angles
  520.     ai_radians = atan2(distance_y, distance_x);
  521.    
  522.     // calculated the directional vector of the "chasing" object
  523.     object_b->d_vector.x = cos(ai_radians);
  524.     object_b->d_vector.y = sin(ai_radians);
  525.    
  526.     // if close enough, initiate "chase"
  527.     if(distance_squared < 6000.0)
  528.     {
  529.         object_b->v_vector.x += object_b->d_vector.x / 2;
  530.         object_b->v_vector.y += object_b->d_vector.y / 2;
  531.     }
  532.    
  533.     // otherwise stop gradually
  534.     else
  535.     {
  536.         object_b->d_vector.x = 0;
  537.         object_b->d_vector.y = 0;
  538.     }
  539. }
  540.  
  541. void collision_detect(Object* object_a, Object* object_b)
  542. {
  543.     float distance_x;
  544.     float distance_y;
  545.     float distance;
  546.     float collision_depth;
  547.     int tile_colour;
  548.     Vec2 u; // how much each object moves in case of a collision
  549.    
  550.     distance_x = object_a->position.x - object_b->position.x;  // x-distance between the two objects
  551.     distance_y = object_a->position.y - object_b->position.y;  // y-distance between the two objects
  552.    
  553.     // actual distance between the two objects (hypotenuse of the x and y distances)
  554.     distance = sqrt((distance_x * distance_x) + (distance_y * distance_y));
  555.    
  556.     // if distance is less than combined radiuses
  557.     if (distance < (object_a->radius + object_b->radius))
  558.     {
  559.         // calculate how much the objects are "inside" each other
  560.         collision_depth = (object_a->radius + object_b->radius) - distance;
  561.        
  562.         //each object is moved for half of that
  563.         u.x = (distance_x/distance) * (collision_depth/2);
  564.         u.y = (distance_y/distance) * (collision_depth/2);
  565.        
  566.         // first object gets the values as is...
  567.         move_circle(object_a, u);
  568.        
  569.         // ...and for the second object they are flipped
  570.         u.x = -u.x;
  571.         u.y = -u.y;
  572.         move_circle(object_b, u);
  573.     }
  574. }
  575.  
  576. void collision()
  577. {
  578.     int x;
  579.     int i;
  580.    
  581.     // iterate through each object pair to see if they collide
  582.     for (i = 0; i < Num_Objects; i++)
  583.     {
  584.         for (x = i; x < Num_Objects-1; x++)
  585.         {
  586.             collision_detect(&object_array[i], &object_array[x+1]);
  587.         }
  588.     }
  589.    
  590.     // also check that none of the objects are going beyond the screen boundaries
  591.     edge_detect();
  592. }
  593.  
  594. void quit()
  595. {  
  596.     deinit_keyboard();
  597.     set_mode(TEXT_MODE);
  598. }
  599.  
  600. void main()
  601. {    
  602.     set_mode(VGA_256_COLOR_MODE);
  603.     init_keyboard();
  604.    
  605.     while (running == 1)
  606.     {
  607.         process_input();
  608.         radians = degToRad(direction);
  609.         chase(&object_array[0], &object_array[2]);
  610.         chase(&object_array[2], &object_array[1]);
  611.         calculate_movement();
  612.         collision();
  613.         draw_stuff();
  614.         delay(50);
  615.     }
  616.     quit();
  617. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement