Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2349 | Serge | 1 | #include |
3068 | serge | 2 | //#include |
3 | //#include |
||
4 | //#include |
||
2349 | Serge | 5 | #include |
3068 | serge | 6 | //#include |
2427 | Serge | 7 | #include "../winlib/winlib.h" |
3068 | serge | 8 | //#include "fplay.h" |
9 | #include "system.h" |
||
2349 | Serge | 10 | |
3068 | serge | 11 | typedef struct |
12 | { |
||
13 | uint32_t width; |
||
14 | uint32_t height; |
||
15 | uint32_t pitch; |
||
16 | uint32_t handle; |
||
17 | uint8_t *data; |
||
18 | }bitmap_t; |
||
19 | |||
20 | |||
2349 | Serge | 21 | #define DISPLAY_VERSION 0x0200 /* 2.00 */ |
22 | |||
23 | #define SRV_GETVERSION 0 |
||
24 | #define SRV_GET_CAPS 3 |
||
25 | |||
3068 | serge | 26 | #define SRV_CREATE_SURFACE 10 |
27 | #define SRV_DESTROY_SURFACE 11 |
||
28 | #define SRV_LOCK_SURFACE 12 |
||
29 | #define SRV_UNLOCK_SURFACE 13 |
||
30 | #define SRV_RESIZE_SURFACE 14 |
||
31 | #define SRV_BLIT_BITMAP 15 |
||
32 | #define SRV_BLIT_TEXTURE 16 |
||
33 | #define SRV_BLIT_VIDEO 17 |
||
2415 | Serge | 34 | |
2349 | Serge | 35 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) |
36 | #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) |
||
37 | |||
38 | |||
3068 | serge | 39 | #define HW_BIT_BLIT (1<<0) /* BGRX blitter */ |
40 | #define HW_TEX_BLIT (1<<1) /* stretch blit */ |
||
41 | #define HW_VID_BLIT (1<<2) /* planar and packed video */ |
||
42 | |||
43 | uint32_t InitPixlib(uint32_t flags); |
||
44 | |||
45 | int create_bitmap(bitmap_t *bitmap); |
||
46 | int lock_bitmap(bitmap_t *bitmap); |
||
47 | int resize_bitmap(bitmap_t *bitmap); |
||
48 | int blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y, |
||
49 | int w, int h); |
||
50 | |||
51 | |||
52 | |||
2349 | Serge | 53 | static uint32_t service; |
54 | static uint32_t blit_caps; |
||
3068 | serge | 55 | static uint32_t screen_width; |
56 | static uint32_t screen_height; |
||
2349 | Serge | 57 | |
58 | typedef struct |
||
59 | { |
||
3068 | serge | 60 | unsigned handle; |
61 | unsigned io_code; |
||
62 | void *input; |
||
63 | int inp_size; |
||
64 | void *output; |
||
65 | int out_size; |
||
66 | }ioctl_t; |
||
67 | |||
68 | |||
69 | |||
70 | typedef struct |
||
71 | { |
||
2349 | Serge | 72 | uint32_t idx; |
73 | union |
||
74 | { |
||
75 | uint32_t opt[2]; |
||
76 | struct { |
||
77 | uint32_t max_tex_width; |
||
78 | uint32_t max_tex_height; |
||
79 | }cap1; |
||
80 | }; |
||
81 | }hwcaps_t; |
||
82 | |||
3068 | serge | 83 | static inline uint32_t GetScreenSize() |
84 | { |
||
85 | uint32_t retval; |
||
86 | |||
87 | __asm__ __volatile__( |
||
88 | "int $0x40" |
||
89 | :"=a"(retval) |
||
90 | :"a"(61), "b"(1)); |
||
91 | return retval; |
||
92 | } |
||
93 | |||
2349 | Serge | 94 | static uint32_t get_service(char *name) |
95 | { |
||
96 | uint32_t retval = 0; |
||
97 | asm volatile ("int $0x40" |
||
98 | :"=a"(retval) |
||
99 | :"a"(68),"b"(16),"c"(name) |
||
100 | :"memory"); |
||
101 | |||
102 | return retval; |
||
103 | }; |
||
104 | |||
105 | static int call_service(ioctl_t *io) |
||
106 | { |
||
107 | int retval; |
||
108 | |||
109 | asm volatile("int $0x40" |
||
110 | :"=a"(retval) |
||
111 | :"a"(68),"b"(17),"c"(io) |
||
112 | :"memory","cc"); |
||
113 | |||
114 | return retval; |
||
115 | }; |
||
116 | |||
117 | #define BUFFER_SIZE(n) ((n)*sizeof(uint32_t)) |
||
118 | |||
119 | |||
120 | |||
121 | uint32_t InitPixlib(uint32_t caps) |
||
122 | { |
||
123 | uint32_t api_version; |
||
3068 | serge | 124 | uint32_t screensize; |
125 | hwcaps_t hwcaps; |
||
126 | ioctl_t io; |
||
2349 | Serge | 127 | |
128 | // __asm__ __volatile__("int3"); |
||
129 | |||
3068 | serge | 130 | screensize = GetScreenSize(); |
131 | screen_width = screensize >> 16; |
||
132 | screen_height = screensize & 0xFFFF; |
||
133 | |||
2349 | Serge | 134 | service = get_service("DISPLAY"); |
135 | if(service == 0) |
||
136 | goto fail; |
||
137 | |||
138 | io.handle = service; |
||
139 | io.io_code = SRV_GETVERSION; |
||
140 | io.input = NULL; |
||
141 | io.inp_size = 0; |
||
142 | io.output = &api_version; |
||
143 | io.out_size = BUFFER_SIZE(1); |
||
144 | |||
145 | if (call_service(&io)!=0) |
||
146 | goto fail; |
||
147 | |||
148 | if( (DISPLAY_VERSION > (api_version & 0xFFFF)) || |
||
149 | (DISPLAY_VERSION < (api_version >> 16))) |
||
150 | goto fail; |
||
151 | |||
152 | /* |
||
153 | * Let's see what this service can do |
||
154 | */ |
||
155 | hwcaps.idx = 0; |
||
156 | |||
157 | io.handle = service; |
||
158 | io.io_code = SRV_GET_CAPS; |
||
159 | io.input = &hwcaps; |
||
160 | io.inp_size = sizeof(hwcaps); |
||
161 | io.output = NULL; |
||
162 | io.out_size = 0; |
||
163 | |||
164 | if (call_service(&io)!=0) |
||
165 | goto fail; |
||
166 | |||
167 | blit_caps = hwcaps.opt[0]; |
||
168 | |||
169 | printf("\nDISPLAY service handle %x\n", service); |
||
170 | |||
171 | if( blit_caps ) |
||
172 | printf("service caps %s%s%s\n", |
||
173 | (blit_caps & HW_BIT_BLIT) != 0 ?"HW_BIT_BLIT ":"", |
||
174 | (blit_caps & HW_TEX_BLIT) != 0 ?"HW_TEX_BLIT ":"", |
||
175 | (blit_caps & HW_VID_BLIT) != 0 ?"HW_VID_BLIT ":""); |
||
176 | |||
177 | blit_caps&= caps; |
||
178 | return blit_caps; |
||
179 | |||
180 | fail: |
||
181 | service = 0; |
||
182 | return 0; |
||
183 | }; |
||
184 | |||
185 | |||
186 | int create_bitmap(bitmap_t *bitmap) |
||
187 | { |
||
188 | // __asm__ __volatile__("int3"); |
||
189 | |||
190 | if( blit_caps & HW_BIT_BLIT ) |
||
191 | { |
||
192 | struct __attribute__((packed)) /* SRV_CREATE_SURFACE */ |
||
193 | { |
||
194 | uint32_t handle; // ignored |
||
195 | void *data; // ignored |
||
196 | |||
197 | uint32_t width; |
||
198 | uint32_t height; |
||
199 | uint32_t pitch; // ignored |
||
200 | |||
201 | uint32_t max_width; |
||
202 | uint32_t max_height; |
||
203 | uint32_t format; // reserved mbz |
||
204 | }io_10; |
||
205 | |||
206 | ioctl_t io; |
||
207 | int err; |
||
208 | |||
209 | // printf("create bitmap %d x %d\n", |
||
210 | // bitmap->width, bitmap->height); |
||
211 | |||
212 | io_10.width = bitmap->width; |
||
213 | io_10.height = bitmap->height; |
||
3068 | serge | 214 | io_10.max_width = screen_width; |
215 | io_10.max_height = screen_height; |
||
2349 | Serge | 216 | io_10.format = 0; |
217 | |||
218 | io.handle = service; |
||
219 | io.io_code = SRV_CREATE_SURFACE; |
||
220 | io.input = &io_10; |
||
221 | io.inp_size = BUFFER_SIZE(8); |
||
222 | io.output = NULL; |
||
223 | io.out_size = 0; |
||
224 | |||
225 | err = call_service(&io); |
||
226 | if(err==0) |
||
227 | { |
||
228 | bitmap->handle = io_10.handle; |
||
229 | bitmap->pitch = io_10.pitch; |
||
230 | bitmap->data = io_10.data; |
||
231 | // printf("Create hardware surface %x pitch %d, buffer %x\n", |
||
232 | // bitmap->handle, bitmap->pitch, bitmap->data); |
||
233 | return 0; |
||
234 | }; |
||
235 | return err; |
||
236 | }; |
||
237 | |||
238 | uint32_t size; |
||
239 | uint32_t pitch; |
||
240 | uint8_t *buffer; |
||
241 | |||
242 | pitch = ALIGN(bitmap->width*4, 16); |
||
243 | size = pitch * bitmap->height; |
||
244 | |||
245 | buffer = (uint8_t*)user_alloc(size); |
||
246 | if( buffer ) |
||
247 | { |
||
248 | bitmap->handle = 0; |
||
249 | bitmap->pitch = pitch; |
||
250 | bitmap->data = buffer; |
||
251 | return 0; |
||
252 | }; |
||
253 | |||
254 | printf("Cannot alloc frame buffer\n\r"); |
||
255 | |||
256 | return -1; |
||
257 | }; |
||
258 | |||
2415 | Serge | 259 | int lock_bitmap(bitmap_t *bitmap) |
260 | { |
||
261 | // __asm__ __volatile__("int3"); |
||
3068 | serge | 262 | int err = 0; |
2415 | Serge | 263 | |
264 | if( blit_caps & HW_BIT_BLIT ) |
||
265 | { |
||
3068 | serge | 266 | struct __attribute__((packed)) /* SRV_LOCK_SURFACE */ |
2415 | Serge | 267 | { |
3068 | serge | 268 | uint32_t handle; |
269 | void *data; |
||
270 | uint32_t pitch; |
||
2415 | Serge | 271 | |
272 | }io_12; |
||
273 | |||
274 | ioctl_t io; |
||
275 | |||
276 | io_12.handle = bitmap->handle; |
||
277 | io_12.pitch = 0; |
||
278 | io_12.data = 0; |
||
279 | |||
280 | io.handle = service; |
||
281 | io.io_code = SRV_LOCK_SURFACE; |
||
282 | io.input = &io_12; |
||
3068 | serge | 283 | io.inp_size = BUFFER_SIZE(3); |
2415 | Serge | 284 | io.output = NULL; |
285 | io.out_size = 0; |
||
286 | |||
287 | err = call_service(&io); |
||
288 | if(err==0) |
||
289 | { |
||
290 | bitmap->pitch = io_12.pitch; |
||
291 | bitmap->data = io_12.data; |
||
292 | // printf("Lock hardware surface %x pitch %d, buffer %x\n", |
||
293 | // bitmap->handle, bitmap->pitch, bitmap->data); |
||
294 | }; |
||
295 | }; |
||
296 | |||
3068 | serge | 297 | return err; |
2415 | Serge | 298 | }; |
299 | |||
2349 | Serge | 300 | int blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y, |
301 | int w, int h) |
||
302 | { |
||
3068 | serge | 303 | int err; |
2349 | Serge | 304 | |
305 | if( blit_caps & HW_BIT_BLIT ) |
||
306 | { |
||
307 | |||
308 | /* |
||
309 | * Now you will experience the full power of the dark side... |
||
310 | */ |
||
311 | |||
312 | struct __attribute__((packed)) |
||
313 | { |
||
314 | uint32_t handle; |
||
315 | int dst_x; |
||
316 | int dst_y; |
||
317 | int src_x; |
||
318 | int src_y; |
||
319 | uint32_t w; |
||
320 | uint32_t h; |
||
3068 | serge | 321 | }io_15; |
2349 | Serge | 322 | |
323 | ioctl_t io; |
||
324 | |||
3068 | serge | 325 | io_15.handle = bitmap->handle; |
326 | io_15.dst_x = dst_x; |
||
327 | io_15.dst_y = dst_y; |
||
328 | io_15.src_x = 0; |
||
329 | io_15.src_y = 0; |
||
330 | io_15.w = w; |
||
331 | io_15.h = h; |
||
2349 | Serge | 332 | |
333 | io.handle = service; |
||
3068 | serge | 334 | io.io_code = SRV_BLIT_BITMAP; |
335 | io.input = &io_15; |
||
2349 | Serge | 336 | io.inp_size = BUFFER_SIZE(7); |
337 | io.output = NULL; |
||
338 | io.out_size = 0; |
||
339 | |||
340 | // printf("do blit %x pitch %d\n",bitmap->handle, |
||
341 | // bitmap->pitch); |
||
342 | err = call_service(&io); |
||
343 | return err; |
||
344 | }; |
||
345 | |||
3068 | serge | 346 | struct blit_call bc; |
2349 | Serge | 347 | |
348 | bc.dstx = dst_x; |
||
349 | bc.dsty = dst_y; |
||
350 | bc.w = w; |
||
351 | bc.h = h; |
||
352 | bc.srcx = 0; |
||
353 | bc.srcy = 0; |
||
354 | bc.srcw = w; |
||
355 | bc.srch = h; |
||
356 | bc.stride = bitmap->pitch; |
||
357 | bc.bitmap = bitmap->data; |
||
358 | |||
359 | __asm__ __volatile__( |
||
360 | "int $0x40" |
||
3068 | serge | 361 | :"=a"(err) |
362 | :"a"(73),"b"(0x00),"c"(&bc) |
||
2693 | Serge | 363 | :"memory"); |
3068 | serge | 364 | |
365 | return err; |
||
2349 | Serge | 366 | }; |
367 | |||
368 | int resize_bitmap(bitmap_t *bitmap) |
||
369 | { |
||
370 | // __asm__ __volatile__("int3"); |
||
371 | |||
372 | if( blit_caps & HW_BIT_BLIT ) |
||
373 | { |
||
3068 | serge | 374 | struct __attribute__((packed)) |
375 | { |
||
376 | uint32_t handle; |
||
377 | char *data; |
||
378 | uint32_t new_w; |
||
379 | uint32_t new_h; |
||
380 | uint32_t pitch; |
||
381 | }io_14; |
||
382 | |||
383 | ioctl_t io; |
||
384 | int err; |
||
385 | |||
386 | io_14.handle = bitmap->handle; |
||
387 | io_14.new_w = bitmap->width; |
||
388 | io_14.new_h = bitmap->height; |
||
389 | |||
390 | io.handle = service; |
||
391 | io.io_code = SRV_RESIZE_SURFACE; |
||
392 | io.input = &io_14; |
||
393 | io.inp_size = BUFFER_SIZE(5); |
||
394 | io.output = NULL; |
||
395 | io.out_size = 0; |
||
396 | |||
397 | err = call_service(&io); |
||
398 | if(err==0) |
||
399 | { |
||
400 | bitmap->pitch = io_14.pitch; |
||
401 | bitmap->data = io_14.data; |
||
402 | }; |
||
403 | return err; |
||
2349 | Serge | 404 | }; |
405 | |||
406 | uint32_t size; |
||
407 | uint32_t pitch; |
||
408 | uint8_t *buffer; |
||
409 | |||
410 | pitch = ALIGN(bitmap->width*4, 16); |
||
411 | size = pitch * bitmap->height; |
||
412 | |||
413 | buffer = (uint8_t*)user_realloc(bitmap->data, size); |
||
414 | if( buffer ) |
||
415 | { |
||
416 | bitmap->handle = 0; |
||
417 | bitmap->pitch = pitch; |
||
418 | bitmap->data = buffer; |
||
419 | return 0; |
||
420 | }; |
||
421 | |||
422 | printf("Cannot realloc frame buffer\n\r"); |
||
423 | |||
424 | return -1; |
||
425 | };>2)><2)>1)><1)>0)><0)> |
||
426 |