]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16/16render.c
hmmm let me see what i did before wwww
[16.git] / src / lib / modex16 / 16render.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 /*\r
23  * Render data code~\r
24  */\r
25 \r
26 #include "src/lib/modex16/16render.h"\r
27 \r
28 //TODO! ADD CLIPPING!!\r
29 //memory management needs to be added\r
30 //void\r
31 //modexDrawBmpRegion    (page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp)\r
32 void modexDrawPBufRegion        (page_t *page, int x, int y, int rx, int ry, int rw, int rh, planar_buf_t *p, boolean sprite)\r
33 {\r
34         sword plane;\r
35         int i;\r
36         const int px=x;//-page->dx;\r
37         const int py=y;//-page->dy;\r
38         #define PEEE ((rw)/4)-rx\r
39         //-(rx/4)\r
40         #define PEEEE ((p->pwidth)*(ry))\r
41         //y=py;\r
42         //x=px;\r
43         //printf("%d,%d p(%d,%d) r(%d,%d) rwh(%d,%d)\n", x, y, px, py, rx, ry, rw, rh);\r
44         for(plane=0; plane < 4; plane++) {\r
45                 i=PEEE+PEEEE;\r
46                 //printf("PEEE=%d ", PEEE);\r
47                 //printf("PEEEE=%d ", PEEEE);\r
48                 //printf("i=%d\n", i);\r
49                 modexSelectPlane(PLANE(plane+x));\r
50                 for(; y < py+rh; y++) {\r
51                         //for(px=0; px < p->width; px++) {\r
52                                 //printf("%02X ", (int) p->plane[plane][i++]);\r
53 //                            _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
54 //                            printf("buff %u==%s\n", y, *buff);\r
55                                 _fmemcpy(page->data + (((page->width/4) * y) + (x / 4)), &(p->plane[plane][i+=p->pwidth]), (rw/4));\r
56                         //}\r
57                         //if(plane==3) IN_Ack();\r
58                 }\r
59                 /*printf("y%d=%d ", plane, y);\r
60                 if(plane==3) printf("y%d=%d\n", plane, y);*/\r
61                 x=px;\r
62                 y=py;\r
63                 }\r
64 }\r
65 \r
66 \r
67 /*temp*/\r
68 void\r
69 modexDrawPBuf(page_t *page, int x, int y, planar_buf_t *p, boolean sprite)\r
70 {\r
71         int plane;\r
72         int i;\r
73 //      byte near *buff;\r
74         const int px=x+page->dx;\r
75         const int py=y+page->dy;\r
76         x=px;\r
77         y=py;\r
78 //      buff = _nmalloc(p->pwidth+1);\r
79         // TODO Make this fast.  It's SLOOOOOOW\r
80 //      for(plane=0; plane < 4; plane++) {\r
81 //              i=0;\r
82 //              modexSelectPlane(PLANE(plane+x));\r
83 //              for(px = plane; px < p->width; px+=4) {\r
84 //                      offset=px;\r
85 //                      for(py=0; py<p->height/2; py++) {\r
86 //                              //SELECT_ALL_PLANES();\r
87 //                              if(!sprite || p->plane[offset])\r
88 //                                      page->data = &(p->plane[offset][i++]);\r
89 //                              offset+=p->width;\r
90 //                              offset++;\r
91 //                      }\r
92 //              }\r
93 //      }\r
94         for(plane=0; plane < 4; plane++) {\r
95                 i=0;\r
96                 modexSelectPlane(PLANE(plane+x));\r
97                 for(; y < py+p->height; y++) {\r
98                         //for(px=0; px < p->width; px++) {\r
99                                 //printf("%02X ", (int) p->plane[plane][i++]);\r
100 //                              _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
101 //                              printf("buff %u==%s\n", y, *buff);\r
102 //                              _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), buff, p->pwidth);\r
103                                 _fmemcpy(page->data + (((page->width/4) * y) + (x / 4)), &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
104                         //}\r
105                 }\r
106                 x=px;\r
107                 y=py;\r
108         }\r
109 //      _nfree(buff);\r
110 }\r
111 \r
112 void\r
113 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
114 {\r
115         byte plane;\r
116         word px, py;\r
117         word offset;\r
118 \r
119         /* TODO Make this fast.  It's SLOOOOOOW */\r
120         for(plane=0; plane < 4; plane++) {\r
121                 modexSelectPlane(PLANE(plane+x));\r
122                 for(px = plane; px < bmp->width; px+=4) {\r
123                         offset=px;\r
124                         for(py=0; py<bmp->height; py++) {\r
125                         if(!sprite || bmp->data[offset])\r
126                                 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
127                         offset+=bmp->width;\r
128                         }\r
129                 }\r
130         }\r
131 }\r
132 \r
133 //* normal versions *//\r
134 void\r
135 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
136     /* draw the region (the entire freakin bitmap) */\r
137     modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
138 }\r
139 \r
140 void\r
141 modexDrawBmpRegion(page_t *page, int x, int y,\r
142                    int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
143         word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
144         byte *data = bmp->data;//+bmp->offset;\r
145         word bmpOffset = (word) data + ry * bmp->width + rx;\r
146         word width = rw;\r
147         word height = rh;\r
148         byte plane = 1 << ((byte) x & 0x03);\r
149         word scanCount = width/4 + (width%4 ? 1 :0);\r
150         word nextPageRow = page->width/4 - scanCount;\r
151         word nextBmpRow = (word) bmp->width - width;\r
152         word rowCounter;\r
153         byte planeCounter = 4;\r
154 \r
155     __asm {\r
156                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
157                 MOV ES, AX\r
158 \r
159                 MOV DX, SC_INDEX        ; point at the map mask register\r
160                 MOV AL, MAP_MASK        ;\r
161                 OUT DX, AL            ;\r
162 \r
163         PLANE_LOOP:\r
164                 MOV DX, SC_DATA  ; select the current plane\r
165                 MOV AL, plane      ;\r
166                 OUT DX, AL            ;\r
167 \r
168                 ;-- begin plane painting\r
169                 MOV AX, height    ; start the row counter\r
170                 MOV rowCounter, AX      ;\r
171                 MOV DI, poffset  ; go to the first pixel\r
172                 MOV SI, bmpOffset       ; go to the bmp pixel\r
173         ROW_LOOP:\r
174                 MOV CX, width      ; count the columns\r
175         SCAN_LOOP:\r
176                 MOVSB              ; copy the pixel\r
177                 SUB CX, 3              ; we skip the next 3\r
178                 ADD SI, 3              ; skip the bmp pixels\r
179                 LOOP SCAN_LOOP    ; finish the scan\r
180 \r
181                 MOV AX, nextPageRow\r
182                 ADD DI, AX            ; go to the next row on screen\r
183                 MOV AX, nextBmpRow\r
184                 ADD SI, AX            ; go to the next row on bmp\r
185 \r
186                 DEC rowCounter\r
187                 JNZ ROW_LOOP        ; do all the rows\r
188                 ;-- end plane painting\r
189                 MOV AL, plane      ; advance to the next plane\r
190                 SHL AL, 1              ;\r
191                 AND AL, 0x0f        ; mask the plane properly\r
192                 MOV plane, AL      ; store the plane\r
193 \r
194                 INC bmpOffset      ; start bmp at the right spot\r
195 \r
196                 DEC planeCounter\r
197                 JNZ PLANE_LOOP    ; do all 4 planes\r
198     }\r
199 }\r
200 \r
201 void\r
202 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
203     /* draw the whole sprite */\r
204     modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
205 }\r
206 \r
207 void\r
208 modexDrawSpriteRegion(page_t *page, int x, int y,\r
209                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
210         word poffset = (word)page->data + y*(page->width/4) + x/4;\r
211         byte *data = bmp->data;//+bmp->offset;\r
212         word bmpOffset = (word) data + ry * bmp->width + rx;\r
213         word width = rw;\r
214         word height = rh;\r
215         byte plane = 1 << ((byte) x & 0x03);\r
216         word scanCount = width/4 + (width%4 ? 1 :0);\r
217         word nextPageRow = page->width/4 - scanCount;\r
218         word nextBmpRow = (word) bmp->width - width;\r
219         word rowCounter;\r
220         byte planeCounter = 4;\r
221 \r
222     __asm {\r
223                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
224                 MOV ES, AX\r
225 \r
226                 MOV DX, SC_INDEX        ; point at the map mask register\r
227                 MOV AL, MAP_MASK        ;\r
228                 OUT DX, AL            ;\r
229 \r
230         PLANE_LOOP:\r
231                 MOV DX, SC_DATA  ; select the current plane\r
232                 MOV AL, plane      ;\r
233                 OUT DX, AL            ;\r
234 \r
235                 ;-- begin plane painting\r
236                 MOV AX, height    ; start the row counter\r
237                 MOV rowCounter, AX      ;\r
238                 MOV DI, poffset  ; go to the first pixel\r
239                 MOV SI, bmpOffset       ; go to the bmp pixel\r
240         ROW_LOOP:\r
241                 MOV CX, width      ; count the columns\r
242         SCAN_LOOP:\r
243                 LODSB\r
244                 DEC SI\r
245                 CMP AL, 0\r
246                 JNE DRAW_PIXEL    ; draw non-zero pixels\r
247 \r
248                 INC DI            ; skip the transparent pixel\r
249                 ADD SI, 1\r
250                 JMP NEXT_PIXEL\r
251         DRAW_PIXEL:\r
252                 MOVSB              ; copy the pixel\r
253         NEXT_PIXEL:\r
254                 SUB CX, 3              ; we skip the next 3\r
255                 ADD SI, 3              ; skip the bmp pixels\r
256                 LOOP SCAN_LOOP    ; finish the scan\r
257 \r
258                 MOV AX, nextPageRow\r
259                 ADD DI, AX            ; go to the next row on screen\r
260                 MOV AX, nextBmpRow\r
261                 ADD SI, AX            ; go to the next row on bmp\r
262 \r
263                 DEC rowCounter\r
264                 JNZ ROW_LOOP        ; do all the rows\r
265                 ;-- end plane painting\r
266 \r
267                 MOV AL, plane      ; advance to the next plane\r
268                 SHL AL, 1              ;\r
269                 AND AL, 0x0f        ; mask the plane properly\r
270                 MOV plane, AL      ; store the plane\r
271 \r
272                 INC bmpOffset      ; start bmp at the right spot\r
273 \r
274                 DEC planeCounter\r
275                 JNZ PLANE_LOOP    ; do all 4 planes\r
276     }\r
277 }\r
278 \r
279 //* planar buffer versions *//\r
280 void\r
281 modexDrawBmpPBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
282     /* draw the region (the entire freakin bitmap) */\r
283     modexDrawBmpPBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
284 }\r
285 \r
286 void\r
287 modexDrawBmpPBufRegion(page_t *page, int x, int y,\r
288                    int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
289         word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
290         byte *data = bmp->plane[0];\r
291         word bmpOffset = (word) data + ry * bmp->width + rx;\r
292         word width = rw;\r
293         word height = rh;\r
294         byte plane = 1 << ((byte) x & 0x03);\r
295         word scanCount = width/4 + (width%4 ? 1 :0);\r
296         word nextPageRow = page->width/4 - scanCount;\r
297         word nextBmpRow = (word) bmp->width - width;\r
298         word rowCounter;\r
299         byte planeCounter = 4;\r
300 \r
301     __asm {\r
302                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
303                 MOV ES, AX\r
304 \r
305                 MOV DX, SC_INDEX        ; point at the map mask register\r
306                 MOV AL, MAP_MASK        ;\r
307                 OUT DX, AL            ;\r
308 \r
309         PLANE_LOOP:\r
310                 MOV DX, SC_DATA  ; select the current plane\r
311                 MOV AL, plane      ;\r
312                 OUT DX, AL            ;\r
313 \r
314                 ;-- begin plane painting\r
315                 MOV AX, height    ; start the row counter\r
316                 MOV rowCounter, AX      ;\r
317                 MOV DI, poffset  ; go to the first pixel\r
318                 MOV SI, bmpOffset       ; go to the bmp pixel\r
319         ROW_LOOP:\r
320                 MOV CX, width      ; count the columns\r
321         SCAN_LOOP:\r
322 \r
323 \r
324 \r
325 \r
326 \r
327 \r
328 \r
329 \r
330 \r
331                 MOVSB              ; copy the pixel\r
332 \r
333                 SUB CX, 3              ; we skip the next 3\r
334                 ADD SI, 3              ; skip the bmp pixels\r
335                 LOOP SCAN_LOOP    ; finish the scan\r
336 \r
337                 MOV AX, nextPageRow\r
338                 ADD DI, AX            ; go to the next row on screen\r
339                 MOV AX, nextBmpRow\r
340                 ADD SI, AX            ; go to the next row on bmp\r
341 \r
342                 DEC rowCounter\r
343                 JNZ ROW_LOOP        ; do all the rows\r
344                 ;-- end plane painting\r
345 \r
346                 MOV AL, plane      ; advance to the next plane\r
347                 SHL AL, 1              ;\r
348                 AND AL, 0x0f        ; mask the plane properly\r
349                 MOV plane, AL      ; store the plane\r
350 \r
351                 INC bmpOffset      ; start bmp at the right spot\r
352 \r
353                 DEC planeCounter\r
354                 JNZ PLANE_LOOP    ; do all 4 planes\r
355     }\r
356 }\r
357 \r
358 void\r
359 modexDrawSpritePBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
360     /* draw the whole sprite */\r
361     modexDrawSpritePBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
362 }\r
363 \r
364 void\r
365 modexDrawSpritePBufRegion(page_t *page, int x, int y,\r
366                       int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
367         word poffset = (word)page->data + y*(page->width/4) + x/4;\r
368         byte *data = bmp->plane[0];\r
369         word bmpOffset = (word) data + ry * bmp->width + rx;\r
370         word width = rw;\r
371         word height = rh;\r
372         byte plane = 1 << ((byte) x & 0x03);\r
373         word scanCount = width/4 + (width%4 ? 1 :0);\r
374         word nextPageRow = page->width/4 - scanCount;\r
375         word nextBmpRow = (word) bmp->width - width;\r
376         word rowCounter;\r
377         byte planeCounter = 4;\r
378 \r
379     __asm {\r
380                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
381                 MOV ES, AX\r
382 \r
383                 MOV DX, SC_INDEX        ; point at the map mask register\r
384                 MOV AL, MAP_MASK        ;\r
385                 OUT DX, AL            ;\r
386 \r
387         PLANE_LOOP:\r
388                 MOV DX, SC_DATA  ; select the current plane\r
389                 MOV AL, plane      ;\r
390                 OUT DX, AL            ;\r
391 \r
392                 ;-- begin plane painting\r
393                 MOV AX, height    ; start the row counter\r
394                 MOV rowCounter, AX      ;\r
395                 MOV DI, poffset  ; go to the first pixel\r
396                 MOV SI, bmpOffset       ; go to the bmp pixel\r
397         ROW_LOOP:\r
398                 MOV CX, width      ; count the columns\r
399         SCAN_LOOP:\r
400                 LODSB\r
401                 DEC SI\r
402                 CMP AL, 0\r
403                 JNE DRAW_PIXEL    ; draw non-zero pixels\r
404 \r
405                 INC DI            ; skip the transparent pixel\r
406                 ADD SI, 1\r
407                 JMP NEXT_PIXEL\r
408         DRAW_PIXEL:\r
409                 MOVSB              ; copy the pixel\r
410         NEXT_PIXEL:\r
411                 SUB CX, 3              ; we skip the next 3\r
412                 ADD SI, 3              ; skip the bmp pixels\r
413                 LOOP SCAN_LOOP    ; finish the scan\r
414 \r
415                 MOV AX, nextPageRow\r
416                 ADD DI, AX            ; go to the next row on screen\r
417                 MOV AX, nextBmpRow\r
418                 ADD SI, AX            ; go to the next row on bmp\r
419 \r
420                 DEC rowCounter\r
421                 JNZ ROW_LOOP        ; do all the rows\r
422                 ;-- end plane painting\r
423 \r
424                 MOV AL, plane      ; advance to the next plane\r
425                 SHL AL, 1              ;\r
426                 AND AL, 0x0f        ; mask the plane properly\r
427                 MOV plane, AL      ; store the plane\r
428 \r
429                 INC bmpOffset      ; start bmp at the right spot\r
430 \r
431                 DEC planeCounter\r
432                 JNZ PLANE_LOOP    ; do all 4 planes\r
433     }\r
434 }\r