283
|
1 #include <stdlib.h>
|
|
2 #include <string.h>
|
|
3 #include "DrawSpanRenew.h"
|
|
4 #include "polygon_pack.h"
|
|
5 #include "SpanPack.h"
|
|
6 #include "texture.h"
|
|
7 #include "viewer_types.h"
|
|
8 #include "Func.h"
|
|
9
|
|
10 #define SPAN_PACK_LOAD 0
|
|
11 #define TEX_LOAD 1
|
|
12 #define FB_STORE 2
|
|
13
|
|
14 SchedDefineTask(DrawSpanRenew);
|
|
15
|
|
16 void
|
|
17 DrawSpanRenew::reboot(SpanPackPtr spack, int cur_span_x)
|
|
18 {
|
|
19 TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
|
|
20
|
|
21 renew_task->add_param((int)args);
|
|
22
|
|
23 SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
|
|
24 memcpy(curr, spack, sizeof(SpanPack));
|
|
25 renew_task->add_param((int)curr);
|
|
26 renew_task->add_param(cur_span_x);
|
|
27
|
298
|
28 // linebuf と zRow も引き継がせる
|
283
|
29 renew_task->add_param((int)linebuf);
|
|
30 renew_task->add_param((int)zRow);
|
|
31
|
|
32 //fprintf(stderr, "[%p] start %u\n", curr, spu_readch(SPU_RdDec));
|
|
33
|
|
34 /**
|
298
|
35 * 再起動したタスクを待つ
|
283
|
36 */
|
|
37 smanager->wait_task(renew_task);
|
|
38
|
298
|
39 // next_spack は free() するので wait する
|
283
|
40 smanager->dma_wait(SPAN_PACK_LOAD);
|
|
41 }
|
|
42
|
|
43 int
|
|
44 DrawSpanRenew::run(void *rbuf, void *wbuf)
|
|
45 {
|
|
46 SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1);
|
|
47 SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
|
|
48 SpanPackPtr free_spack1 = spack;
|
|
49 SpanPackPtr free_spack2 = next_spack;
|
|
50 Span *span;
|
|
51
|
|
52 args = (DrawSpanArgPtr)smanager->get_param(0);
|
|
53 uint32 display = args->display;
|
|
54 int screen_width = args->screen_width;
|
|
55 int rangex_start = args->rangex_start;
|
|
56 int rangex_end = args->rangex_end;
|
|
57
|
298
|
58 // このタスクが担当する x の範囲
|
283
|
59 int rangex = rangex_end - rangex_start + 1;
|
|
60
|
298
|
61 // y の範囲 (render_y + rangey - 1)
|
283
|
62 int rangey = args->rangey;
|
|
63
|
|
64 hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
|
|
65 tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
|
|
66
|
|
67 linebuf = (int*)smanager->get_param(3);
|
|
68 zRow = (float*)smanager->get_param(4);
|
|
69
|
|
70 doneWrite = 0;
|
|
71
|
298
|
72 // span->length_x の処理での再起動位置
|
283
|
73 int js_cont = smanager->get_param(2);
|
|
74
|
|
75 //fprintf(stderr, "[%p] end %u\n", spack, spu_readch(SPU_RdDec));
|
|
76
|
|
77 smanager->dma_wait(TEX_LOAD);
|
|
78
|
|
79 do {
|
|
80 /**
|
298
|
81 * SpanPack->next が存在する場合、
|
|
82 * 現在の SpanPack を処理してる間に
|
|
83 * 次の SpanPack の DMA 転送を行う
|
283
|
84 */
|
|
85 if (spack->next != NULL) {
|
|
86 smanager->dma_load(next_spack, (uint32)spack->next,
|
|
87 sizeof(SpanPack), SPAN_PACK_LOAD);
|
|
88 } else {
|
|
89 next_spack = NULL;
|
|
90 }
|
|
91
|
|
92 for (int t = spack->info.start; t < spack->info.size; t++) {
|
|
93 span = &spack->span[t];
|
|
94
|
|
95 uint32 rgb = 0x00ff0000;
|
|
96 float tex1 = span->tex_x1;
|
|
97 float tex2 = span->tex_x2;
|
|
98 float tey1 = span->tex_y1;
|
|
99 float tey2 = span->tex_y2;
|
|
100
|
|
101 /**
|
298
|
102 * Span が持つ 1 pixel 毎の
|
|
103 * テクスチャの座標
|
283
|
104 */
|
|
105 int tex_xpos;
|
|
106 int tex_ypos;
|
|
107
|
|
108 /**
|
298
|
109 * (tex_xpos, tex_ypos) の、ブロック内(上の図参照)での座標と
|
|
110 * そのブロックのアドレス(MainMemory)
|
283
|
111 */
|
|
112 int tex_localx;
|
|
113 int tex_localy;
|
|
114 uint32 *tex_addr;
|
|
115
|
|
116 int x = span->x;
|
|
117 int y = span->y;
|
|
118 int x_len = span->length_x;
|
|
119 float z = span->start_z;
|
|
120 float zpos = span->end_z;
|
|
121
|
298
|
122 // 座標が [0 .. split_screen_w-1] に入るように x,y を -1
|
283
|
123 int localx = getLocalX(x-1);
|
|
124 int localy = getLocalY(y-1);
|
|
125
|
|
126 if (x_len == 1) {
|
|
127 if (x < rangex_start || rangex_end < x) {
|
|
128 continue;
|
|
129 }
|
|
130
|
|
131 tex_xpos = (int)((span->tex_width-1) * tex1);
|
|
132 tex_ypos = (int)((span->tex_height-1) * tey1);
|
|
133
|
|
134 if (zpos < zRow[localx + (rangex * localy)]) {
|
|
135 tex_addr = getTile(tex_xpos, tex_ypos,
|
|
136 span->tex_width, span->tex_addr);
|
|
137 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
|
|
138 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
|
|
139
|
|
140 if (!isAvailableTile(tex_addr)) {
|
|
141 set_rgb(tex_addr, 0);
|
|
142 smanager->dma_wait(0);
|
|
143 }
|
|
144
|
|
145 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
|
|
146
|
|
147 zRow[localx + (rangex*localy)] = zpos;
|
|
148 linebuf[localx + (rangex*localy)] = rgb;
|
|
149 }
|
|
150 } else {
|
|
151 int js = (x < rangex_start) ? rangex_start - x : 0;
|
|
152 int je = (x + x_len > rangex_end) ? rangex_end - x : x_len;
|
|
153 float tex_x, tex_y, tex_z;
|
|
154
|
|
155 /**
|
298
|
156 * 一回比較すれば、以後再起動するまでは
|
|
157 * js_cont は使わないから 0 にしてるわけだけど、
|
|
158 * 最初の一回のためだけにこれはめんどくさいのー。
|
283
|
159 */
|
|
160 js = (js < js_cont) ? js_cont : js;
|
|
161 js_cont = 0;
|
|
162
|
|
163 for (int j = js; j <= je; j++) {
|
|
164 localx = getLocalX(x-1+j);
|
|
165
|
|
166 tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
|
|
167
|
|
168 tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
|
|
169 tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
|
|
170 if (tex_x > 1) tex_x = 1;
|
|
171 if (tex_x < 0) tex_x = 0;
|
|
172 if (tex_y > 1) tex_y = 1;
|
|
173 if (tex_y < 0) tex_y = 0;
|
|
174 tex_xpos = (int)((span->tex_width-1) * tex_x);
|
|
175 tex_ypos = (int)((span->tex_height-1) * tex_y);
|
|
176
|
|
177 if (tex_z < zRow[localx + (rangex*localy)]) {
|
|
178 tex_addr = getTile(tex_xpos, tex_ypos,
|
|
179 span->tex_width, span->tex_addr);
|
|
180 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
|
|
181 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
|
|
182
|
|
183 if (!isAvailableTile(tex_addr)) {
|
|
184 spack->info.start = t;
|
|
185 #if 0
|
|
186 set_rgbs(tex_addr,
|
|
187 getTile(span->tex_width-1, tex_ypos,
|
|
188 span->tex_width, span->tex_addr));
|
|
189 reboot(spack, j);
|
|
190 goto FINISH;
|
|
191 #else
|
|
192 set_rgb(tex_addr, TEX_LOAD);
|
|
193 smanager->dma_wait(TEX_LOAD);
|
|
194 #endif
|
|
195 }
|
|
196
|
|
197 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
|
|
198
|
|
199 zRow[localx + (rangex*localy)] = tex_z;
|
|
200 linebuf[localx + (rangex*localy)] = rgb;
|
|
201 }
|
|
202 }
|
|
203 }
|
|
204 }
|
|
205
|
|
206 smanager->dma_wait(SPAN_PACK_LOAD);
|
|
207
|
|
208 SpanPackPtr tmp_spack = spack;
|
|
209 spack = next_spack;
|
|
210 next_spack = tmp_spack;
|
|
211 } while (spack);
|
|
212
|
|
213 writebuffer(display, rangex, rangey, screen_width);
|
|
214
|
|
215 free(zRow);
|
|
216 free(args);
|
|
217
|
|
218 //FINISH:
|
|
219 /**
|
298
|
220 * linebuf, zRow, args は RenewTask が引き継ぐ
|
283
|
221 */
|
|
222 free(free_spack1);
|
|
223 free(free_spack2);
|
|
224
|
|
225 return 0;
|
|
226 }
|