@@ -40,16 +40,26 @@ uint32_t psx_gpu_read32(psx_gpu_t* gpu, uint32_t offset) {
4040 case 0x00 : {
4141 uint32_t data = 0x0 ;
4242
43- if (gpu -> c0_ysiz ) {
44- data = * (( uint32_t * )( & gpu -> vram [gpu -> c0_xpos + (gpu -> c0_ypos * 1024 )])) ;
43+ if (gpu -> c0_tsiz ) {
44+ data |= gpu -> vram [gpu -> c0_addr + (gpu -> c0_xcnt + ( gpu -> c0_ycnt * 1024 ))] ;
4545
46- gpu -> c0_xsiz -= 2 ;
47- gpu -> c0_xpos += 2 ;
46+ gpu -> c0_xcnt += 1 ;
4847
49- if (gpu -> c0_xsiz <= 0 ) {
50- gpu -> c0_ypos += 1 ;
51- gpu -> c0_ysiz -= 1 ;
48+ if (gpu -> c0_xcnt == gpu -> c0_xsiz ) {
49+ gpu -> c0_ycnt += 1 ;
50+ gpu -> c0_xcnt = 0 ;
5251 }
52+
53+ data |= gpu -> vram [gpu -> c0_addr + (gpu -> c0_xcnt + (gpu -> c0_ycnt * 1024 ))] << 16 ;
54+
55+ gpu -> c0_xcnt += 1 ;
56+
57+ if (gpu -> c0_xcnt == gpu -> c0_xsiz ) {
58+ gpu -> c0_ycnt += 1 ;
59+ gpu -> c0_xcnt = 0 ;
60+ }
61+
62+ gpu -> c0_tsiz -= 2 ;
5363 }
5464
5565 return data ;
@@ -94,11 +104,11 @@ int max(int x0, int x1) {
94104
95105#define EDGE (a , b , c ) ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x))
96106
97- uint16_t gpu_fetch_texel (psx_gpu_t * gpu , uint16_t tx , uint16_t ty , uint32_t tpx , uint32_t tpy ) {
107+ uint16_t gpu_fetch_texel (psx_gpu_t * gpu , uint16_t tx , uint16_t ty , uint32_t tpx , uint32_t tpy , int depth ) {
98108 tx = (tx & ~gpu -> texw_mx ) | (gpu -> texw_ox & gpu -> texw_mx );
99109 ty = (ty & ~gpu -> texw_my ) | (gpu -> texw_oy & gpu -> texw_my );
100110
101- switch (gpu -> texp_d ) {
111+ switch (depth ) {
102112 // 4-bit
103113 case 0 : {
104114 uint16_t texel = gpu -> vram [(tpx + (tx >> 2 )) + ((tpy + ty ) * 1024 )];
@@ -124,20 +134,82 @@ uint16_t gpu_fetch_texel(psx_gpu_t* gpu, uint16_t tx, uint16_t ty, uint32_t tpx,
124134 }
125135}
126136
127- void gpu_render_flat_line (psx_gpu_t * gpu , vertex_t v0 , vertex_t v1 , uint32_t color ) {
128- double l = 640.0 ;
137+ void plotLineLow (psx_gpu_t * gpu , int x0 , int y0 , int x1 , int y1 , uint16_t color ) {
138+ int dx = x1 - x0 ;
139+ int dy = y1 - y0 ;
140+ int yi = 1 ;
141+ if (dy < 0 ) {
142+ yi = -1 ;
143+ dy = - dy ;
144+ }
145+ int d = (2 * dy ) - dx ;
146+ int y = y0 ;
129147
130- for (double p = 0.0 ; p < 1.0 ; p += 1.0 / l ) {
131- unsigned int ax = (v0 .x * p ) + (v1 .x * (1.0f - p ));
132- unsigned int ay = (v0 .y * p ) + (v1 .y * (1.0f - p ));
148+ for (int x = x0 ; x < x1 ; x ++ ) {
149+ gpu -> vram [x + (y * 1024 )] = color ;
133150
134- if ((ax > 1024 ) || (ay > 512 ))
135- continue ;
151+ if (d > 0 ) {
152+ y += yi ;
153+ d += (2 * (dy - dx ));
154+ } else {
155+ d += 2 * dy ;
156+ }
157+ }
158+ }
136159
137- gpu -> vram [ax + (ay * 1024 )] = color ;
160+ void plotLineHigh (psx_gpu_t * gpu , int x0 , int y0 , int x1 , int y1 , uint16_t color ) {
161+ int dx = x1 - x0 ;
162+ int dy = y1 - y0 ;
163+ int xi = 1 ;
164+ if (dx < 0 ) {
165+ xi = -1 ;
166+ dx = - dx ;
167+ }
168+ int d = (2 * dx ) - dy ;
169+ int x = x0 ;
170+
171+ for (int y = y0 ; y < y1 ; y ++ ) {
172+ gpu -> vram [x + (y * 1024 )] = color ;
173+ if (d > 0 ) {
174+ x = x + xi ;
175+ d += (2 * (dx - dy ));
176+ } else {
177+ d += 2 * dx ;
178+ }
138179 }
139180}
140181
182+ void plotLine (psx_gpu_t * gpu , int x0 , int y0 , int x1 , int y1 , uint16_t color ) {
183+ if (abs (y1 - y0 ) < abs (x1 - x0 )) {
184+ if (x0 > x1 ) {
185+ plotLineLow (gpu , x1 , y1 , x0 , y0 , color );
186+ } else {
187+ plotLineLow (gpu , x0 , y0 , x1 , y1 , color );
188+ }
189+ } else {
190+ if (y0 > y1 ) {
191+ plotLineHigh (gpu , x1 , y1 , x0 , y0 , color );
192+ } else {
193+ plotLineHigh (gpu , x0 , y0 , x1 , y1 , color );
194+ }
195+ }
196+ }
197+
198+ void gpu_render_flat_line (psx_gpu_t * gpu , vertex_t v0 , vertex_t v1 , uint32_t color ) {
199+ plotLine (gpu , v0 .x , v0 .y , v1 .x , v1 .y , color );
200+ // double l = 640.0;
201+
202+ // for (double p = 0.0; p < 1.0; p += 1.0 / l) {
203+ // unsigned int ax = (v0.x * p) + (v1.x * (1.0f - p));
204+ // unsigned int ay = (v0.y * p) + (v1.y * (1.0f - p));
205+
206+ // if ((ax > 1024) || (ay > 512))
207+ // continue;
208+
209+ // gpu->vram[ax + (ay * 1024)] = color;
210+ // }
211+ }
212+
141213void gpu_render_flat_rectangle (psx_gpu_t * gpu , vertex_t v , uint32_t w , uint32_t h , uint32_t color ) {
142214 /* Offset coordinates */
143215 v .x += gpu -> off_x ;
@@ -171,7 +243,7 @@ void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint3
171243
172244 for (int y = ymin ; y < ymax ; y ++ ) {
173245 for (int x = xmin ; x < xmax ; x ++ ) {
174- uint16_t color = gpu_fetch_texel (gpu , a .tx + xc , a .ty + yc , tpx , tpy );
246+ uint16_t color = gpu_fetch_texel (gpu , a .tx + xc , a .ty + yc , tpx , tpy , gpu -> texp_d );
175247
176248 ++ xc ;
177249
@@ -298,7 +370,7 @@ void gpu_render_shaded_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex
298370 }
299371}
300372
301- void gpu_render_textured_triangle (psx_gpu_t * gpu , vertex_t v0 , vertex_t v1 , vertex_t v2 , uint32_t tpx , uint32_t tpy ) {
373+ void gpu_render_textured_triangle (psx_gpu_t * gpu , vertex_t v0 , vertex_t v1 , vertex_t v2 , uint32_t tpx , uint32_t tpy , int depth ) {
302374 vertex_t a , b , c ;
303375
304376 a = v0 ;
@@ -341,7 +413,7 @@ void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vert
341413 uint32_t tx = ((z0 * a .tx ) + (z1 * b .tx ) + (z2 * c .tx )) / area ;
342414 uint32_t ty = ((z0 * a .ty ) + (z1 * b .ty ) + (z2 * c .ty )) / area ;
343415
344- uint16_t color = gpu_fetch_texel (gpu , tx , ty , tpx , tpy );
416+ uint16_t color = gpu_fetch_texel (gpu , tx , ty , tpx , tpy , depth );
345417
346418 if (!color ) continue ;
347419
@@ -511,9 +583,9 @@ void gpu_cmd_2c(psx_gpu_t* gpu) {
511583 if (!gpu -> cmd_args_remaining ) {
512584 gpu -> state = GPU_STATE_RECV_DATA ;
513585
586+ uint32_t texp = gpu -> buf [4 ] >> 16 ;
514587 gpu -> color = gpu -> buf [0 ] & 0xffffff ;
515588 gpu -> pal = gpu -> buf [2 ] >> 16 ;
516- gpu -> texp = gpu -> buf [4 ] >> 16 ;
517589 gpu -> v0 .tx = gpu -> buf [2 ] & 0xff ;
518590 gpu -> v0 .ty = (gpu -> buf [2 ] >> 8 ) & 0xff ;
519591 gpu -> v1 .tx = gpu -> buf [4 ] & 0xff ;
@@ -534,11 +606,12 @@ void gpu_cmd_2c(psx_gpu_t* gpu) {
534606 gpu -> clut_x = (gpu -> pal & 0x3f ) << 4 ;
535607 gpu -> clut_y = (gpu -> pal >> 6 ) & 0x1ff ;
536608
537- uint32_t tpx = (gpu -> texp & 0xf ) << 6 ;
538- uint32_t tpy = (gpu -> texp & 0x10 ) << 4 ;
609+ uint32_t tpx = (texp & 0xf ) << 6 ;
610+ uint32_t tpy = (texp & 0x10 ) << 4 ;
611+ uint32_t depth = (texp >> 7 ) & 0x3 ;
539612
540- gpu_render_textured_triangle (gpu , gpu -> v0 , gpu -> v1 , gpu -> v2 , tpx , tpy );
541- gpu_render_textured_triangle (gpu , gpu -> v1 , gpu -> v2 , gpu -> v3 , tpx , tpy );
613+ gpu_render_textured_triangle (gpu , gpu -> v0 , gpu -> v1 , gpu -> v2 , tpx , tpy , depth );
614+ gpu_render_textured_triangle (gpu , gpu -> v1 , gpu -> v2 , gpu -> v3 , tpx , tpy , depth );
542615
543616 gpu -> state = GPU_STATE_RECV_CMD ;
544617 }
@@ -558,9 +631,9 @@ void gpu_cmd_2d(psx_gpu_t* gpu) {
558631 if (!gpu -> cmd_args_remaining ) {
559632 gpu -> state = GPU_STATE_RECV_DATA ;
560633
634+ uint32_t texp = gpu -> buf [4 ] >> 16 ;
561635 gpu -> color = gpu -> buf [0 ] & 0xffffff ;
562636 gpu -> pal = gpu -> buf [2 ] >> 16 ;
563- gpu -> texp = gpu -> buf [4 ] >> 16 ;
564637 gpu -> v0 .tx = gpu -> buf [2 ] & 0xff ;
565638 gpu -> v0 .ty = (gpu -> buf [2 ] >> 8 ) & 0xff ;
566639 gpu -> v1 .tx = gpu -> buf [4 ] & 0xff ;
@@ -581,11 +654,12 @@ void gpu_cmd_2d(psx_gpu_t* gpu) {
581654 gpu -> clut_x = (gpu -> pal & 0x3f ) << 4 ;
582655 gpu -> clut_y = (gpu -> pal >> 6 ) & 0x1ff ;
583656
584- uint32_t tpx = (gpu -> texp & 0xf ) << 6 ;
585- uint32_t tpy = (gpu -> texp & 0x10 ) << 4 ;
657+ uint32_t tpx = (texp & 0xf ) << 6 ;
658+ uint32_t tpy = (texp & 0x10 ) << 4 ;
659+ int depth = (texp >> 7 ) & 0x3 ;
586660
587- gpu_render_textured_triangle (gpu , gpu -> v0 , gpu -> v1 , gpu -> v2 , tpx , tpy );
588- gpu_render_textured_triangle (gpu , gpu -> v1 , gpu -> v2 , gpu -> v3 , tpx , tpy );
661+ gpu_render_textured_triangle (gpu , gpu -> v0 , gpu -> v1 , gpu -> v2 , tpx , tpy , depth );
662+ gpu_render_textured_triangle (gpu , gpu -> v1 , gpu -> v2 , gpu -> v3 , tpx , tpy , depth );
589663
590664 gpu -> state = GPU_STATE_RECV_CMD ;
591665 }
@@ -687,10 +761,18 @@ void gpu_cmd_c0(psx_gpu_t* gpu) {
687761
688762 case GPU_STATE_RECV_ARGS : {
689763 if (!gpu -> cmd_args_remaining ) {
690- gpu -> c0_xpos = gpu -> buf [1 ] & 0xffff ;
691- gpu -> c0_ypos = gpu -> buf [1 ] >> 16 ;
764+ gpu -> c0_xcnt = 0 ;
765+ gpu -> c0_ycnt = 0 ;
766+ uint32_t c0_xpos = gpu -> buf [1 ] & 0xffff ;
767+ uint32_t c0_ypos = gpu -> buf [1 ] >> 16 ;
692768 gpu -> c0_xsiz = gpu -> buf [2 ] & 0xffff ;
693769 gpu -> c0_ysiz = gpu -> buf [2 ] >> 16 ;
770+ c0_xpos = c0_xpos & 0x3ff ;
771+ c0_ypos = c0_ypos & 0x1ff ;
772+ gpu -> c0_xsiz = ((gpu -> c0_xsiz - 1 ) & 0x3ff ) + 1 ;
773+ gpu -> c0_ysiz = ((gpu -> c0_ysiz - 1 ) & 0x1ff ) + 1 ;
774+ gpu -> c0_tsiz = ((gpu -> c0_xsiz * gpu -> c0_ysiz ) + 1 ) & 0xfffffffe ;
775+ gpu -> c0_addr = c0_xpos + (c0_ypos * 1024 );
694776
695777 gpu -> state = GPU_STATE_RECV_CMD ;
696778 }
@@ -720,12 +802,6 @@ void gpu_cmd_02(psx_gpu_t* gpu) {
720802 gpu -> xsiz = (((gpu -> xsiz & 0x3ff ) + 0x0f ) & 0xfffffff0 );
721803 gpu -> ysiz = gpu -> ysiz & 0x1ff ;
722804
723- log_fatal ("Render flat rectangle pos=(%u, %u) siz=(%u, %u), color=%02x" ,
724- gpu -> v0 .x , gpu -> v0 .y ,
725- gpu -> xsiz , gpu -> ysiz ,
726- gpu -> color
727- );
728-
729805 gpu -> v0 .x += gpu -> off_x ;
730806 gpu -> v0 .y += gpu -> off_y ;
731807
@@ -743,9 +819,12 @@ void psx_gpu_update_cmd(psx_gpu_t* gpu) {
743819 case 0x01 : /* Cache clear */ break ;
744820 case 0x02 : gpu_cmd_02 (gpu ); break ;
745821 case 0x28 : gpu_cmd_28 (gpu ); break ;
746- case 0x2c : gpu_cmd_2c (gpu ); break ;
822+ case 0x2c : gpu_cmd_2d (gpu ); break ;
747823 case 0x2d : gpu_cmd_2d (gpu ); break ;
824+ case 0x2e : gpu_cmd_2d (gpu ); break ;
825+ case 0x2f : gpu_cmd_2d (gpu ); break ;
748826 case 0x30 : gpu_cmd_30 (gpu ); break ;
827+ case 0x32 : gpu_cmd_30 (gpu ); break ;
749828 case 0x38 : gpu_cmd_38 (gpu ); break ;
750829 case 0x40 : gpu_cmd_40 (gpu ); break ;
751830 case 0x64 : gpu_cmd_64 (gpu ); break ;
0 commit comments