185
|
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
|
|
13 SchedDefineTask(DrawSpanRenew);
|
|
14
|
|
15 int
|
|
16 DrawSpanRenew::run(void *rbuf, void *wbuf)
|
|
17 {
|
|
18 hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
|
|
19 tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
|
|
20
|
|
21 int rangex_start = smanager->get_param(0);
|
|
22 int rangex_end = smanager->get_param(1);
|
|
23
|
|
24 // このタスクが担当する x の範囲
|
|
25 int rangex = rangex_end - rangex_start + 1;
|
|
26
|
|
27 // y の範囲 (render_y + rangey - 1)
|
|
28 int rangey = smanager->get_param(2);
|
|
29
|
|
30 float *zRow = (float*)smanager->allocate(sizeof(float)*rangex*rangey);
|
|
31
|
|
32 for (int i = 0; i < rangex*rangey; i++) {
|
|
33 zRow[i] = 65535.0f;
|
|
34 }
|
|
35
|
|
36 int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey);
|
|
37
|
|
38 for (int i = 0; i < rangey; i++) {
|
|
39 linebuf[i] = (int*)smanager->get_output(i);
|
|
40 linebuf_init(linebuf[i], rangex, 0xffffffff);
|
|
41 }
|
|
42
|
|
43 SpanPackPtr spack = (SpanPackPtr)smanager->get_param(3);
|
|
44 SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
|
|
45 Span *span;
|
|
46
|
|
47 // span->length_x の処理での再起動位置
|
|
48 int js_cont = smanager->get_param(4);
|
|
49
|
|
50 do {
|
|
51 /**
|
|
52 * SpanPack->next が存在する場合、
|
|
53 * 現在の SpanPack を処理してる間に
|
|
54 * 次の SpanPack の DMA 転送を行う
|
|
55 */
|
|
56 if (spack->next != NULL) {
|
|
57 smanager->dma_load(next_spack, (uint32)spack->next,
|
|
58 sizeof(SpanPack), SPAN_PACK_LOAD);
|
|
59 } else {
|
|
60 next_spack = NULL;
|
|
61 }
|
|
62
|
|
63 for (int t = spack->info.start; t < spack->info.size; t++) {
|
|
64 span = &spack->span[t];
|
|
65
|
|
66 Uint32 rgb = 0x00ff00;
|
|
67 float tex1 = span->tex_x1;
|
|
68 float tex2 = span->tex_x2;
|
|
69 float tey1 = span->tex_y1;
|
|
70 float tey2 = span->tex_y2;
|
|
71
|
|
72 /**
|
|
73 * Span が持つ 1 pixel 毎の
|
|
74 * テクスチャの座標
|
|
75 */
|
|
76 int tex_xpos;
|
|
77 int tex_ypos;
|
|
78
|
|
79 /**
|
|
80 * (tex_xpos, tex_ypos) の、ブロック内(上の図参照)での座標と
|
|
81 * そのブロックのアドレス(MainMemory)
|
|
82 */
|
|
83 int tex_localx;
|
|
84 int tex_localy;
|
|
85 uint32 *tex_addr;
|
|
86
|
|
87 int x = span->x;
|
|
88 int y = span->y;
|
|
89 int x_len = span->length_x;
|
|
90 float z = span->start_z;
|
|
91 float zpos = span->end_z;
|
|
92
|
|
93 // 座標が [0 .. split_screen_w-1] に入るように x,y を -1
|
|
94 int localx = getLocalX(x-1);
|
|
95 int localy = getLocalY(y-1);
|
|
96
|
|
97 if (x_len == 1) {
|
|
98 if (x < rangex_start || rangex_end < x) {
|
|
99 continue;
|
|
100 }
|
|
101
|
|
102 tex_xpos = (int)((span->tex_width-1) * tex1);
|
|
103 tex_ypos = (int)((span->tex_height-1) * tey1);
|
|
104
|
|
105 if (zpos < zRow[localx + (rangex * localy)]) {
|
|
106 tex_addr = getTile(tex_xpos, tex_ypos,
|
|
107 span->tex_width, span->tex_addr);
|
|
108 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
|
|
109 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
|
|
110
|
|
111 /**
|
|
112 * Tile が無い場合、一旦タスクはここで中断し、
|
|
113 * Tile をロードするタスクを走らせた後に再起動する
|
|
114 */
|
|
115 if (!isAvailableTile(tex_addr)) {
|
|
116 spack->info.start = t;
|
186
|
117 set_rgb(tex_addr);
|
|
118 //set_rgbs(tex_addr,
|
|
119 //getTile(span->tex_width-1, tex_ypos,
|
|
120 //span->tex_width, span->tex_addr));
|
|
121 //reboot(spack, 0);
|
|
122 //goto FINISH;
|
185
|
123 }
|
|
124
|
|
125 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
|
|
126
|
|
127 zRow[localx + (rangex * localy)] = zpos;
|
|
128 linebuf[localy][localx] = rgb;
|
|
129 }
|
|
130 } else {
|
|
131 int js = (x < rangex_start) ? rangex_start - x : 0;
|
|
132 int je = (x + x_len > rangex_end) ? rangex_end - x : x_len;
|
|
133 float tex_x, tex_y, tex_z;
|
|
134
|
|
135 /**
|
|
136 * 一回比較すれば、以後再起動するまでは
|
|
137 * js_cont は使わないから 0 にしてるわけだけど、
|
|
138 * 最初の一回のためだけにこれはめんどくさいのー。
|
|
139 */
|
|
140 js = (js < js_cont) ? js_cont : js;
|
|
141 js_cont = 0;
|
|
142
|
|
143 for (int j = js; j <= je; j++) {
|
|
144 localx = getLocalX(x-1+j);
|
|
145
|
|
146 tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
|
|
147
|
|
148 tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
|
|
149 tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
|
|
150 if (tex_x > 1) tex_x = 1;
|
|
151 if (tex_x < 0) tex_x = 0;
|
|
152 if (tex_y > 1) tex_y = 1;
|
|
153 if (tex_y < 0) tex_y = 0;
|
|
154 tex_xpos = (int)((span->tex_width-1) * tex_x);
|
|
155 tex_ypos = (int)((span->tex_height-1) * tex_y);
|
|
156
|
|
157 if (tex_z < zRow[localx + (rangex*localy)]) {
|
|
158 tex_addr = getTile(tex_xpos, tex_ypos,
|
|
159 span->tex_width, span->tex_addr);
|
|
160 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
|
|
161 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
|
|
162
|
|
163 if (!isAvailableTile(tex_addr)) {
|
|
164 spack->info.start = t;
|
186
|
165 set_rgb(tex_addr);
|
|
166 //set_rgbs(tex_addr,
|
|
167 //getTile(span->tex_width-1, tex_ypos,
|
|
168 //span->tex_width, span->tex_addr));
|
|
169 //reboot(spack, j);
|
|
170 //goto FINISH;
|
185
|
171 }
|
|
172
|
|
173 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
|
|
174
|
|
175 zRow[localx + (rangex*localy)] = tex_z;
|
|
176 linebuf[localy][localx] = rgb;
|
|
177 }
|
|
178 }
|
|
179 }
|
|
180 }
|
|
181
|
|
182 smanager->dma_wait(SPAN_PACK_LOAD);
|
|
183
|
|
184 SpanPackPtr tmp_spack = spack;
|
|
185 spack = next_spack;
|
|
186 next_spack = tmp_spack;
|
|
187 } while (spack);
|
|
188
|
|
189
|
|
190 FINISH:
|
|
191 free(next_spack);
|
|
192 free(linebuf);
|
186
|
193 free(zRow);
|
|
194
|
|
195 // Renew したタスクで allocate されたものなので、これも free
|
|
196 free(spack);
|
185
|
197
|
|
198 return 0;
|
|
199 }
|