~ubuntu-core-dev/usplash/ubuntu

« back to all changes in this revision

Viewing changes to bogl/bogl-cfb.h

  • Committer: Scott James Remnant
  • Date: 2006-06-09 15:01:23 UTC
  • Revision ID: scott@netsplit.com-20060609150123-fee9f1bc83d30884
import 0.3-1 into bzr

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BOGL - Ben's Own Graphics Library.
 
2
   Written by Ben Pfaff <pfaffben@debian.org>.
 
3
 
 
4
   This program is free software; you can redistribute it and/or
 
5
   modify it under the terms of the GNU General Public License as
 
6
   published by the Free Software Foundation; either version 2 of the
 
7
   License, or (at your option) any later version.
 
8
   
 
9
   This program is distributed in the hope that it will be useful, but
 
10
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
   General Public License for more details.
 
13
   
 
14
   You should have received a copy of the GNU General Public License
 
15
   along with this program; if not, write to the Free Software
 
16
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
17
   USA. */
 
18
 
 
19
/* bogl-cfb.h: Common inline functions and data structures used by the
 
20
   packed-pixel drivers.  This should be considered an internal,
 
21
   private header file.
 
22
 
 
23
   Written by David Huggins-Daines <dhd@debian.org> */
 
24
 
 
25
#include <sys/types.h>
 
26
#include <string.h>
 
27
#include <endian.h>
 
28
 
 
29
struct bits4 {
 
30
  unsigned int p0:4 __attribute__ ((packed));
 
31
  unsigned int p1:4 __attribute__ ((packed));
 
32
} __attribute__ ((packed));
 
33
 
 
34
struct bits24 {
 
35
  unsigned char bytes[3]  __attribute__ ((packed));
 
36
} __attribute__ ((packed));
 
37
 
 
38
static inline unsigned int
 
39
get_var (volatile void* src, size_t off, size_t b)
 
40
{
 
41
  unsigned int c;
 
42
  switch (b)
 
43
      {
 
44
      case 32:
 
45
        /* FIXME: probably has endianness problems */
 
46
        return ((u_int32_t*)(src))[off];
 
47
      case 24:
 
48
        /* FIXME: probably also has endianness problems */
 
49
        c  = ((struct bits24*)(src))[off].bytes[2] << 16;
 
50
        c += ((struct bits24*)(src))[off].bytes[1] << 8;
 
51
        c += ((struct bits24*)(src))[off].bytes[0];
 
52
        return c;
 
53
      case 16:
 
54
        return ((unsigned short*)(src))[off];
 
55
      case 8:
 
56
        return ((unsigned char*)(src))[off];
 
57
      case 4:
 
58
        if (off % 2)
 
59
          return ((struct bits4*)(src))[off/2].p1;
 
60
        else
 
61
          return ((struct bits4*)(src))[off/2].p0;
 
62
      }
 
63
  return 0;
 
64
}
 
65
 
 
66
static inline void
 
67
put_var (volatile void* dst, size_t off, unsigned int c, size_t b)
 
68
{
 
69
  switch (b)
 
70
      {
 
71
      case 32:
 
72
        /* FIXME: probably has endianness problems */
 
73
        ((u_int32_t*)(dst))[off] = c;
 
74
        break;
 
75
      case 24:
 
76
        /* FIXME: probably also has endianness problems */
 
77
        ((struct bits24*)(dst))[off].bytes[2] = (c >> 16);
 
78
        ((struct bits24*)(dst))[off].bytes[1] = (c >> 8);
 
79
        ((struct bits24*)(dst))[off].bytes[0] = c;
 
80
        break;
 
81
      case 16:
 
82
        ((unsigned short*)(dst))[off] = c;
 
83
        break;
 
84
      case 8:
 
85
        ((unsigned char*)(dst))[off] = c;
 
86
        break;
 
87
      case 4:
 
88
        if (off % 2)
 
89
          ((struct bits4*)(dst))[off/2].p1 = c;
 
90
        else
 
91
          ((struct bits4*)(dst))[off/2].p0 = c;
 
92
        break;
 
93
      }
 
94
}
 
95
 
 
96
static inline void*
 
97
memset_24(void* d, unsigned int c, size_t len, size_t b)
 
98
{
 
99
  unsigned char* dst = d;
 
100
 
 
101
  if (len > 8)
 
102
    {
 
103
      /* We have to use a block of 3 regardless of the sizeof(int) */
 
104
      unsigned int block[3];
 
105
      const unsigned int bsiz = sizeof(unsigned int);
 
106
      ssize_t xlen;
 
107
      
 
108
      /* Yes we have to do it this way due to little-endian brain
 
109
         damage */
 
110
      put_var (block, 0, c, 24);
 
111
      put_var (block, 1, c, 24);
 
112
      put_var (block, 2, c, 24);
 
113
      put_var (block, 3, c, 24);
 
114
      
 
115
      if (sizeof(unsigned int) == 8)
 
116
        {
 
117
          put_var (block, 4, c, 24);
 
118
          put_var (block, 5, c, 24);
 
119
          put_var (block, 6, c, 24);
 
120
          put_var (block, 7, c, 24);
 
121
        }
 
122
 
 
123
      /* Align to an int boundary */
 
124
      while ((unsigned int)dst % sizeof(unsigned int))
 
125
        {
 
126
          put_var(dst, 0, c, 24);
 
127
          dst += 3;
 
128
          len--;
 
129
        }
 
130
      
 
131
      xlen = len / bsiz;
 
132
      while (xlen)
 
133
        {
 
134
          
 
135
          ((unsigned int*)(dst))[0] = block[0];
 
136
          ((unsigned int*)(dst))[1] = block[1];
 
137
          ((unsigned int*)(dst))[2] = block[2];
 
138
          dst += sizeof(block);
 
139
          xlen--;
 
140
        }
 
141
      len %= bsiz;
 
142
    }
 
143
  
 
144
  /* Plot individual pixels */
 
145
  while (len--)
 
146
    {
 
147
      put_var(dst, 0, c, 24);
 
148
      dst += 3;
 
149
    }
 
150
  return dst;
 
151
}
 
152
 
 
153
static inline void*
 
154
memset_sub8(void* d, unsigned int c, ssize_t offset, size_t len, size_t b)
 
155
{
 
156
  unsigned char* dst = d;
 
157
  unsigned char fill;
 
158
  int i;
 
159
 
 
160
  /* Align to one byte */
 
161
  while (offset % (8 / b))
 
162
    {
 
163
      put_var (dst, offset, c, b);
 
164
      offset++;
 
165
      len--;
 
166
    }
 
167
  dst += offset * b / 8;
 
168
 
 
169
  /* Copy */
 
170
  for (i = 0; i*b < 8; i++)
 
171
    put_var (&fill, i, c, b);
 
172
  memset (dst, fill, len * b / 8);
 
173
  dst += len * b / 8;
 
174
 
 
175
  /* Align again */
 
176
  len %= 8 / b;
 
177
  for (i = 0; i < len; i++)
 
178
    {
 
179
      put_var (dst, i, c, b);
 
180
    }
 
181
  dst++;
 
182
 
 
183
  return dst;
 
184
}
 
185
 
 
186
void* memset_var(void* d, unsigned int c, ssize_t offset,
 
187
                 size_t len, size_t b);