]> 4ch.mooo.com Git - 16.git/blob - src/lib/modex16/16render.c
fixed ^^ still buggy but it works better now~
[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-1));\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 //getch();\r
107                 x=px;\r
108                 y=py;\r
109         }\r
110 //      _nfree(buff);\r
111 }\r
112 \r
113 void\r
114 oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
115 {\r
116         byte plane;\r
117         word px, py;\r
118         word offset;\r
119 \r
120         /* TODO Make this fast.  It's SLOOOOOOW */\r
121         for(plane=0; plane < 4; plane++) {\r
122                 modexSelectPlane(PLANE(plane+x));\r
123                 for(px = plane; px < bmp->width; px+=4) {\r
124                         offset=px;\r
125                         for(py=0; py<bmp->height; py++) {\r
126                         if(!sprite || bmp->data[offset])\r
127                                 page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
128                         offset+=bmp->width;\r
129                         }\r
130                 }\r
131         }\r
132 }\r
133 \r
134 //* normal versions *//\r
135 void\r
136 modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
137     /* draw the region (the entire freakin bitmap) */\r
138     modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
139 }\r
140 \r
141 void\r
142 modexDrawBmpRegion(page_t *page, int x, int y,\r
143                    int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
144         word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
145         byte *data = bmp->data;//+bmp->offset;\r
146         word bmpOffset = (word) data + ry * bmp->width + rx;\r
147         word width = rw;\r
148         word height = rh;\r
149         byte plane = 1 << ((byte) x & 0x03);\r
150         word scanCount = width/4 + (width%4 ? 1 :0);\r
151         word nextPageRow = page->width/4 - scanCount;\r
152         word nextBmpRow = (word) bmp->width - width;\r
153         word rowCounter;\r
154         byte planeCounter = 4;\r
155 \r
156     __asm {\r
157                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
158                 MOV ES, AX\r
159 \r
160                 MOV DX, SC_INDEX        ; point at the map mask register\r
161                 MOV AL, MAP_MASK        ;\r
162                 OUT DX, AL            ;\r
163 \r
164         PLANE_LOOP:\r
165                 MOV DX, SC_DATA  ; select the current plane\r
166                 MOV AL, plane      ;\r
167                 OUT DX, AL            ;\r
168 \r
169                 ;-- begin plane painting\r
170                 MOV AX, height    ; start the row counter\r
171                 MOV rowCounter, AX      ;\r
172                 MOV DI, poffset  ; go to the first pixel\r
173                 MOV SI, bmpOffset       ; go to the bmp pixel\r
174         ROW_LOOP:\r
175                 MOV CX, width      ; count the columns\r
176         SCAN_LOOP:\r
177                 MOVSB              ; copy the pixel\r
178                 SUB CX, 3              ; we skip the next 3\r
179                 ADD SI, 3              ; skip the bmp pixels\r
180                 LOOP SCAN_LOOP    ; finish the scan\r
181 \r
182                 MOV AX, nextPageRow\r
183                 ADD DI, AX            ; go to the next row on screen\r
184                 MOV AX, nextBmpRow\r
185                 ADD SI, AX            ; go to the next row on bmp\r
186 \r
187                 DEC rowCounter\r
188                 JNZ ROW_LOOP        ; do all the rows\r
189                 ;-- end plane painting\r
190                 MOV AL, plane      ; advance to the next plane\r
191                 SHL AL, 1              ;\r
192                 AND AL, 0x0f        ; mask the plane properly\r
193                 MOV plane, AL      ; store the plane\r
194 \r
195                 INC bmpOffset      ; start bmp at the right spot\r
196 \r
197                 DEC planeCounter\r
198                 JNZ PLANE_LOOP    ; do all 4 planes\r
199     }\r
200 }\r
201 \r
202 void\r
203 modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
204     /* draw the whole sprite */\r
205     modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
206 }\r
207 \r
208 void\r
209 modexDrawSpriteRegion(page_t *page, int x, int y,\r
210                       int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
211         word poffset = (word)page->data + y*(page->width/4) + x/4;\r
212         byte *data = bmp->data;//+bmp->offset;\r
213         word bmpOffset = (word) data + ry * bmp->width + rx;\r
214         word width = rw;\r
215         word height = rh;\r
216         byte plane = 1 << ((byte) x & 0x03);\r
217         word scanCount = width/4 + (width%4 ? 1 :0);\r
218         word nextPageRow = page->width/4 - scanCount;\r
219         word nextBmpRow = (word) bmp->width - width;\r
220         word rowCounter;\r
221         byte planeCounter = 4;\r
222 \r
223     __asm {\r
224                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
225                 MOV ES, AX\r
226 \r
227                 MOV DX, SC_INDEX        ; point at the map mask register\r
228                 MOV AL, MAP_MASK        ;\r
229                 OUT DX, AL            ;\r
230 \r
231         PLANE_LOOP:\r
232                 MOV DX, SC_DATA  ; select the current plane\r
233                 MOV AL, plane      ;\r
234                 OUT DX, AL            ;\r
235 \r
236                 ;-- begin plane painting\r
237                 MOV AX, height    ; start the row counter\r
238                 MOV rowCounter, AX      ;\r
239                 MOV DI, poffset  ; go to the first pixel\r
240                 MOV SI, bmpOffset       ; go to the bmp pixel\r
241         ROW_LOOP:\r
242                 MOV CX, width      ; count the columns\r
243         SCAN_LOOP:\r
244                 LODSB\r
245                 DEC SI\r
246                 CMP AL, 0\r
247                 JNE DRAW_PIXEL    ; draw non-zero pixels\r
248 \r
249                 INC DI            ; skip the transparent pixel\r
250                 ADD SI, 1\r
251                 JMP NEXT_PIXEL\r
252         DRAW_PIXEL:\r
253                 MOVSB              ; copy the pixel\r
254         NEXT_PIXEL:\r
255                 SUB CX, 3              ; we skip the next 3\r
256                 ADD SI, 3              ; skip the bmp pixels\r
257                 LOOP SCAN_LOOP    ; finish the scan\r
258 \r
259                 MOV AX, nextPageRow\r
260                 ADD DI, AX            ; go to the next row on screen\r
261                 MOV AX, nextBmpRow\r
262                 ADD SI, AX            ; go to the next row on bmp\r
263 \r
264                 DEC rowCounter\r
265                 JNZ ROW_LOOP        ; do all the rows\r
266                 ;-- end plane painting\r
267 \r
268                 MOV AL, plane      ; advance to the next plane\r
269                 SHL AL, 1              ;\r
270                 AND AL, 0x0f        ; mask the plane properly\r
271                 MOV plane, AL      ; store the plane\r
272 \r
273                 INC bmpOffset      ; start bmp at the right spot\r
274 \r
275                 DEC planeCounter\r
276                 JNZ PLANE_LOOP    ; do all 4 planes\r
277     }\r
278 }\r
279 \r
280 //* planar buffer versions *//\r
281 void\r
282 modexDrawBmpPBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
283     /* draw the region (the entire freakin bitmap) */\r
284     modexDrawBmpPBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
285 }\r
286 \r
287 void\r
288 modexDrawBmpPBufRegion(page_t *page, int x, int y,\r
289                    int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
290         word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
291         byte *data = bmp->plane[0];\r
292         word bmpOffset = (word) data + ry * bmp->width + rx;\r
293         word width = rw;\r
294         word height = rh;\r
295         byte plane = 1 << ((byte) x & 0x03);\r
296         word scanCount = width/4 + (width%4 ? 1 :0);\r
297         word nextPageRow = page->width/4 - scanCount;\r
298         word nextBmpRow = (word) bmp->width - width;\r
299         word rowCounter;\r
300         byte planeCounter = 4;\r
301 \r
302     __asm {\r
303                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
304                 MOV ES, AX\r
305 \r
306                 MOV DX, SC_INDEX        ; point at the map mask register\r
307                 MOV AL, MAP_MASK        ;\r
308                 OUT DX, AL            ;\r
309 \r
310         PLANE_LOOP:\r
311                 MOV DX, SC_DATA  ; select the current plane\r
312                 MOV AL, plane      ;\r
313                 OUT DX, AL            ;\r
314 \r
315                 ;-- begin plane painting\r
316                 MOV AX, height    ; start the row counter\r
317                 MOV rowCounter, AX      ;\r
318                 MOV DI, poffset  ; go to the first pixel\r
319                 MOV SI, bmpOffset       ; go to the bmp pixel\r
320         ROW_LOOP:\r
321                 MOV CX, width      ; count the columns\r
322         SCAN_LOOP:\r
323 \r
324 \r
325 \r
326 \r
327 \r
328 \r
329 \r
330 \r
331 \r
332                 MOVSB              ; copy the pixel\r
333 \r
334                 SUB CX, 3              ; we skip the next 3\r
335                 ADD SI, 3              ; skip the bmp pixels\r
336                 LOOP SCAN_LOOP    ; finish the scan\r
337 \r
338                 MOV AX, nextPageRow\r
339                 ADD DI, AX            ; go to the next row on screen\r
340                 MOV AX, nextBmpRow\r
341                 ADD SI, AX            ; go to the next row on bmp\r
342 \r
343                 DEC rowCounter\r
344                 JNZ ROW_LOOP        ; do all the rows\r
345                 ;-- end plane painting\r
346 \r
347                 MOV AL, plane      ; advance to the next plane\r
348                 SHL AL, 1              ;\r
349                 AND AL, 0x0f        ; mask the plane properly\r
350                 MOV plane, AL      ; store the plane\r
351 \r
352                 INC bmpOffset      ; start bmp at the right spot\r
353 \r
354                 DEC planeCounter\r
355                 JNZ PLANE_LOOP    ; do all 4 planes\r
356     }\r
357 }\r
358 \r
359 void\r
360 modexDrawSpritePBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
361     /* draw the whole sprite */\r
362     modexDrawSpritePBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
363 }\r
364 \r
365 void\r
366 modexDrawSpritePBufRegion(page_t *page, int x, int y,\r
367                       int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
368         word poffset = (word)page->data + y*(page->width/4) + x/4;\r
369         byte *data = bmp->plane[0];\r
370         word bmpOffset = (word) data + ry * bmp->width + rx;\r
371         word width = rw;\r
372         word height = rh;\r
373         byte plane = 1 << ((byte) x & 0x03);\r
374         word scanCount = width/4 + (width%4 ? 1 :0);\r
375         word nextPageRow = page->width/4 - scanCount;\r
376         word nextBmpRow = (word) bmp->width - width;\r
377         word rowCounter;\r
378         byte planeCounter = 4;\r
379 \r
380     __asm {\r
381                 MOV AX, SCREEN_SEG      ; go to the VGA memory\r
382                 MOV ES, AX\r
383 \r
384                 MOV DX, SC_INDEX        ; point at the map mask register\r
385                 MOV AL, MAP_MASK        ;\r
386                 OUT DX, AL            ;\r
387 \r
388         PLANE_LOOP:\r
389                 MOV DX, SC_DATA  ; select the current plane\r
390                 MOV AL, plane      ;\r
391                 OUT DX, AL            ;\r
392 \r
393                 ;-- begin plane painting\r
394                 MOV AX, height    ; start the row counter\r
395                 MOV rowCounter, AX      ;\r
396                 MOV DI, poffset  ; go to the first pixel\r
397                 MOV SI, bmpOffset       ; go to the bmp pixel\r
398         ROW_LOOP:\r
399                 MOV CX, width      ; count the columns\r
400         SCAN_LOOP:\r
401                 LODSB\r
402                 DEC SI\r
403                 CMP AL, 0\r
404                 JNE DRAW_PIXEL    ; draw non-zero pixels\r
405 \r
406                 INC DI            ; skip the transparent pixel\r
407                 ADD SI, 1\r
408                 JMP NEXT_PIXEL\r
409         DRAW_PIXEL:\r
410                 MOVSB              ; copy the pixel\r
411         NEXT_PIXEL:\r
412                 SUB CX, 3              ; we skip the next 3\r
413                 ADD SI, 3              ; skip the bmp pixels\r
414                 LOOP SCAN_LOOP    ; finish the scan\r
415 \r
416                 MOV AX, nextPageRow\r
417                 ADD DI, AX            ; go to the next row on screen\r
418                 MOV AX, nextBmpRow\r
419                 ADD SI, AX            ; go to the next row on bmp\r
420 \r
421                 DEC rowCounter\r
422                 JNZ ROW_LOOP        ; do all the rows\r
423                 ;-- end plane painting\r
424 \r
425                 MOV AL, plane      ; advance to the next plane\r
426                 SHL AL, 1              ;\r
427                 AND AL, 0x0f        ; mask the plane properly\r
428                 MOV plane, AL      ; store the plane\r
429 \r
430                 INC bmpOffset      ; start bmp at the right spot\r
431 \r
432                 DEC planeCounter\r
433                 JNZ PLANE_LOOP    ; do all 4 planes\r
434     }\r
435 }\r