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