source: libcaca/trunk/caca/driver_vga.c @ 2821

Last change on this file since 2821 was 2821, checked in by Sam Hocevar, 11 years ago

Starting refactoring to get rid of libcucul. The initial reason for the
split is rendered moot by the plugin system: when enabled, binaries do
not link directly with libX11 or libGL. I hope this is a step towards
more consisteny and clarity.

  • Property svn:keywords set to Id
File size: 4.2 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: driver_vga.c 2821 2008-09-27 13:12:46Z sam $
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/*
16 *  This file contains the libcaca VGA input and output driver
17 */
18
19#include "config.h"
20
21#if defined(USE_VGA)
22
23#include "caca.h"
24#include "caca_internals.h"
25
26/* Address of the VGA screen */
27#define VGA_SCREEN ((char *)(intptr_t)0x000b8000)
28
29static uint8_t const vga_colors[][4] =
30{
31    /* Colour values range from 0x00 to 0x3f */
32    { 0,      0x00, 0x00, 0x00 },
33    { 1,      0x00, 0x00, 0x1f },
34    { 2,      0x00, 0x1f, 0x00 },
35    { 3,      0x00, 0x1f, 0x1f },
36    { 4,      0x1f, 0x00, 0x00 },
37    { 5,      0x1f, 0x00, 0x1f },
38    { 0x14,   0x1f, 0x1f, 0x00 },
39    { 7,      0x1f, 0x1f, 0x1f },
40
41    { 0x38,   0x0f, 0x0f, 0x0f },
42    { 0x39,   0x0f, 0x0f, 0x3f },
43    { 0x3a,   0x0f, 0x3f, 0x0f },
44    { 0x3b,   0x0f, 0x3f, 0x3f },
45    { 0x3c,   0x3f, 0x0f, 0x0f },
46    { 0x3d,   0x3f, 0x0f, 0x3f },
47    { 0x3e,   0x3f, 0x3f, 0x0f },
48    { 0x3f,   0x3f, 0x3f, 0x3f },
49};
50
51static int vga_init_graphics(caca_display_t *dp)
52{
53    int i;
54    uint8_t tmp;
55
56    /* Blank screen */
57    memset(VGA_SCREEN, 0, 80 * 25 * 2);
58
59    /* Fill VGA palette */
60    for(i = 0; i < 16; i++)
61    {
62        outb(vga_colors[i][0], 0x3c8);
63        outb(vga_colors[i][1], 0x3c9);
64        outb(vga_colors[i][2], 0x3c9);
65        outb(vga_colors[i][3], 0x3c9);
66    }
67
68    /* Hide cursor */
69    outb(0x0a, 0x3d4);
70    tmp = inb(0x3d5);
71    tmp |= 0x20;
72    outb(0x0a, 0x3d4);
73    outb(tmp, 0x3d5);
74
75    /* We don't have much choice */
76    dp->resize.allow = 1;
77    caca_set_canvas_size(dp->cv, 80, 25);
78    dp->resize.allow = 0;
79
80    return 0;
81}
82
83static int vga_end_graphics(caca_display_t *dp)
84{
85    uint8_t tmp;
86
87    /* Show cursor again */
88    outb(0x0a, 0x3d4);
89    tmp = inb(0x3d5);
90    tmp &= 0xdf;
91    outb(0x0a, 0x3d4);
92    outb(tmp, 0x3d5);
93
94    return 0;
95}
96
97static int vga_set_display_title(caca_display_t *dp, char const *title)
98{
99    /* Unsupported, of course. */
100    return -1;
101}
102
103static int vga_get_display_width(caca_display_t const *dp)
104{
105    /* Fallback to a 320x200 screen */
106    return 320;
107}
108
109static int vga_get_display_height(caca_display_t const *dp)
110{
111    /* Fallback to a 320x200 screen */
112    return 200;
113}
114
115static void vga_display(caca_display_t *dp)
116{
117    char *screen = (char *)(intptr_t)0x000b8000;
118    uint32_t const *cvchars = (uint32_t const *)caca_get_canvas_chars(dp->cv);
119    uint32_t const *cvattrs = (uint32_t const *)caca_get_canvas_attrs(dp->cv);
120    int width = caca_get_canvas_width(dp->cv);
121    int height = caca_get_canvas_height(dp->cv);
122    int n;
123
124    for(n = height * width; n--; )
125    {
126        char ch = caca_utf32_to_cp437(*cvchars++);
127        if(n && *cvchars == CACA_MAGIC_FULLWIDTH)
128        {
129            *screen++ = '[';
130            *screen++ = caca_attr_to_ansi(*cvattrs++);
131            ch = ']';
132            cvchars++;
133            n--;
134        }
135        *screen++ = ch;
136        *screen++ = caca_attr_to_ansi(*cvattrs++);
137    }
138}
139
140static void vga_handle_resize(caca_display_t *dp)
141{
142    /* We know nothing about our window */
143    dp->resize.w = caca_get_canvas_width(dp->cv);
144    dp->resize.h = caca_get_canvas_height(dp->cv);
145}
146
147static int vga_get_event(caca_display_t *dp, caca_privevent_t *ev)
148{
149    /* FIXME */
150    ev->type = CACA_EVENT_NONE;
151    return 0;
152}
153
154/*
155 * Driver initialisation
156 */
157
158int vga_install(caca_display_t *dp)
159{
160    dp->drv.id = CACA_DRIVER_VGA;
161    dp->drv.driver = "vga";
162
163    dp->drv.init_graphics = vga_init_graphics;
164    dp->drv.end_graphics = vga_end_graphics;
165    dp->drv.set_display_title = vga_set_display_title;
166    dp->drv.get_display_width = vga_get_display_width;
167    dp->drv.get_display_height = vga_get_display_height;
168    dp->drv.display = vga_display;
169    dp->drv.handle_resize = vga_handle_resize;
170    dp->drv.get_event = vga_get_event;
171    dp->drv.set_mouse = NULL;
172    dp->drv.set_cursor = NULL;
173
174    return 0;
175}
176
177#endif /* USE_VGA */
178
Note: See TracBrowser for help on using the repository browser.