9 static int32_t mvmat[16];
10 static int32_t pmat[16];
12 static int dirty_x0, dirty_x1, dirty_y0, dirty_y1;
14 unsigned char *g3d_fbpixels;
15 int g3d_width, g3d_height;
22 memset(mvmat, 0, sizeof mvmat);
23 memset(pmat, 0, sizeof pmat);
24 mvmat[0] = mvmat[5] = mvmat[10] = mvmat[15] = 0x10000;
25 pmat[0] = pmat[5] = pmat[10] = pmat[15] = 0x10000;
30 void g3d_shutdown(void)
34 void g3d_framebuffer(int width, int height, void *fb)
47 void g3d_reset_dirty(void)
55 void blkclear(void *p, int len, int col);
56 #pragma aux blkclear = \
64 parm [edi] [ecx] [eax] \
67 extern volatile long nticks;
70 void g3d_clear_dirty(void)
75 if(dirty_x0 < 0) dirty_x0 = 0;
76 if(dirty_y0 < 0) dirty_y0 = 0;
77 if(dirty_x1 >= XRES) dirty_x1 = XRES - 1;
78 if(dirty_y1 >= YRES) dirty_y1 = YRES - 1;
80 nlines = dirty_y1 - dirty_y0;
81 if(dirty_y1 <= 0 || nlines >= YRES) {
82 blkclear(g3d_fbpixels, XRES * YRES, COL);
86 ptr = g3d_fbpixels + dirty_y0 * XRES;
87 if(dirty_x1 > XRES - 4) {
88 blkclear(ptr, nlines * XRES, COL);
92 ptr = (unsigned char*)((uintptr_t)(ptr + dirty_x0) & 0xfffffffc);
93 count = dirty_x1 + 3 - dirty_x0;
94 for(i=0; i<nlines; i++) {
95 blkclear(ptr, count, COL);
103 void vmemcopy(long fboffs, void *p, int len);
104 #pragma aux vmemcopy = \
109 parm [eax] [esi] [ecx] \
110 modify [ecx edi esi];
112 void g3d_copy_dirty(void)
114 int i, count, nlines;
115 unsigned long fboffs;
117 if(dirty_x0 < 0) dirty_x0 = 0;
118 if(dirty_y0 < 0) dirty_y0 = 0;
119 if(dirty_x1 >= XRES) dirty_x1 = XRES - 1;
120 if(dirty_y1 >= YRES) dirty_y1 = YRES - 1;
122 nlines = dirty_y1 - dirty_y0;
123 if(dirty_y1 <= 0 || nlines >= YRES) {
124 vmemcopy(0, g3d_fbpixels, XRES * YRES);
128 fboffs = dirty_y0 * XRES;
129 if(dirty_x1 > XRES - 4) {
130 vmemcopy(fboffs, g3d_fbpixels + fboffs, nlines * XRES);
134 fboffs += dirty_x0 & 0xfffffffc;
135 count = dirty_x1 + 3 - dirty_x0;
136 for(i=0; i<nlines; i++) {
137 vmemcopy(fboffs, g3d_fbpixels + fboffs, count);
142 void g3d_modelview(const int32_t *m)
144 memcpy(mvmat, m, sizeof mvmat);
147 void g3d_projection(const int32_t *m)
149 memcpy(pmat, m, sizeof pmat);
152 void g3d_color(int cidx)
157 static const int primverts[] = {1, 2, 3, 4};
159 void g3d_draw(int prim, struct g3d_vertex *varr, int vcount)
163 prim_vnum = primverts[prim];
165 for(i=0; i<vcount; i+=prim_vnum) {
166 g3d_draw_prim(prim, varr);
171 int32_t vpscale(int32_t x, int32_t s, int32_t shift);
172 #pragma aux vpscale = \
175 "shrd eax, edx, cl" \
176 parm [eax] [ebx] [ecx] \
181 void g3d_draw_prim(int prim, struct g3d_vertex *varr)
183 int i, vcount, x, y, x1, y1;
184 struct g3d_vertex v[4];
186 vcount = primverts[prim];
188 for(i=0; i<vcount; i++) {
191 /* transform to view space */
192 g3d_xform(v + i, mvmat);
194 /* transform to homogeneous clip space */
195 g3d_xform(v + i, pmat);
199 /* perspective division */
201 v[i].x = (v[i].x << 4) / (v[i].w >> 4);
202 v[i].y = (v[i].y << 4) / (v[i].w >> 4);
208 /* viewport transform */
209 v[i].x = vpscale(v[i].x, vp[2], 1) + (vp[0] << 8);
210 v[i].y = vpscale(-v[i].y, vp[3], 1) + (vp[1] << 8);
212 #if defined(USE_DIRTY_CLEAR) || defined(USE_DIRTY_COPY)
215 if(x - 4 < dirty_x0) dirty_x0 = x - 4;
216 if(y - 4 < dirty_y0) dirty_y0 = y - 4;
217 if(x + 8 > dirty_x1) dirty_x1 = x + 8;
218 if(y + 8 > dirty_y1) dirty_y1 = y + 8;
226 if(x >= 0 && y >= 0 && x < XRES && y < YRES) {
227 g3d_fbpixels[y * XRES + x] = g3d_curcidx;