Revision 323
more stuff
graph.c | ||
---|---|---|
8 | 8 |
#define VC_BIOS_SERV 0x10 /** @brief Interrupt service of video card */ |
9 | 9 |
#define VBE_CALL 0x4F /** @brief VBE call function specifier */ |
10 | 10 |
|
11 |
#define MBYTE_BASE 0x0 /** @brief Base address (zero address) */ |
|
12 |
#define MBYTE_SIZE 0xFFFFF /** @brief Size of a mebibyte */ |
|
11 |
//#define MBYTE_BASE 0x0 /** @brief Base address (zero address) */
|
|
12 |
//#define MBYTE_SIZE 0xFFFFF /** @brief Size of a mebibyte */
|
|
13 | 13 |
|
14 | 14 |
// Graphics Functions |
15 |
#define VBE_CTRL_INFO 0x00 /** @brief Get VBE Controller Information */ |
|
15 |
//#define VBE_CTRL_INFO 0x00 /** @brief Get VBE Controller Information */
|
|
16 | 16 |
#define VBE_MD_INFO 0x01 /** @brief Get VBE Mode Information */ |
17 | 17 |
#define SET_VBE_MD 0x02 /** @brief Set VBE Mode */ |
18 | 18 |
|
19 | 19 |
// Error codes (AH) |
20 | 20 |
#define AH_SUCCESS 0x00 /** @brief Success code on BIOS call */ |
21 |
#define AH_FUNC_CALL_FAIL 0x01 /** @brief Function call failed */ |
|
22 |
#define AH_FUNC_NOT_SUPP 0x02 /** @brief Function call is not supported in current HW configuration */ |
|
23 |
#define AH_FUNC_INVALID 0x03 /** @brief Invalid function in current video mode */ |
|
21 |
//#define AH_FUNC_CALL_FAIL 0x01 /** @brief Function call failed */
|
|
22 |
//#define AH_FUNC_NOT_SUPP 0x02 /** @brief Function call is not supported in current HW configuration */
|
|
23 |
//#define AH_FUNC_INVALID 0x03 /** @brief Invalid function in current video mode */
|
|
24 | 24 |
|
25 | 25 |
/// MACROS |
26 |
#define FAR2PHYS(n) ((((n)>>12) & 0xFFFFFFF0) + ((n) & 0x0000FFFF)) |
|
26 |
//#define FAR2PHYS(n) ((((n)>>12) & 0xFFFFFFF0) + ((n) & 0x0000FFFF))
|
|
27 | 27 |
|
28 | 28 |
/// STRUCT |
29 | 29 |
typedef struct __attribute__((packed)) { |
... | ... | |
211 | 211 |
*/ |
212 | 212 |
|
213 | 213 |
/// INIT |
214 |
/** |
|
215 |
* @brief |
|
216 |
* @param mode |
|
217 |
* @return |
|
218 |
*/ |
|
219 | 214 |
static int (graph_set_mode)(uint16_t mode) { |
220 | 215 |
struct reg86 reg_86; |
221 | 216 |
|
... | ... | |
314 | 309 |
int16_t (basic_sprite_get_u0) (const basic_sprite_t *p){ return p->u0 ; } |
315 | 310 |
int16_t (basic_sprite_get_v0) (const basic_sprite_t *p){ return p->v0 ; } |
316 | 311 |
|
317 |
/* |
|
318 |
struct basic_sprite_alpha{ |
|
319 |
uint8_t *map; |
|
320 |
uint16_t w, h; |
|
321 |
int16_t u0, v0; |
|
322 |
}; |
|
323 |
basic_sprite_alpha_t* (basic_sprite_alpha_ctor)(const char **xpm, int16_t u0, int16_t v0){ |
|
324 |
basic_sprite_alpha_t *ret = malloc(sizeof(basic_sprite_t)); |
|
325 |
if(ret == NULL) return NULL; |
|
326 |
enum xpm_image_type type = XPM_8_8_8_8; |
|
327 |
xpm_image_t img; |
|
328 |
ret->map = NULL; |
|
329 |
uint8_t *m = xpm_load((xpm_map_t)xpm, type, &img); |
|
330 |
if(m == NULL){ |
|
331 |
basic_sprite_alpha_dtor(ret); |
|
332 |
return NULL; |
|
333 |
} |
|
334 |
ret->map = m; |
|
335 |
if(ret->map == NULL){ |
|
336 |
basic_sprite_alpha_dtor(ret); |
|
337 |
return NULL; |
|
338 |
} |
|
339 |
ret->w = img.width; |
|
340 |
ret->h = img.height; |
|
341 |
ret->u0 = u0; |
|
342 |
ret->v0 = v0; |
|
343 |
return ret; |
|
344 |
} |
|
345 |
void (basic_sprite_alpha_dtor)(basic_sprite_alpha_t *p){ |
|
346 |
if(p == NULL) return; |
|
347 |
free(p->map); |
|
348 |
free(p); |
|
349 |
} |
|
350 |
const uint8_t* (basic_sprite_alpha_get_map)(const basic_sprite_alpha_t *p){ return p->map; } |
|
351 |
uint16_t (basic_sprite_alpha_get_w) (const basic_sprite_alpha_t *p){ return p->w ; } |
|
352 |
uint16_t (basic_sprite_alpha_get_h) (const basic_sprite_alpha_t *p){ return p->h ; } |
|
353 |
int16_t (basic_sprite_alpha_get_u0) (const basic_sprite_alpha_t *p){ return p->u0 ; } |
|
354 |
int16_t (basic_sprite_alpha_get_v0) (const basic_sprite_alpha_t *p){ return p->v0 ; } |
|
355 |
*/ |
|
356 |
|
|
357 | 312 |
struct sprite{ |
358 | 313 |
const basic_sprite_t *bsp; |
359 | 314 |
int16_t x, y; //position in screen |
... | ... | |
381 | 336 |
void (sprite_set_pos) (sprite_t *p, int16_t x , int16_t y ){ p->x = x; p->y = y; } |
382 | 337 |
void (sprite_set_angle) (sprite_t *p, double angle ){ p->theta = angle; p->c = fm_cos(p->theta); p->s = fm_sin(p->theta); } |
383 | 338 |
void (sprite_set_scale) (sprite_t *p, double scale ){ |
384 |
if(p->scale == scale) return;
|
|
339 |
if(deq(p->scale, scale)) return;
|
|
385 | 340 |
p->scale = scale; |
386 | 341 |
|
387 |
p->su0 = p->bsp->u0*p->scale;
|
|
388 |
p->sv0 = p->bsp->u0*p->scale;
|
|
342 |
p->su0 = (int16_t)(p->bsp->u0*p->scale);
|
|
343 |
p->sv0 = (int16_t)(p->bsp->u0*p->scale);
|
|
389 | 344 |
|
390 | 345 |
const uint16_t W = basic_sprite_get_w(p->bsp), |
391 | 346 |
H = basic_sprite_get_h(p->bsp); |
392 |
uint16_t sW = W*scale, sH = H*scale;
|
|
347 |
uint16_t sW = (uint16_t)(W*scale), sH = (uint16_t)(H*scale);
|
|
393 | 348 |
p->sbuf = realloc(p->sbuf, sW*sH*4); |
394 | 349 |
const uint8_t *map = basic_sprite_get_map(p->bsp); |
395 | 350 |
for(uint16_t sx = 0; sx < sW; ++sx){ |
396 | 351 |
for(uint16_t sy = 0; sy < sH; ++sy){ |
397 |
uint16_t x = sx/scale, y = sy/scale;
|
|
352 |
uint16_t x = (uint16_t)(sx/scale), y = (uint16_t)(sy/scale);
|
|
398 | 353 |
if(x > W || y > H) continue; |
399 | 354 |
memcpy(p->sbuf+4*(sx+sy*sW), map+4*(x+y*W), 4); |
400 | 355 |
} |
... | ... | |
405 | 360 |
double (sprite_get_angle)(const sprite_t *p){ return p->theta; } |
406 | 361 |
uint16_t (sprite_get_w)(const sprite_t *p){ return basic_sprite_get_w(p->bsp); } |
407 | 362 |
uint16_t (sprite_get_h)(const sprite_t *p){ return basic_sprite_get_h(p->bsp); } |
408 |
void (sprite_src2sbuf)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){ |
|
363 |
static void (sprite_src2sbuf)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){
|
|
409 | 364 |
if(p->theta == 0.0){ |
410 | 365 |
*u = x - p->x + p->su0; |
411 | 366 |
*v = y - p->y + p->sv0; |
412 | 367 |
}else{ |
413 | 368 |
double dx = x - p->x; |
414 | 369 |
double dy = y - p->y; |
415 |
int16_t du = dx*p->c - dy*p->s - 0.5f;
|
|
416 |
int16_t dv = dx*p->s + dy*p->c - 0.5f;
|
|
370 |
int16_t du = (int16_t)(dx*p->c - dy*p->s - 0.5f);
|
|
371 |
int16_t dv = (int16_t)(dx*p->s + dy*p->c - 0.5f);
|
|
417 | 372 |
*u = du + p->su0; |
418 | 373 |
*v = dv + p->sv0; |
419 | 374 |
} |
420 | 375 |
} |
421 |
void (sprite_sbuf2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){ |
|
376 |
static void (sprite_sbuf2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){
|
|
422 | 377 |
int16_t du = u - p->su0; |
423 | 378 |
int16_t dv = v - p->sv0; |
424 | 379 |
double dx = du*p->c + dv*p->s; |
425 | 380 |
double dy = -du*p->s + dv*p->c; |
426 |
*x = dx + 0.5 + p->x;
|
|
427 |
*y = dy + 0.5 + p->y;
|
|
381 |
*x = (int16_t)(dx + 0.5 + p->x);
|
|
382 |
*y = (int16_t)(dy + 0.5 + p->y);
|
|
428 | 383 |
} |
429 | 384 |
|
430 | 385 |
void (sprite_draw)(const sprite_t *p){ |
431 |
const uint16_t sw = p->scale*basic_sprite_get_w(p->bsp);
|
|
432 |
const uint16_t sh = p->scale*basic_sprite_get_h(p->bsp);
|
|
386 |
const uint16_t sw = (uint16_t)(p->scale*basic_sprite_get_w(p->bsp));
|
|
387 |
const uint16_t sh = (uint16_t)(p->scale*basic_sprite_get_h(p->bsp));
|
|
433 | 388 |
int16_t xmin, xmax, ymin, ymax; { |
434 | 389 |
int16_t x, y; |
435 |
sprite_sbuf2src(p, 0 , 0 , &x, &y);
|
|
390 |
sprite_sbuf2src(p, 0 , 0 , &x, &y);
|
|
436 | 391 |
xmin = x; xmax = x; ymin = y; ymax = y; |
437 |
sprite_sbuf2src(p, sw, 0 , &x, &y);
|
|
438 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
|
|
439 |
sprite_sbuf2src(p, 0 , sh, &x, &y);
|
|
440 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
|
|
441 |
sprite_sbuf2src(p, sw, sh, &x, &y);
|
|
442 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
|
|
443 |
xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes());
|
|
444 |
ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes());
|
|
392 |
sprite_sbuf2src(p, (int16_t)sw, 0 , &x, &y);
|
|
393 |
xmin = min16(x, xmin); xmax = max16(x, xmax); ymin = min16(y, ymin); ymax = max16(y, ymax);
|
|
394 |
sprite_sbuf2src(p, 0 , (int16_t)sh, &x, &y);
|
|
395 |
xmin = min16(x, xmin); xmax = max16(x, xmax); ymin = min16(y, ymin); ymax = max16(y, ymax);
|
|
396 |
sprite_sbuf2src(p, (int16_t)sw, (int16_t)sh, &x, &y);
|
|
397 |
xmin = min16(x, xmin); xmax = max16(x, xmax); ymin = min16(y, ymin); ymax = max16(y, ymax);
|
|
398 |
xmin = max16(xmin-2, 0); xmax = min16(xmax+2, (int16_t)graph_get_XRes());
|
|
399 |
ymin = max16(ymin-2, 0); ymax = min16(ymax+2, (int16_t)graph_get_YRes());
|
|
445 | 400 |
} |
446 | 401 |
const uint16_t bytes_pixel = 3/*graph_get_bytes_pixel()*/; |
447 | 402 |
for(int16_t u, v, y = ymin; y < ymax; ++y){ |
Also available in: Unified diff