1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/lib/src/2d/RCS/fl8rsd8.c $
21 * $Revision: 1.6 $
22 * $Author: kevin $
23 * $Date: 1994/10/27 18:26:56 $
24 *
25 * Routines for drawing rsd bitmaps into a flat 8 canvas.
26 *
27 * This file is part of the 2d library.
28 *
29 * $Log: fl8rsd8.c $
30 * Revision 1.6 1994/10/27 18:26:56 kevin
31 * fixed gr_rsd8_blit prototype.
32 *
33 * Revision 1.5 1994/10/25 15:13:14 kevin
34 * Renamed funcs, use fast rsd blitter when possible.
35 *
36 * Revision 1.4 1993/10/19 09:50:54 kaboom
37 * Replaced #include <grd.h" with new headers split from grd.h.
38 *
39 * Revision 1.3 1993/10/01 16:00:47 kaboom
40 * Converted to include clpcon.h instead of clip.h
41 *
42 * Revision 1.2 1993/07/13 17:47:13 kaboom
43 * Fixed bugs in clipping case off right edge. Updated for padded clipping
44 * rectangle.
45 *
46 * Revision 1.1 1993/02/16 14:17:21 kaboom
47 * Initial revision
48 *
49 ********************************************************************
50 * Log from old flat8.c:
51 * Revision 1.7 1992/12/14 18:08:40 kaboom
52 * Fixed bug in flat8_rsd8_[u]bitmap() -- were omitting bottom lines.
53 */
54
55 #include "clpcon.h"
56 #include "cnvdat.h"
57 #include "fl8tf.h"
58 #include "general.h"
59 #include "grdbm.h"
60 #include "lg.h"
61 #include "rsd.h"
62 #include <string.h>
63
64 // prototypes
65 void gr_rsd8_blit(uchar *rsd_src, uchar *dst, int grd_bm_row, int bm_w);
66
67 //### MLA- not supposed to be used (PC code is in RSDBLT.ASM)
gr_rsd8_blit(uchar * rsd_src,uchar * dst,int grd_bm_row,int bm_w)68 void gr_rsd8_blit(uchar *rsd_src, uchar *dst, int grd_bm_row, int bm_w) {
69 DEBUG("%s: ask mark", __FUNCTION__);
70 }
71
gri_flat8_rsd8_ubitmap(grs_bitmap * bm,short x,short y)72 void gri_flat8_rsd8_ubitmap(grs_bitmap *bm, short x, short y) {
73 /* uchar *p_dst;
74 uchar *rsd_src; // rsd source buffer
75
76 rsd_src = bm->bits;
77 p_dst = grd_bm.bits + grd_bm.row*y + x;
78 gr_rsd8_blit(rsd_src,p_dst,grd_bm.row,bm->w);*/
79 unpack_rsd8_ubitmap(bm, x, y);
80 }
81
gri_flat8_rsd8_bitmap(grs_bitmap * bm,short x_left,short y_top)82 int gri_flat8_rsd8_bitmap(grs_bitmap *bm, short x_left, short y_top) {
83 short x, y; /* current destination position */
84 short x_right, y_bot; /* opposite edges of bitmap */
85 short x_off, y_off; /* x,y offset for clip */
86 ulong start_byte; /* byte to start drawing */
87 ulong cur_byte; /* current position within rsd */
88 uchar *p_dst;
89 uchar *rsd_src; /* rsd source buffer */
90 short rsd_code; /* last rsd opcode */
91 short rsd_count; /* count for last opcode */
92 short op_count; /* operational count */
93 int code; /* clip code to return */
94
95 rsd_src = bm->bits;
96 x = x_left;
97 y = y_top;
98 x_off = y_off = cur_byte = rsd_count = 0;
99 x_right = x_left + bm->w;
100 y_bot = y_top + bm->h;
101
102 /* clip bitmap to rectangular clipping window. */
103 if (x_left > grd_clip.right || x_right <= grd_clip.left || y_top > grd_clip.bot || y_bot <= grd_clip.top)
104 /* completely clipped, forget it. */
105 return CLIP_ALL;
106
107 code = CLIP_NONE;
108 if (x_left < grd_clip.left) {
109 /* clipped off left edge. */
110 x_off = grd_clip.left - x_left;
111 x = grd_clip.left;
112 code |= CLIP_LEFT;
113 }
114 if (y < grd_clip.top) {
115 /* clipped off top edge. */
116 y_off = grd_clip.top - y_top;
117 y = grd_clip.top;
118 code |= CLIP_TOP;
119 }
120 if (x_right >= grd_clip.right) {
121 /* clipped off right edge. */
122 x_right = grd_clip.right;
123 code |= CLIP_RIGHT;
124 }
125 if (y_bot > grd_clip.bot) {
126 /* clipped off bottom edge. */
127 y_bot = grd_clip.bot;
128 code |= CLIP_BOT;
129 }
130
131 if (code == CLIP_NONE) {
132 gr_ubitmap(bm, x_left, y_top);
133 return CLIP_NONE;
134 }
135
136 if (y_off > 0 || x_off > 0) {
137 /* been clipped of left and/or top, so we need to skip from beginning
138 of rsd buffer to be at x_off,y_off within rsd bitmap. */
139 start_byte = y_off * bm->row + x_off;
140 while (cur_byte < start_byte) {
141 if (rsd_count == 0)
142 /* no pending opcodes, get a new one. */
143 RSD_GET_TOKEN();
144 if (cur_byte + rsd_count <= start_byte) {
145 /* current code doesn't hit start_byte yet, so skip all of it. */
146 switch (rsd_code) {
147 case RSD_RUN:
148 /* advance past 1 byte of run color. */
149 rsd_src++;
150 break;
151 case RSD_SKIP:
152 break;
153 default: /* RSD_DUMP */
154 /* advance past rsd_count bytes of dump pixel data. */
155 rsd_src += rsd_count;
156 break;
157 }
158 cur_byte += rsd_count;
159 rsd_count = 0;
160 } else {
161 /* current code goes past start_byte, so skip only enough to get
162 to start_byte. */
163 op_count = start_byte - cur_byte;
164 switch (rsd_code) {
165 case RSD_RUN:
166 break;
167 case RSD_SKIP:
168 break;
169 default: /* RSD_DUMP */
170 rsd_src += op_count;
171 break;
172 }
173 cur_byte += op_count;
174 rsd_count -= op_count;
175 }
176 }
177 }
178
179 p_dst = grd_bm.bits + y * grd_bm.row + x;
180
181 /* process each scanline in two chunks. the first is the clipped section
182 from the right edge, wrapping around to to the left. the second is the
183 unclipped area in the middle. */
184 while (y < y_bot) {
185 /* clipped section. */
186 while (x < x_left + x_off) {
187 if (rsd_count == 0)
188 RSD_GET_TOKEN();
189 if (x + rsd_count <= x_left + x_off) {
190 switch (rsd_code) {
191 case RSD_RUN:
192 rsd_src++;
193 break;
194 case RSD_SKIP:
195 break;
196 default: /* RSD_DUMP */
197 rsd_src += rsd_count;
198 break;
199 }
200 x += rsd_count;
201 rsd_count = 0;
202 } else {
203 op_count = x_left + x_off - x;
204 switch (rsd_code) {
205 case RSD_RUN:
206 break;
207 case RSD_SKIP:
208 break;
209 default: /* RSD_DUMP */
210 rsd_src += op_count;
211 break;
212 }
213 rsd_count -= op_count;
214 x += op_count;
215 }
216 }
217
218 /* section to draw. */
219 while (x < x_right) {
220 if (rsd_count == 0)
221 RSD_GET_TOKEN();
222 if (x + rsd_count <= x_right) {
223 switch (rsd_code) {
224 case RSD_RUN:
225 LG_memset(p_dst, *rsd_src, rsd_count);
226 rsd_src++;
227 break;
228 case RSD_SKIP:
229 break;
230 default: /* RSD_DUMP */
231 LG_memcpy(p_dst, rsd_src, rsd_count);
232 rsd_src += rsd_count;
233 break;
234 }
235 x += rsd_count;
236 p_dst += rsd_count;
237 rsd_count = 0;
238 } else {
239 op_count = x_right - x;
240 switch (rsd_code) {
241 case RSD_RUN:
242 LG_memset(p_dst, *rsd_src, op_count);
243 break;
244 case RSD_SKIP:
245 break;
246 default: /* RSD_DUMP */
247 LG_memcpy(p_dst, rsd_src, op_count);
248 rsd_src += op_count;
249 break;
250 }
251 x += op_count;
252 p_dst += op_count;
253 rsd_count -= op_count;
254 }
255 }
256
257 /* reset x to be beginning of line and set y to next scanline. */
258 x -= bm->w;
259 p_dst += grd_bm.row - (x_right - x_left) + x_off;
260 y++;
261 }
262 rsd_done:
263 return code;
264 }
265