Advertisement
Nuppiz

Line.c

Mar 20th, 2022 (edited)
1,064
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 31.72 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dos.h>
  4. #include <stdint.h>
  5. #include <math.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. #define SIGN(x)                   (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
  18.  
  19. #define KB_ARRAY_LENGTH     256
  20. #define KB_QUEUE_LENGTH     256
  21.  
  22. #define KEY_HIT_FLAG        1
  23. #define KEY_PRESSED_FLAG    2
  24. #define KEY_RELEASED_FLAG   0x80 // 128, MSB
  25. #define KEY_SPECIAL_CODE    0xE0 // 224
  26. #define KEY_IS_PRESSED(k)   (g_Keyboard[k] & KEY_PRESSED_FLAG)
  27. #define KEY_WAS_HIT(k)      (g_Keyboard[k] & KEY_HIT_FLAG)
  28. #define KEY_WAS_RELEASED(k) (g_Keyboard[k] & KEY_RELEASED_FLAG)
  29. #define KEY_WAS_TOGGLED(k)  (g_Keyboard[k] & (KEY_HIT_FLAG|KEY_RELEASED_FLAG))
  30. #define KEY_LEFT            75
  31. #define KEY_RIGHT           77
  32. #define KEY_UP              72
  33. #define KEY_DOWN            80
  34. #define KEY_F10             68
  35. #define KEY_ADD             78
  36. #define KEY_SUB             74
  37. #define KEY_Q               16
  38. #define KEY_W               17
  39.  
  40. #define degToRad(degree)    ((degree) * M_PI / 180.0)
  41. #define RAD_15              (M_PI/12)
  42. #define RAD_30              (M_PI/6)
  43. #define RAD_45              (M_PI/4)
  44. #define RAD_60              (M_PI/3)
  45. #define RAD_90              (M_PI/2)
  46. #define RAD_120             (M_PI/1.5)
  47. #define RAD_240             (1.5*M_PI)
  48. #define RAD_360             (2*M_PI)
  49.  
  50. #define X_AXIS              1
  51. #define Y_AXIS              2
  52.  
  53. #define SCREEN_SIZE         64000
  54. #define TILE_WIDTH          8
  55. #define TILE_HEIGHT         8
  56. #define CHARACTER_SIZE      72
  57.  
  58. int running = 1;
  59. uint8_t alphabet [4240];
  60.  
  61. typedef struct
  62. {
  63.     float x, y;
  64. } Vec2;
  65.  
  66. typedef struct
  67. {
  68.     int x, y;
  69. } Vec2_int;
  70.  
  71. typedef struct
  72. {
  73.     Vec2 startpos;
  74.     Vec2 endpos;
  75.     uint8_t colour;
  76. } Line;
  77.  
  78. typedef struct
  79. {
  80.     Vec2_int startpos;
  81.     Vec2_int endpos;
  82.     uint8_t colour;
  83. } Line_int;
  84.  
  85. typedef struct
  86. {
  87.     float angle;
  88.     Vec2* vertices;
  89.     Vec2* transformedV;
  90.     int numVertices;
  91.     float radius;
  92.     float scale;
  93.     uint8_t colour;
  94.     uint8_t* vertexColors;
  95. } Polygon;
  96.  
  97. Line line_array[5] = {
  98.     {{40.0,  50.0}, {20.0, 40.0}, 41},
  99.     {{100.0, 20.0}, {180.0, 30.0}, 55},
  100.     {{220.0, 100.0}, {220.0, 180.0}, 41},
  101.     {{60.0,  50.0}, {120.0, 50.0}, 55},
  102.     {{240.0, 100.0}, {240.0, 105.0}, 41}
  103. };
  104.  
  105. Line_int intline_array[2] = {
  106.     {{210, 10}, {260, 20}, 55},
  107.     {{220, 10}, {230, 60}, 41}
  108. };
  109.  
  110. Polygon poly_array[10];
  111.  
  112. typedef struct
  113. {
  114.     int offset[SCREEN_HEIGHT];
  115.     uint8_t color[SCREEN_HEIGHT];
  116. } Span;
  117.  
  118. Span LeftEdge;
  119. Span RightEdge;
  120.  
  121. struct Input
  122. {
  123.     uint8_t kb_array[KB_ARRAY_LENGTH];
  124.     uint8_t kb_queue[KB_QUEUE_LENGTH];
  125.     uint8_t kb_head;
  126.     uint8_t kb_tail;
  127. };
  128.  
  129. typedef struct Input Input_t;
  130.  
  131. uint8_t *VGA=(uint8_t *)0xA0000000L;        /* this points to video memory. */
  132. uint8_t far screen_buf [64000];
  133.  
  134. Input_t Input = {0};
  135. Input_t* g_Input = &Input;
  136. uint8_t* g_Keyboard = Input.kb_array;
  137.  
  138. static void interrupt (far *old_keyhandler)(void);
  139.  
  140. void set_mode(uint8_t mode)
  141. {
  142.     union REGS regs;
  143.  
  144.     regs.h.ah = SET_MODE;
  145.     regs.h.al = mode;
  146.     int86(VIDEO_INT, &regs, &regs);
  147. }
  148.  
  149. Vec2 change_vec_angle(Vec2 vector, float angle)
  150. {
  151.     Vec2 x_vec;
  152.     Vec2 y_vec;
  153.     Vec2 newVector;
  154.    
  155.     x_vec.x = cos(angle) * vector.x;
  156.     x_vec.y = sin(angle) * vector.x;
  157.     y_vec.x = cos(angle) * vector.y;
  158.     y_vec.y = sin(angle) * vector.y;
  159.    
  160.     newVector.x = x_vec.x - y_vec.y;
  161.     newVector.y = x_vec.y + y_vec.x;
  162.    
  163.     return newVector;
  164. }
  165.  
  166. /*Vec2 change_vec_scale(Vec2 vector, float scale)
  167. {
  168.     Vec2 newVector;
  169.    
  170.     newVector.x = vector.x * scale;
  171.     newVector.y = vector.y * scale;
  172.    
  173.     return newVector;
  174. }
  175. void change_poly_angles(Polygon* poly, float angle)
  176. {
  177.     char i;
  178.    
  179.     for (i = 0; i < poly->numVertices; i++)
  180.     {
  181.         poly->transformedV[i] = change_vec_angle(poly->transformedV[i], angle);
  182.     }
  183.     poly->angle = angle;
  184. }
  185. void change_poly_size(Polygon* poly, float scale)
  186. {
  187.     char i;
  188.    
  189.     for (i = 0; i < poly->numVertices; i++)
  190.     {
  191.         poly->transformedV[i] = change_vec_scale(poly->transformedV[i], scale);
  192.     }
  193. }*/
  194.  
  195. void updatePoly(Polygon* poly)
  196. {
  197.     char i;
  198.     float cos_angle;
  199.     float sin_angle;
  200.     float old_x;
  201.     float old_y;
  202.     float new_x;
  203.     float new_y;
  204.    
  205.     for (i = 0; i < poly->numVertices; i++)
  206.     {
  207.         old_x = poly->vertices[i].x;
  208.         old_y = poly->vertices[i].y;
  209.         cos_angle = cos(poly->angle);
  210.         sin_angle = sin(poly->angle);
  211.         new_x = (old_x * cos_angle - old_y * sin_angle) * poly->scale;
  212.         new_y = (old_x * sin_angle + old_y * cos_angle) * poly->scale;
  213.         poly->transformedV[i].x = new_x;
  214.         poly->transformedV[i].y = new_y;
  215.     }
  216. }
  217.  
  218. void interrupt far keyhandler()
  219. {
  220.     uint8_t key_scan = 0;
  221.     static uint8_t key_scan_last = 0;
  222.     static uint8_t key_special = 0;
  223.     static uint8_t key_special_last = 0;
  224.     // obtain scancode
  225.     asm {
  226.         cli // clear interrupt flag; prevent other external interrupts
  227.         in  al, 0x60
  228.         mov key_scan, al
  229.         in  al, 0x61 // get keyboard status
  230.         mov bl, al
  231.         or  al, 0x80 // MSB set
  232.         out 0x61, al // write (ACK)
  233.         mov al, bl   // MSB clear
  234.         out 0x61, al // write
  235.     }
  236.     // remember the last special key code
  237.     if (key_scan_last == KEY_SPECIAL_CODE)
  238.         key_special = key_scan;
  239.     else if (key_scan != KEY_SPECIAL_CODE)
  240.         key_special = 0;
  241.     // place scancode on queue unless it's the same as the previous one
  242.     if (key_scan != key_scan_last && (key_special != key_special_last || key_special_last == 0))
  243.     {
  244.         g_Input->kb_queue[g_Input->kb_tail] = key_scan;
  245.         if (g_Input->kb_tail+1 != g_Input->kb_head)
  246.             g_Input->kb_tail++;
  247.     }
  248.     key_scan_last = key_scan;
  249.     key_special_last = key_special;
  250.     // PIC 8259 reset
  251.     asm {
  252.         mov al, 0x20
  253.         out 0x20, al
  254.         sti // set interrupt flag; allow external interrupts again
  255.     }
  256. }
  257.  
  258. void init_keyboard()
  259. {
  260.     uint8_t far *bios_key_state;
  261.     asm cli
  262.     // save address of current keyhandler interrupt function
  263.     old_keyhandler = _dos_getvect(9);
  264.     // caps lock & num lock off
  265.     bios_key_state = MK_FP(0x040, 0x017);
  266.     *bios_key_state &= (~(32|64));
  267.     old_keyhandler();
  268.     // replace old keyhandler with new keyhandler function
  269.     _dos_setvect(9, keyhandler);
  270.     asm sti
  271. }
  272.  
  273. void deinit_keyboard()
  274. {
  275.     // restore old keyhandler
  276.     asm cli
  277.     _dos_setvect(9, old_keyhandler);
  278.     asm sti
  279.  
  280.     g_Input = NULL;
  281. }
  282.  
  283. void get_keyboard()
  284. {
  285.     int i;
  286.     uint8_t key_scan;
  287.     uint8_t extended = 0;
  288.     uint8_t released = 0;
  289.  
  290.     while (g_Input->kb_head != g_Input->kb_tail)
  291.     {
  292.         key_scan = g_Input->kb_queue[g_Input->kb_head++];
  293.         /* handle special keys, but only if a second scancode follows*/
  294.         if (key_scan == KEY_SPECIAL_CODE)
  295.                 extended = 128;
  296.         /* remember the release flag before clearing it*/
  297.         released = key_scan & KEY_RELEASED_FLAG;
  298.         key_scan &= ~KEY_RELEASED_FLAG;
  299.         if (released)
  300.         {
  301.             g_Input->kb_array[key_scan+extended] &= KEY_HIT_FLAG;
  302.             g_Input->kb_array[key_scan+extended] |= KEY_RELEASED_FLAG;
  303.         }
  304.         else
  305.             g_Input->kb_array[key_scan+extended] |= (KEY_HIT_FLAG|KEY_PRESSED_FLAG);
  306.  
  307.         extended = 0;
  308.     }
  309. }
  310.  
  311. void clear_keys()
  312. {
  313.     int i;
  314.     for (i = 0; i < KB_ARRAY_LENGTH; i++)
  315.         g_Input->kb_array[i] &= KEY_PRESSED_FLAG;
  316. }
  317.  
  318. void control_ingame()
  319. {
  320.     if (KEY_IS_PRESSED(KEY_UP))
  321.     {
  322.         poly_array[4].transformedV[2] = change_vec_angle(poly_array[1].transformedV[2], RAD_15);
  323.     }
  324.    
  325.     else if (KEY_IS_PRESSED(KEY_DOWN))
  326.     {
  327.         poly_array[4].transformedV[2] = change_vec_angle(poly_array[1].transformedV[2], -RAD_15);
  328.     }
  329.    
  330.     else if (KEY_IS_PRESSED(KEY_LEFT))
  331.     {
  332.         poly_array[5].angle -= RAD_15;
  333.         updatePoly(&poly_array[5]);
  334.     }
  335.    
  336.     else if (KEY_IS_PRESSED(KEY_RIGHT))
  337.     {
  338.         poly_array[5].angle += RAD_15;
  339.         updatePoly(&poly_array[5]);
  340.     }
  341.    
  342.     else if (KEY_IS_PRESSED(KEY_ADD))
  343.     {
  344.         poly_array[5].scale *= 1.05;
  345.         updatePoly(&poly_array[5]);
  346.     }
  347.    
  348.     else if (KEY_IS_PRESSED(KEY_SUB))
  349.     {
  350.         poly_array[5].scale /= 1.05;
  351.         updatePoly(&poly_array[5]);
  352.     }
  353. }
  354.  
  355. void process_input()
  356. {
  357.     get_keyboard();
  358.  
  359.     control_ingame();
  360.    
  361.     // F10 always exits, wherever you are
  362.     if (KEY_WAS_HIT(KEY_F10))
  363.         running = 0;
  364.  
  365.     clear_keys();
  366. }
  367.  
  368. void load_font()
  369. {
  370.     FILE* file_ptr;
  371.     file_ptr = fopen("FONT.7UP", "rb");
  372.     fread(alphabet, 1, 4240, file_ptr);
  373.     fclose(file_ptr);
  374. }
  375.  
  376. void draw_text(int x, int y, int i, uint8_t color)
  377. {
  378.     uint8_t index_x = 0;
  379.     uint8_t index_y = 0;
  380.     i = i * CHARACTER_SIZE;
  381.  
  382.     for (index_y=0;index_y<TILE_HEIGHT;index_y++)
  383.     {
  384.         for (index_x=0;index_x<TILE_WIDTH;index_x++)
  385.         {
  386.             if (alphabet[i] != 13)
  387.             {
  388.                 SET_PIXEL(x, y, alphabet[i] + color);
  389.                 i++;
  390.                 x++;
  391.             }
  392.             else
  393.             {
  394.                 i++;
  395.                 x++;
  396.             }
  397.         }
  398.         index_x = 0;
  399.         x = x - TILE_WIDTH;
  400.         y++;
  401.     }
  402.     index_y = 0;
  403.     i= 0;
  404. }
  405.  
  406. void render_text(int x, int y, char* string, uint8_t color)
  407. {
  408.     int i = 0;
  409.     char c;
  410.    
  411.     while (string[i] != 0)
  412.     {
  413.         c = string[i];
  414.         draw_text(x, y, c - 32, color);
  415.         x = x + 10;
  416.         i++;
  417.     }
  418. }
  419.  
  420. void draw_line_hor(int start_x, int start_y, int x_diff, uint8_t colour)
  421. {
  422.     int offset_x;
  423.    
  424.     if (x_diff < 0)
  425.     {
  426.         start_x += x_diff;
  427.         x_diff = abs(x_diff);
  428.     }
  429.    
  430.     for (offset_x = 0; offset_x < x_diff; offset_x++)
  431.     {
  432.         SET_PIXEL(start_x + offset_x, start_y, colour);
  433.     }
  434. }
  435.  
  436. void draw_line_ver(int start_x, int start_y, int y_diff, uint8_t colour)
  437. {
  438.     int offset_y;
  439.    
  440.     if (y_diff < 0)
  441.     {
  442.         start_y += y_diff;
  443.         y_diff = abs(y_diff);
  444.     }
  445.    
  446.     for (offset_y = 0; offset_y < y_diff + 1; offset_y++)
  447.     {
  448.         SET_PIXEL(start_x, start_y + offset_y, colour);
  449.     }
  450. }
  451.  
  452. void draw_line(Vec2 v1, Vec2 v2, uint8_t colour)
  453. {
  454.     float offset_x;
  455.     float offset_y;
  456.    
  457.     float x_diff = (v2.x - v1.x);
  458.     float y_diff = (v2.y - v1.y);
  459.    
  460.     int x_sign = SIGN(x_diff);
  461.     int y_sign = SIGN(y_diff);
  462.    
  463.     int x_pixel;
  464.     int y_pixel;
  465.    
  466.     float slope = 0.0;
  467.    
  468.     if (fabs(y_diff) < 1.5)
  469.         draw_line_hor(v1.x, v1.y, x_diff, colour);
  470.    
  471.     else if (fabs(x_diff) < 1.5)
  472.         draw_line_ver(v1.x, v1.y, y_diff, colour);
  473.    
  474.     else if (y_diff < 0 && x_diff < 0)
  475.     {
  476.         if (y_diff < x_diff)
  477.         {
  478.             slope = y_diff / x_diff;
  479.            
  480.             for (offset_x = 0; offset_x > x_diff; offset_x += x_sign)
  481.             {
  482.                 offset_y = offset_x * slope;
  483.                 offset_x += 0.75;
  484.                 offset_y += 0.75;
  485.                 SET_PIXEL((int)v2.x - (int)offset_x, (int)v2.y - (int)offset_y, colour);
  486.             }
  487.         }
  488.         else
  489.         {
  490.             slope = x_diff / y_diff;
  491.            
  492.             for (offset_y = 0; offset_y > y_diff; offset_y += y_sign)
  493.             {
  494.                 offset_x = offset_y * slope;
  495.                 offset_x -= 0.75;
  496.                 offset_y += 0.75;
  497.                 SET_PIXEL((int)v2.x - (int)offset_x, (int)v2.y - (int)offset_y, colour);
  498.             }
  499.         }
  500.     }
  501.    
  502.     else if (y_diff < 0 || x_diff < 0)
  503.     {
  504.         if (y_diff < x_diff)
  505.         {
  506.             slope = y_diff / x_diff;
  507.            
  508.             for (offset_x = 0; offset_x < x_diff; offset_x += x_sign)
  509.             {
  510.                 offset_y = offset_x * slope;
  511.                 offset_x -= 0.6;
  512.                 offset_y -= 0.6;
  513.                 SET_PIXEL((int)v1.x + (int)offset_x, (int)v1.y + (int)offset_y, colour);
  514.             }
  515.         }
  516.  
  517.         else
  518.         {
  519.             slope = x_diff / y_diff;
  520.            
  521.             for (offset_y = 0; offset_y < y_diff; offset_y += y_sign)
  522.             {
  523.                 offset_x = offset_y * slope;
  524.                 offset_x -= 0.6;
  525.                 offset_y -= 0.6;
  526.                 SET_PIXEL((int)v1.x + (int)offset_x, (int)v1.y + (int)offset_y, colour);
  527.             }
  528.         }
  529.     }
  530.    
  531.     else if (y_diff < x_diff)
  532.     {
  533.         slope = y_diff / x_diff;
  534.        
  535.         for (offset_x = 0; offset_x < x_diff; offset_x += x_sign)
  536.         {
  537.             offset_y = offset_x * slope;
  538.             SET_PIXEL((int)v1.x + (int)offset_x, (int)v1.y + (int)offset_y, colour);
  539.         }
  540.     }
  541.    
  542.     else
  543.     {
  544.         slope = x_diff / y_diff;
  545.        
  546.         for (offset_y = 0; offset_y < y_diff; offset_y += y_sign)
  547.         {
  548.             offset_x = offset_y * slope;
  549.             SET_PIXEL((int)v1.x + (int)offset_x, (int)v1.y + (int)offset_y, colour);
  550.         }
  551.     }
  552. }
  553.  
  554. void draw_line_int(Vec2_int p0, Vec2_int p1, uint8_t colour)
  555. {
  556.     int offset_x = 0;
  557.     int offset_y = 0;
  558.    
  559.     int x_diff = (p1.x - p0.x);
  560.     int y_diff = (p1.y - p0.y);
  561.     int counter;
  562.    
  563.     int x_diff_true = x_diff;
  564.     int y_diff_true = y_diff;
  565.    
  566.     int x_sign = SIGN(x_diff);
  567.     int y_sign = SIGN(y_diff);
  568.    
  569.     x_diff = abs(x_diff);
  570.     y_diff = abs(y_diff);
  571.    
  572.     if (y_diff == 0)
  573.         draw_line_hor(p0.x, p0.y, x_diff_true, colour);
  574.    
  575.     else if (x_diff == 0)
  576.         draw_line_ver(p0.x, p0.y, y_diff_true, colour);
  577.    
  578.     else if (y_diff < x_diff)
  579.     {
  580.         counter = 0;
  581.         while (offset_x < x_diff)
  582.         {
  583.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, colour);
  584.             offset_x++;
  585.             counter += y_diff;
  586.             if (counter >= x_diff)
  587.             {
  588.                 offset_y++;
  589.                 counter -= x_diff;
  590.             }
  591.         }
  592.     }
  593.    
  594.     else if (x_diff < y_diff)
  595.     {
  596.         counter = 0;
  597.         while (offset_y < y_diff)
  598.         {
  599.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, colour);
  600.             offset_y++;
  601.             counter += x_diff;
  602.             if (counter >= y_diff)
  603.             {
  604.                 offset_x++;
  605.                 counter -= y_diff;
  606.             }
  607.         }
  608.     }
  609.    
  610.     else
  611.     {        
  612.         while (offset_y <= y_diff && offset_x <= x_diff)
  613.         {
  614.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, colour);
  615.             offset_y++;
  616.             offset_x++;
  617.         }
  618.     }
  619. }
  620.  
  621. void interpolate_hor(int start_x, int end_x, int start_y, uint8_t start_colour, uint8_t end_colour)
  622. {
  623.     int offset_x;
  624.     int x_diff = end_x - start_x;
  625.     uint8_t colour_add = 0;
  626.     float colour_step = (float)x_diff / abs(end_colour - start_colour);
  627.     uint8_t colour_counter = 0;
  628.    
  629.     for (offset_x = 0; offset_x < x_diff; offset_x++)
  630.     {
  631.         SET_PIXEL(start_x + offset_x, start_y, start_colour + colour_add);
  632.         colour_counter++;
  633.         if (colour_counter > colour_step && (start_colour + colour_add) < end_colour)
  634.         {
  635.             colour_add++;
  636.             colour_counter = 0;
  637.         }
  638.     }
  639. }
  640.  
  641. void interpolate_colours(Vec2 p0, Vec2 p1, uint8_t st_col, uint8_t end_col)
  642. {
  643.     int offset_x = 0;
  644.     int offset_y = 0;
  645.    
  646.     int x_diff = (p1.x - p0.x);
  647.     int y_diff = (p1.y - p0.y);
  648.    
  649.     int length = sqrt((abs(x_diff) * abs(x_diff)) + (abs(y_diff) * abs(y_diff)));
  650.     uint8_t col_add = 0;
  651.     uint8_t col_step = length / abs(end_col - st_col);
  652.     uint8_t col_counter = 0;
  653.    
  654.     int counter;
  655.    
  656.     int x_diff_true = x_diff;
  657.     int y_diff_true = y_diff;
  658.    
  659.     int x_sign = SIGN(x_diff);
  660.     int y_sign = SIGN(y_diff);
  661.    
  662.     x_diff = abs(x_diff);
  663.     y_diff = abs(y_diff);
  664.    
  665.     if (y_diff == 0)
  666.     {
  667.         if (x_diff_true < 0)
  668.         {
  669.             p0.x += x_diff_true;
  670.         }
  671.        
  672.         for (offset_x = 0; offset_x < x_diff; offset_x++)
  673.         {
  674.             SET_PIXEL(p0.x + offset_x, p0.y, st_col + col_add);
  675.             col_counter++;
  676.             if (col_counter == col_step && (st_col + col_add) < end_col)
  677.             {
  678.                 col_add++;
  679.                 col_counter = 0;
  680.             }
  681.         }
  682.     }
  683.        
  684.     else if (x_diff == 0)
  685.     {
  686.         if (y_diff_true < 0)
  687.         {
  688.             p0.y += y_diff_true;
  689.         }
  690.        
  691.         for (offset_y = 0; offset_y < y_diff; offset_y++)
  692.         {
  693.             SET_PIXEL(p0.x, p0.y + offset_y, st_col + col_add);
  694.             col_counter++;
  695.             if (col_counter == col_step && (st_col + col_add) < end_col)
  696.             {
  697.                 col_add++;
  698.                 col_counter = 0;
  699.             }
  700.         }
  701.     }
  702.    
  703.     else if (y_diff < x_diff)
  704.     {
  705.         counter = 0;
  706.         while (offset_x < x_diff)
  707.         {
  708.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, st_col + col_add);
  709.             offset_x++;
  710.             col_counter++;
  711.             if (col_counter == col_step && (st_col + col_add) < end_col)
  712.             {
  713.                 col_add++;
  714.                 col_counter = 0;
  715.             }
  716.             counter += y_diff;
  717.             if (counter >= x_diff)
  718.             {
  719.                 offset_y++;
  720.                 counter -= x_diff;
  721.             }
  722.         }
  723.     }
  724.    
  725.     else if (x_diff < y_diff)
  726.     {
  727.         counter = 0;
  728.         while (offset_y < y_diff)
  729.         {
  730.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, st_col + col_add);
  731.             offset_y++;
  732.             col_counter++;
  733.             if (col_counter == col_step && (st_col + col_add) < end_col)
  734.             {
  735.                 col_add++;
  736.                 col_counter = 0;
  737.             }
  738.             counter += x_diff;
  739.             if (counter >= y_diff)
  740.             {
  741.                 offset_x++;
  742.                 counter -= y_diff;
  743.             }
  744.         }
  745.     }
  746.    
  747.     else
  748.     {        
  749.         while (offset_y <= y_diff && offset_x <= x_diff)
  750.         {
  751.             SET_PIXEL(p0.x + offset_x * x_sign, p0.y + offset_y * y_sign, st_col + col_add);
  752.             offset_y++;
  753.             offset_x++;
  754.             col_counter++;
  755.             if (col_counter == col_step && (st_col + col_add) < end_col)
  756.             {
  757.                 col_add++;
  758.                 col_counter = 0;
  759.             }
  760.         }
  761.     }
  762. }
  763.  
  764. void test_draw()
  765. {
  766.     char i = 0;
  767.     float angle = 12;
  768.     int radius = 90;
  769.     Vec2 v1;
  770.     Vec2 v2;
  771.     Vec2 v3;
  772.    
  773.     while (i < 12)
  774.     {
  775.         v1.x = cos(angle) * radius + 160.0;
  776.         v1.y = sin(angle) * radius + 100.0;
  777.         v2.x = cos(angle + RAD_30) * radius + 160.0;
  778.         v2.y = sin(angle + RAD_30) * radius + 100.0;
  779.         v3.x = 160.0;
  780.         v3.y = 100.0;
  781.         interpolate_colours(v1, v2, 64, 79);
  782.         interpolate_colours(v3, v1, 64, 79);
  783.         //SET_PIXEL(v1.x, v1.y, 14);
  784.         //SET_PIXEL(v2.x, v2.y, 14);
  785.         angle += RAD_30;
  786.         i++;
  787.     }
  788. }
  789.  
  790. Polygon makeSquare(float angle, float side_length, float scale, uint8_t colour)
  791. {
  792.     Polygon newSquare;
  793.    
  794.     newSquare.numVertices = 4;
  795.     newSquare.vertices = malloc(newSquare.numVertices * sizeof(Vec2));
  796.     newSquare.transformedV = malloc(newSquare.numVertices * sizeof(Vec2));
  797.     newSquare.angle = angle;
  798.     newSquare.scale = scale;
  799.     newSquare.colour = colour;
  800.    
  801.     newSquare.vertices[0].x = -side_length/2.0;
  802.     newSquare.vertices[0].y = -side_length/2.0;
  803.     newSquare.vertices[1].x = side_length/2.0;
  804.     newSquare.vertices[1].y = -side_length/2.0;
  805.     newSquare.vertices[2].x = side_length/2.0;
  806.     newSquare.vertices[2].y = side_length/2.0;
  807.     newSquare.vertices[3].x = -side_length/2.0;
  808.     newSquare.vertices[3].y = side_length/2.0;
  809.    
  810.     memcpy(newSquare.transformedV, newSquare.vertices, sizeof(Vec2) * newSquare.numVertices);
  811.    
  812.     return newSquare;
  813. }
  814.  
  815. Polygon makePolygon(float angle, int numVertices, float radius, float scale, uint8_t colour)
  816. {
  817.     Polygon newPolygon;
  818.     char i = 0;
  819.     float angle_step = RAD_360/numVertices;
  820.    
  821.     newPolygon.numVertices = numVertices;
  822.     newPolygon.vertices = malloc(numVertices * sizeof(Vec2));
  823.     newPolygon.transformedV = malloc(numVertices * sizeof(Vec2));
  824.     newPolygon.angle = angle;
  825.     newPolygon.radius = radius;
  826.     newPolygon.scale = scale;
  827.     newPolygon.colour = colour;
  828.    
  829.     while (i < newPolygon.numVertices)
  830.     {
  831.         newPolygon.vertices[i].x = cos((angle_step + angle) * (i + 1)) * radius;
  832.         newPolygon.vertices[i].y = sin((angle_step + angle) * (i + 1)) * radius;
  833.        
  834.         i++;
  835.     }
  836.    
  837.     memcpy(newPolygon.transformedV, newPolygon.vertices, sizeof(Vec2) * newPolygon.numVertices);
  838.    
  839.     return newPolygon;
  840. }
  841.  
  842. Polygon makeShadedTriangle(float angle, int numVertices, float radius, float scale, uint8_t col_1, uint8_t col_2, uint8_t col_3)
  843. {
  844.     Polygon newPolygon;
  845.     char i = 0;
  846.     float angle_step = RAD_360/numVertices;
  847.    
  848.     newPolygon.numVertices = numVertices;
  849.     newPolygon.vertices = malloc(numVertices * sizeof(Vec2));
  850.     newPolygon.transformedV = malloc(numVertices * sizeof(Vec2));
  851.     newPolygon.vertexColors = malloc(3 * sizeof(uint8_t));
  852.     newPolygon.angle = angle;
  853.     newPolygon.radius = radius;
  854.     newPolygon.scale = scale;
  855.    
  856.     while (i < newPolygon.numVertices)
  857.     {
  858.         newPolygon.vertices[i].x = cos((angle_step + angle) * (i + 1)) * radius;
  859.         newPolygon.vertices[i].y = sin((angle_step + angle) * (i + 1)) * radius;
  860.        
  861.         i++;
  862.     }
  863.    
  864.     newPolygon.vertexColors[0] = col_1;
  865.     newPolygon.vertexColors[1] = col_2;
  866.     newPolygon.vertexColors[2] = col_3;
  867.    
  868.     memcpy(newPolygon.transformedV, newPolygon.vertices, sizeof(Vec2) * newPolygon.numVertices);
  869.    
  870.     return newPolygon;
  871. }
  872.  
  873. void drawTriangleLine(Vec2 p1, Vec2 p2, Vec2_int center, Span* edge)
  874. {
  875.     uint8_t color;
  876.    
  877.     float offset_y;
  878.     float offset_x;
  879.    
  880.     float x_diff = (p2.x - p1.x);
  881.     float y_diff = (p2.y - p1.y);
  882.    
  883.     float slope = 0.0;
  884.    
  885.     int y_sign = SIGN(y_diff);
  886.    
  887.     int x, y;
  888.    
  889.     y_diff = fabs(y_diff);
  890.    
  891.     slope = x_diff / y_diff;
  892.        
  893.     for (offset_y = 0; offset_y < y_diff; offset_y++)
  894.     {
  895.         offset_x = offset_y * slope;
  896.         x = (int)(center.x + p1.x + offset_x);
  897.         y = (int)(center.y + p1.y + offset_y) * y_sign;
  898.         edge->offset[y] = x;
  899.         //SET_PIXEL(edge->offset[y], y, color);
  900.     }
  901. }
  902.  
  903. void drawTriangleLineInterpolated(Vec2 p1, Vec2 p2, Vec2_int center, Span* edge, uint8_t colour_1, uint8_t colour_2)
  904. {
  905.     float colour = colour_1;
  906.     int colour_diff = colour_2 - colour_1;
  907.    
  908.     float offset_y;
  909.     float offset_x;
  910.    
  911.     float x_diff = (p2.x - p1.x);
  912.     float y_diff = (p2.y - p1.y);
  913.    
  914.     float colour_ratio;
  915.    
  916.     float slope = 0.0;
  917.    
  918.     int y_sign = SIGN(y_diff);
  919.     int x, y;
  920.     colour_diff = abs(colour_diff);
  921.    
  922.     if (y_diff > x_diff)
  923.     {
  924.         y_diff = fabs(y_diff);
  925.         colour_ratio = colour_diff / y_diff;
  926.         slope = x_diff / y_diff;
  927.            
  928.         for (offset_y = 0; offset_y < y_diff; offset_y++)
  929.         {
  930.             offset_x = offset_y * slope;
  931.             colour += colour_ratio;
  932.             x = (int)(center.x + p1.x + offset_x);
  933.             y = (int)(center.y + p1.y + offset_y) * y_sign;
  934.             edge->offset[y] = x;
  935.             edge->color[y] = (uint8_t)colour;
  936.             SET_PIXEL(edge->offset[y], y, edge->color[y]);
  937.         }
  938.     }
  939.    
  940.     else if (x_diff > y_diff)
  941.     {
  942.         x_diff = fabs(x_diff);
  943.         colour_ratio =  colour_diff / x_diff;
  944.         slope = y_diff / x_diff;
  945.            
  946.         for (offset_x = 0; offset_x < x_diff; offset_x++)
  947.         {
  948.             offset_y = offset_x * slope;
  949.             colour += colour_ratio;
  950.             x = (int)(center.x + p1.x + offset_x);
  951.             y = (int)(center.y + p1.y + offset_y) * y_sign;
  952.             edge->offset[y] = x;
  953.             edge->color[y] = (uint8_t)colour;
  954.             SET_PIXEL(edge->offset[y], y, edge->color[y]);
  955.         }
  956.     }
  957. }
  958.  
  959. void fillSpans(int top, int bottom, uint8_t colour)
  960. {
  961.     int line;
  962.     Vec2 p0, p1;
  963.    
  964.     for (line = top; line < bottom; line++)
  965.     {
  966.         draw_line_hor(LeftEdge.offset[line], line, (RightEdge.offset[line] - LeftEdge.offset[line]), colour);
  967.         /*
  968.         p0.y = line;
  969.         p1.y = line;
  970.         p0.x = LeftEdge.offset[line];
  971.         p1.x = RightEdge.offset[line];
  972.        
  973.         interpolate_colours(p0, p1, 64, 95);*/
  974.     }
  975. }
  976.  
  977. void interpolateSpans(int top, int bottom)
  978. {
  979.     int line;
  980.     Vec2 p0, p1;
  981.     uint8_t col_1, col_2;
  982.    
  983.     for (line = top; line < bottom; line++)
  984.     {
  985.         p0.y = line;
  986.         p1.y = line;
  987.         p0.x = LeftEdge.offset[line];
  988.         p1.x = RightEdge.offset[line];
  989.         col_1 = LeftEdge.color[line];
  990.         col_2 = RightEdge.color[line];
  991.        
  992.         //interpolate_colours(p0, p1, col_1, col_2);
  993.         interpolate_hor(p0.x, p1.x, line, col_1, col_2);
  994.     }
  995. }
  996.  
  997. void sortPair(Vec2* v0, Vec2* v1)
  998. {
  999.     Vec2 temp;
  1000.    
  1001.     if (v0->y > v1->y)
  1002.     {
  1003.         temp = *v0;
  1004.         *v0 = *v1;
  1005.         *v1 = temp;
  1006.     }
  1007. }
  1008.  
  1009. void sortPairWithColour(Vec2* v0, Vec2* v1, uint8_t* colour1, uint8_t* colour2)
  1010. {
  1011.     Vec2 temp;
  1012.     uint8_t colour_temp;
  1013.    
  1014.     if (v0->y > v1->y)
  1015.     {
  1016.         temp = *v0;
  1017.         colour_temp = *colour1;
  1018.         *v0 = *v1;
  1019.         *colour1 = *colour2;
  1020.         *v1 = temp;
  1021.         *colour2 = colour_temp;
  1022.     }
  1023. }
  1024.  
  1025. void drawFilledTriangle(Polygon* triangle)
  1026. {    
  1027.     Vec2 A, B, C;
  1028.     Vec2 AB, AC;
  1029.     Vec2_int center = {159, 99};
  1030.     float cross_product;
  1031.    
  1032.     A = triangle->transformedV[0];
  1033.     B = triangle->transformedV[1];
  1034.     C = triangle->transformedV[2];
  1035.    
  1036.     sortPair(&A, &B);
  1037.     sortPair(&A, &C);
  1038.     sortPair(&B, &C);
  1039.    
  1040.     AB.x = B.x - A.x;
  1041.     AB.y = B.y - A.y;
  1042.     AC.x = C.x - A.x;
  1043.     AC.y = C.y - A.y;
  1044.    
  1045.     cross_product = (AB.x * AC.y) - (AB.y * AC.x);
  1046.    
  1047.     if (cross_product > 0)
  1048.     {
  1049.         drawTriangleLine(A, B, center, &RightEdge);
  1050.         drawTriangleLine(B, C, center, &RightEdge);
  1051.         drawTriangleLine(A, C, center, &LeftEdge);
  1052.     }
  1053.     else
  1054.     {
  1055.         drawTriangleLine(A, B, center, &LeftEdge);
  1056.         drawTriangleLine(B, C, center, &LeftEdge);
  1057.         drawTriangleLine(A, C, center, &RightEdge);
  1058.     }
  1059.    
  1060.     fillSpans(center.y + A.y, center.y + C.y, triangle->colour);
  1061. }
  1062.  
  1063. void drawShadedTriangle(Polygon* triangle)
  1064. {    
  1065.     Vec2 A, B, C;
  1066.     Vec2 AB, AC;
  1067.     Vec2_int center = {159, 99};
  1068.     float cross_product;
  1069.     uint8_t A_colour, B_colour, C_colour;
  1070.    
  1071.     A = triangle->transformedV[0];
  1072.     B = triangle->transformedV[1];
  1073.     C = triangle->transformedV[2];
  1074.    
  1075.     A_colour = triangle->vertexColors[0];
  1076.     B_colour = triangle->vertexColors[1];
  1077.     C_colour = triangle->vertexColors[2];
  1078.    
  1079.     sortPairWithColour(&A, &B, &A_colour, &B_colour);
  1080.     sortPairWithColour(&A, &C, &A_colour, &C_colour);
  1081.     sortPairWithColour(&B, &C, &B_colour, &C_colour);
  1082.    
  1083.     AB.x = B.x - A.x;
  1084.     AB.y = B.y - A.y;
  1085.     AC.x = C.x - A.x;
  1086.     AC.y = C.y - A.y;
  1087.    
  1088.     cross_product = (AB.x * AC.y) - (AB.y * AC.x);
  1089.    
  1090.     if (cross_product > 0)
  1091.     {
  1092.         drawTriangleLineInterpolated(A, B, center, &RightEdge, A_colour, B_colour);
  1093.         drawTriangleLineInterpolated(B, C, center, &RightEdge, B_colour, C_colour);
  1094.         drawTriangleLineInterpolated(A, C, center, &LeftEdge, A_colour, C_colour);
  1095.     }
  1096.     else
  1097.     {
  1098.         drawTriangleLineInterpolated(A, B, center, &LeftEdge, A_colour, B_colour);
  1099.         drawTriangleLineInterpolated(B, C, center, &LeftEdge, B_colour, C_colour);
  1100.         drawTriangleLineInterpolated(A, C, center, &RightEdge, A_colour, C_colour);
  1101.     }
  1102.    
  1103.     //interpolateSpans(center.y + A.y, center.y + C.y);
  1104. }
  1105.  
  1106. void draw_polygon(Polygon* poly, int center_x, int center_y)
  1107. {
  1108.     char i = 0;
  1109.     Vec2 start_loc;
  1110.     Vec2 end_loc;
  1111.    
  1112.     while (i < poly->numVertices - 1)
  1113.     {
  1114.         start_loc.x = center_x + poly->transformedV[i].x;
  1115.         start_loc.y = center_y + poly->transformedV[i].y;
  1116.        
  1117.         end_loc.x = center_x + poly->transformedV[i + 1].x;
  1118.         end_loc.y = center_y + poly->transformedV[i + 1].y;
  1119.  
  1120.         draw_line(start_loc, end_loc, poly->colour);
  1121.        
  1122.         i++;
  1123.     }
  1124.    
  1125.     start_loc.x = center_x + poly->transformedV[i].x;
  1126.     start_loc.y = center_y + poly->transformedV[i].y;
  1127.    
  1128.     end_loc.x = center_x + poly->transformedV[0].x;
  1129.     end_loc.y = center_y + poly->transformedV[0].y;
  1130.    
  1131.     draw_line(start_loc, end_loc, poly->colour);
  1132. }
  1133.  
  1134. void draw_polygon_int(Polygon* poly, int center_x, int center_y)
  1135. {
  1136.     char i = 0;
  1137.     Vec2_int start_loc;
  1138.     Vec2_int end_loc;
  1139.    
  1140.     while (i < poly->numVertices - 1)
  1141.     {
  1142.         start_loc.x = center_x + (int)poly->transformedV[i].x;
  1143.         start_loc.y = center_y + (int)poly->transformedV[i].y;
  1144.        
  1145.         end_loc.x = center_x + (int)poly->transformedV[i + 1].x;
  1146.         end_loc.y = center_y + (int)poly->transformedV[i + 1].y;
  1147.  
  1148.         draw_line_int(start_loc, end_loc, poly->colour);
  1149.        
  1150.         i++;
  1151.     }
  1152.    
  1153.     start_loc.x = center_x + (int)poly->transformedV[i].x;
  1154.     start_loc.y = center_y + (int)poly->transformedV[i].y;
  1155.    
  1156.     end_loc.x = center_x + (int)poly->transformedV[0].x;
  1157.     end_loc.y = center_y + (int)poly->transformedV[0].y;
  1158.    
  1159.     draw_line_int(start_loc, end_loc, poly->colour);
  1160. }
  1161.  
  1162. void draw_lines()
  1163. {
  1164.     char i = 0;
  1165.     Vec2 p0 = {100.0, 185.0};
  1166.     Vec2 p1 = {170.0, 165.0};
  1167.    
  1168.     while (i < 5)
  1169.     {
  1170.         draw_line(line_array[i].startpos, line_array[i].endpos, line_array[i].colour);
  1171.         i++;
  1172.     }
  1173.     draw_line_int(intline_array[0].startpos, intline_array[0].endpos, line_array[0].colour);
  1174.     draw_line_int(intline_array[1].startpos, intline_array[1].endpos, line_array[1].colour);
  1175.     interpolate_colours(p0, p1, 16, 31);
  1176. }
  1177.  
  1178. void draw_polygons()
  1179. {
  1180.     char i = 0;
  1181.     int x = 100;
  1182.     int y = 100;
  1183.    
  1184.     while (i < 3)
  1185.     {
  1186.         draw_polygon(&poly_array[i], x, y);
  1187.         x += 45;
  1188.         i++;
  1189.     }
  1190.     draw_polygon_int(&poly_array[i], 60, 150);
  1191. }
  1192.  
  1193. void draw_stuff()
  1194. {
  1195.     //draw_lines();
  1196.     //draw_polygons();
  1197.     //test_draw();
  1198.     //drawFilledTriangle(&poly_array[4]);
  1199.     drawShadedTriangle(&poly_array[5]);
  1200. }
  1201.  
  1202. void render()
  1203. {    
  1204.     // copy off-screen buffer to VGA memory
  1205.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  1206.  
  1207.     // clear off-screen buffer so the screen updates properly
  1208.     _fmemset(screen_buf, 0, SCREEN_SIZE);
  1209. }
  1210.  
  1211. void quit()
  1212. {  
  1213.     deinit_keyboard();
  1214.     set_mode(TEXT_MODE);
  1215. }
  1216.  
  1217. void main()
  1218. {  
  1219.     poly_array[0] = makeSquare(0.0, 10.0, 1.0, 44);
  1220.     poly_array[1] = makePolygon(0.0, 3, 15.0, 1.0, 47);
  1221.     poly_array[2] = makePolygon(0.0, 5, 25.0, 1.0, 47);
  1222.     poly_array[3] = makePolygon(0.0, 5, 25.0, 1.0, 47);
  1223.     poly_array[4] = makePolygon(0.0, 3, 15.0, 1.0, 47);
  1224.     poly_array[5] = makeShadedTriangle(0.0, 3, 15.0, 1.0, 16, 23, 31);
  1225.  
  1226.     load_font();
  1227.     set_mode(VGA_256_COLOR_MODE);
  1228.     init_keyboard();
  1229.    
  1230.     while (running == 1)
  1231.     {
  1232.         process_input();
  1233.         draw_stuff();
  1234.         render();
  1235.         delay(50);
  1236.     }
  1237.     quit();
  1238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement