1 #include <rl_tile.h>
2 #include <rl_memory.h>
3 #include <rl_backgrnd.h>
4
5 #include <string.h>
6
7 #include <rl_endian.c>
8
rl_tileset_create(const void * data,size_t size)9 rl_tileset_t* rl_tileset_create( const void* data, size_t size )
10 {
11 union
12 {
13 const void* restrict v;
14 const uint16_t* restrict u16;
15 }
16 ptr;
17
18 ptr.v = data;
19
20 int width = ne16( *ptr.u16++ );
21 int height = ne16( *ptr.u16++ );
22 int num_tiles = ne16( *ptr.u16++ );
23
24 size -= 3 * sizeof( uint16_t );
25
26 rl_tileset_t* tileset = (rl_tileset_t*)rl_malloc( sizeof( rl_tileset_t ) + size );
27
28 if ( tileset )
29 {
30 tileset->width = width;
31 tileset->height = height;
32 tileset->size = width * height;
33 tileset->num_tiles = num_tiles;
34
35 uint16_t* restrict pixel = (uint16_t*)( (uint8_t*)tileset + sizeof( rl_tileset_t ) );
36
37 const uint16_t* restrict end = pixel + size / 2;
38
39 while ( pixel < end )
40 {
41 *pixel++ = ne16( *ptr.u16++ );
42 }
43
44 return tileset;
45 }
46
47 return NULL;
48 }
49
rl_tileset_blit_nobg(const rl_tileset_t * tileset,int index,int x,int y)50 void rl_tileset_blit_nobg( const rl_tileset_t* tileset, int index, int x, int y )
51 {
52 int width = tileset->width;
53 int height = tileset->height;
54 int size = tileset->size;
55
56 const uint16_t* pixels = tileset->data + size * index;
57 rl_tile_blit_nobg( width, height, pixels, x, y );
58 }
59
rl_tileset_blit(const rl_tileset_t * tileset,int index,int x,int y,uint16_t * bg)60 uint16_t* rl_tileset_blit( const rl_tileset_t* tileset, int index, int x, int y, uint16_t* bg )
61 {
62 int width = tileset->width;
63 int height = tileset->height;
64 int size = tileset->size;
65
66 const uint16_t* pixels = tileset->data + size * index;
67 return rl_tile_blit( width, height, pixels, x, y, bg );
68 }
69
rl_tileset_unblit(const rl_tileset_t * tileset,int x,int y,const uint16_t * bg)70 void rl_tileset_unblit( const rl_tileset_t* tileset, int x, int y, const uint16_t* bg )
71 {
72 int width = tileset->width;
73 int height = tileset->height;
74
75 rl_tile_unblit( width, height, x, y, bg );
76 }
77
rl_tile_blit_nobg(int width,int height,const uint16_t * pixels,int x,int y)78 void rl_tile_blit_nobg( int width, int height, const uint16_t* pixels, int x, int y )
79 {
80 int d_width, d_height;
81 uint16_t* restrict dest = rl_backgrnd_fb( &d_width, &d_height );
82
83 const uint16_t* restrict source = pixels;
84
85 int pitch = width;
86 int d_pitch = d_width + RL_BACKGRND_MARGIN;
87
88 if ( x < 0 )
89 {
90 width += x;
91 source -= x;
92 x = 0;
93 }
94
95 if ( x + width > d_width )
96 {
97 int out = x + width - d_width;
98 width -= out;
99 }
100
101 if ( y < 0 )
102 {
103 height += y;
104 source -= y * pitch;
105 y = 0;
106 }
107
108 if ( y + height > d_height )
109 {
110 int out = y + height - d_height;
111 height -= out;
112 }
113
114 if ( width > 0 && height > 0 )
115 {
116 dest += y * d_pitch + x;
117 width *= 2;
118
119 for ( int y = height; y > 0; --y )
120 {
121 memcpy( (void*)dest, (void*)source, width );
122
123 source += pitch;
124 dest += d_pitch;
125 }
126 }
127 }
128
rl_tile_blit(int width,int height,const uint16_t * pixels,int x,int y,uint16_t * bg)129 uint16_t* rl_tile_blit( int width, int height, const uint16_t* pixels, int x, int y, uint16_t* bg )
130 {
131 int d_width, d_height;
132 uint16_t* restrict dest = rl_backgrnd_fb( &d_width, &d_height );
133
134 const uint16_t* restrict source = pixels;
135
136 int pitch = width;
137 int d_pitch = d_width + RL_BACKGRND_MARGIN;
138
139 if ( x < 0 )
140 {
141 width += x;
142 source -= x;
143 x = 0;
144 }
145
146 if ( x + width > d_width )
147 {
148 int out = x + width - d_width;
149 width -= out;
150 }
151
152 if ( y < 0 )
153 {
154 height += y;
155 source -= y * pitch;
156 y = 0;
157 }
158
159 if ( y + height > d_height )
160 {
161 int out = y + height - d_height;
162 height -= out;
163 }
164
165 if ( width > 0 && height > 0 )
166 {
167 dest += y * d_pitch + x;
168
169 for ( int y = height; y > 0; --y )
170 {
171 memcpy( (void*)bg, (void*)dest, width * 2 );
172 memcpy( (void*)dest, (void*)source, width * 2 );
173
174 source += pitch;
175 dest += d_pitch;
176 }
177 }
178
179 return bg;
180 }
181
rl_tile_unblit(int width,int height,int x,int y,const uint16_t * bg)182 void rl_tile_unblit( int width, int height, int x, int y, const uint16_t* bg )
183 {
184 int d_width, d_height;
185 uint16_t* restrict dest = rl_backgrnd_fb( &d_width, &d_height );
186
187 int pitch = width;
188 int d_pitch = d_width + RL_BACKGRND_MARGIN;
189
190 if ( x < 0 )
191 {
192 width += x;
193 x = 0;
194 }
195
196 if ( x + width > d_width )
197 {
198 int out = x + width - d_width;
199 width -= out;
200 }
201
202 if ( y < 0 )
203 {
204 height += y;
205 y = 0;
206 }
207
208 if ( y + height > d_height )
209 {
210 int out = y + height - d_height;
211 height -= out;
212 }
213
214 if ( width > 0 && height > 0 )
215 {
216 dest += y * d_pitch + x;
217 width *= 2;
218
219 for ( int y = height; y > 0; --y )
220 {
221 memcpy( (void*)dest, (void*)bg, width );
222
223 dest += d_pitch;
224 bg += width;
225 }
226 }
227 }
228