You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 19 години
преди 18 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
преди 19 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * libcaca Colour ASCII-Art library
  3. * Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * This file contains the libcaca VGA input and output driver
  16. */
  17. #include "config.h"
  18. #if defined(USE_VGA)
  19. #include "caca.h"
  20. #include "caca_internals.h"
  21. /* Address of the VGA screen */
  22. #define VGA_SCREEN ((char *)(intptr_t)0x000b8000)
  23. static uint8_t const vga_colors[][4] =
  24. {
  25. /* Colour values range from 0x00 to 0x3f */
  26. { 0, 0x00, 0x00, 0x00 },
  27. { 1, 0x00, 0x00, 0x1f },
  28. { 2, 0x00, 0x1f, 0x00 },
  29. { 3, 0x00, 0x1f, 0x1f },
  30. { 4, 0x1f, 0x00, 0x00 },
  31. { 5, 0x1f, 0x00, 0x1f },
  32. { 0x14, 0x1f, 0x1f, 0x00 },
  33. { 7, 0x1f, 0x1f, 0x1f },
  34. { 0x38, 0x0f, 0x0f, 0x0f },
  35. { 0x39, 0x0f, 0x0f, 0x3f },
  36. { 0x3a, 0x0f, 0x3f, 0x0f },
  37. { 0x3b, 0x0f, 0x3f, 0x3f },
  38. { 0x3c, 0x3f, 0x0f, 0x0f },
  39. { 0x3d, 0x3f, 0x0f, 0x3f },
  40. { 0x3e, 0x3f, 0x3f, 0x0f },
  41. { 0x3f, 0x3f, 0x3f, 0x3f },
  42. };
  43. static int vga_init_graphics(caca_display_t *dp)
  44. {
  45. int i;
  46. uint8_t tmp;
  47. /* Blank screen */
  48. memset(VGA_SCREEN, 0, 80 * 25 * 2);
  49. /* Fill VGA palette */
  50. for(i = 0; i < 16; i++)
  51. {
  52. outb(vga_colors[i][0], 0x3c8);
  53. outb(vga_colors[i][1], 0x3c9);
  54. outb(vga_colors[i][2], 0x3c9);
  55. outb(vga_colors[i][3], 0x3c9);
  56. }
  57. /* Hide cursor */
  58. outb(0x0a, 0x3d4);
  59. tmp = inb(0x3d5);
  60. tmp |= 0x20;
  61. outb(0x0a, 0x3d4);
  62. outb(tmp, 0x3d5);
  63. caca_add_dirty_rect(dp->cv, 0, 0, dp->cv->width, dp->cv->height);
  64. dp->resize.allow = 1;
  65. caca_set_canvas_size(dp->cv, 80, 25); /* We don't have much choice */
  66. dp->resize.allow = 0;
  67. return 0;
  68. }
  69. static int vga_end_graphics(caca_display_t *dp)
  70. {
  71. uint8_t tmp;
  72. /* Show cursor again */
  73. outb(0x0a, 0x3d4);
  74. tmp = inb(0x3d5);
  75. tmp &= 0xdf;
  76. outb(0x0a, 0x3d4);
  77. outb(tmp, 0x3d5);
  78. return 0;
  79. }
  80. static int vga_set_display_title(caca_display_t *dp, char const *title)
  81. {
  82. /* Unsupported, of course. */
  83. return -1;
  84. }
  85. static int vga_get_display_width(caca_display_t const *dp)
  86. {
  87. /* Fallback to a 320x200 screen */
  88. return 320;
  89. }
  90. static int vga_get_display_height(caca_display_t const *dp)
  91. {
  92. /* Fallback to a 320x200 screen */
  93. return 200;
  94. }
  95. static void vga_display(caca_display_t *dp)
  96. {
  97. int x, y, i;
  98. for(i = 0; i < caca_get_dirty_rectangle_count(dp->cv); i++)
  99. {
  100. char *screen = (char *)(intptr_t)0x000b8000;
  101. uint32_t const *cvchars, *cvattrs;
  102. int dx, dy, dw, dh;
  103. caca_get_dirty_rect(dp->cv, i, &dx, &dy, &dw, &dh);
  104. cvchars = (uint32_t const *)caca_get_canvas_chars(dp->cv)
  105. + dx + dy * dp->cv->width;
  106. cvattrs = (uint32_t const *)caca_get_canvas_attrs(dp->cv)
  107. + dx + dy * dp->cv->width;
  108. screen += dy * dp->cv->width + dx;
  109. for(y = dy; y < dy + dh; y++)
  110. {
  111. for(x = dx; x < dx + dw; x++)
  112. {
  113. char ch = caca_utf32_to_cp437(*cvchars++);
  114. if(x < dx + dw - 1 && *cvchars == CACA_MAGIC_FULLWIDTH)
  115. {
  116. *screen++ = '[';
  117. *screen++ = caca_attr_to_ansi(*cvattrs++);
  118. ch = ']';
  119. cvchars++;
  120. x++;
  121. }
  122. *screen++ = ch;
  123. *screen++ = caca_attr_to_ansi(*cvattrs++);
  124. }
  125. cvchars += dp->cv->width - dw;
  126. cvattrs += dp->cv->width - dw;
  127. screen += 2 * (dp->cv->width - dw);
  128. }
  129. }
  130. }
  131. static void vga_handle_resize(caca_display_t *dp)
  132. {
  133. /* We know nothing about our window */
  134. dp->resize.w = caca_get_canvas_width(dp->cv);
  135. dp->resize.h = caca_get_canvas_height(dp->cv);
  136. }
  137. static int vga_get_event(caca_display_t *dp, caca_privevent_t *ev)
  138. {
  139. /* FIXME */
  140. ev->type = CACA_EVENT_NONE;
  141. return 0;
  142. }
  143. /*
  144. * Driver initialisation
  145. */
  146. int vga_install(caca_display_t *dp)
  147. {
  148. dp->drv.id = CACA_DRIVER_VGA;
  149. dp->drv.driver = "vga";
  150. dp->drv.init_graphics = vga_init_graphics;
  151. dp->drv.end_graphics = vga_end_graphics;
  152. dp->drv.set_display_title = vga_set_display_title;
  153. dp->drv.get_display_width = vga_get_display_width;
  154. dp->drv.get_display_height = vga_get_display_height;
  155. dp->drv.display = vga_display;
  156. dp->drv.handle_resize = vga_handle_resize;
  157. dp->drv.get_event = vga_get_event;
  158. dp->drv.set_mouse = NULL;
  159. dp->drv.set_cursor = NULL;
  160. return 0;
  161. }
  162. #endif /* USE_VGA */