222b0c0820fafa958deb9e63f142463731824fb5
3 * Elite - The New Kind.
5 * Allegro version of Graphics routines.
7 * The code in this file has not been derived from the original Elite code.
8 * Written by C.J.Pinder 1999-2001.
9 * email: <christian@newkind.co.uk>
11 * Routines for drawing anti-aliased lines and circles by T.Harte.
29 volatile int frame_count
;
31 BITMAP
*scanner_image
;
35 static int start_poly
;
36 static int total_polys
;
47 static struct poly_data poly_chain
[MAX_POLYS
];
52 void frame_timer (void)
56 END_OF_FUNCTION(frame_timer
);
60 int gfx_graphics_startup (void)
65 #ifdef ALLEGRO_WINDOWS
68 rv
= set_gfx_mode(GFX_DIRECTX_OVL
, 512, 512, 0, 0);
71 rv
= set_gfx_mode(GFX_DIRECTX_WIN
, 512, 512, 0, 0);
74 rv
= set_gfx_mode(GFX_GDI
, 512, 512, 0, 0);
77 set_display_switch_mode (SWITCH_BACKGROUND
);
79 rv
= set_gfx_mode(GFX_DIRECTX
, 800, 600, 0, 0);
82 rv
= set_gfx_mode(GFX_GDI
, 800, 600, 0, 0);
86 rv
= set_gfx_mode(GFX_AUTODETECT
, 800, 600, 0, 0);
91 set_gfx_mode(GFX_TEXT
, 0, 0, 0, 0);
92 allegro_message("Unable to set graphics mode.");
96 datafile
= load_datafile("elite.dat");
99 set_gfx_mode(GFX_TEXT
, 0, 0, 0, 0);
100 allegro_message("Error loading %s!\n", "elite.dat");
104 scanner_image
= load_bitmap(scanner_filename
, the_palette
);
107 set_gfx_mode(GFX_TEXT
, 0, 0, 0, 0);
108 allegro_message("Error reading scanner bitmap file.\n");
112 /* select the scanner palette */
113 set_palette(the_palette
);
115 /* Create the screen buffer bitmap */
116 gfx_screen
= create_bitmap (SCREEN_W
, SCREEN_H
);
120 blit (scanner_image
, gfx_screen
, 0, 0, GFX_X_OFFSET
, 385+GFX_Y_OFFSET
, scanner_image
->w
, scanner_image
->h
);
121 gfx_draw_line (0, 0, 0, 384);
122 gfx_draw_line (0, 0, 511, 0);
123 gfx_draw_line (511, 0, 511, 384);
125 /* Install a timer to regulate the speed of the game... */
127 LOCK_VARIABLE(frame_count
);
128 LOCK_FUNCTION(frame_timer
);
130 install_int (frame_timer
, speed_cap
);
136 void gfx_graphics_shutdown (void)
138 destroy_bitmap(scanner_image
);
139 destroy_bitmap(gfx_screen
);
140 unload_datafile(datafile
);
145 * Blit the back buffer to the screen.
148 void gfx_update_screen (void)
150 while (frame_count
< 1)
155 blit (gfx_screen
, screen
, GFX_X_OFFSET
, GFX_Y_OFFSET
, GFX_X_OFFSET
, GFX_Y_OFFSET
, 512, 512);
160 void gfx_acquire_screen (void)
162 acquire_bitmap (gfx_screen
);
166 void gfx_release_screen (void)
168 release_bitmap(gfx_screen
);
171 void gfx_fast_plot_pixel (int x
, int y
, int col
)
173 // _putpixel(gfx_screen, x, y, col);
174 gfx_screen
->line
[y
][x
] = col
;
178 void gfx_plot_pixel (int x
, int y
, int col
)
180 putpixel (gfx_screen
, x
+ GFX_X_OFFSET
, y
+ GFX_Y_OFFSET
, col
);
184 void gfx_draw_filled_circle (int cx
, int cy
, int radius
, int circle_colour
)
186 circlefill (gfx_screen
, cx
+ GFX_X_OFFSET
, cy
+ GFX_Y_OFFSET
, radius
, circle_colour
);
194 #define trunc(x) ((x) & ~65535)
195 #define frac(x) ((x) & 65535)
196 #define invfrac(x) (65535-frac(x))
197 #define plot(x,y,c) putpixel(gfx_screen, (x), (y), (c)+AA_BASE)
200 * Draw anti-aliased wireframe circle.
204 void gfx_draw_aa_circle(int cx
, int cy
, int radius
)
213 radius
>>= (16 - AA_BITS
);
222 sx
= cx
+ (x
>> AA_BITS
); sy
= cy
+ (y
>> AA_BITS
);
224 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
225 plot(sx
+ 1, sy
, x
&AA_AND
);
227 sy
= cy
- (y
>> AA_BITS
);
229 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
230 plot(sx
+ 1, sy
, x
&AA_AND
);
232 sx
= cx
- (x
>> AA_BITS
);
234 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
235 plot(sx
- 1, sy
, x
&AA_AND
);
237 sy
= cy
+ (y
>> AA_BITS
);
239 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
240 plot(sx
- 1, sy
, x
&AA_AND
);
243 sx
= cx
+ (y
>> AA_BITS
); sy
= cy
+ (x
>> AA_BITS
);
245 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
246 plot(sx
, sy
+ 1, x
&AA_AND
);
248 sy
= cy
- (x
>> AA_BITS
);
250 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
251 plot(sx
, sy
- 1, x
&AA_AND
);
253 sx
= cx
- (y
>> AA_BITS
);
255 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
256 plot(sx
, sy
- 1, x
&AA_AND
);
258 sy
= cy
+ (x
>> AA_BITS
);
260 plot(sx
, sy
, AA_AND
- (x
&AA_AND
));
261 plot(sx
, sy
+ 1, x
&AA_AND
);
263 s
+= AA_AND
+1 + (y
<< (AA_BITS
+1)) + ((1 << (AA_BITS
+2))-2);
276 * Draw anti-aliased line.
280 void gfx_draw_aa_line (int x1
, int y1
, int x2
, int y2
)
283 fixed xgap
, ygap
, xend
, yend
, xf
, yf
;
284 fixed brightness1
, brightness2
, swap
;
286 int x
, y
, ix1
, ix2
, iy1
, iy2
;
288 x1
+= itofix(GFX_X_OFFSET
);
289 x2
+= itofix(GFX_X_OFFSET
);
290 y1
+= itofix(GFX_Y_OFFSET
);
291 y2
+= itofix(GFX_Y_OFFSET
);
296 if (abs(xd
) > abs(yd
))
300 swap
= x1
; x1
= x2
; x2
= swap
;
301 swap
= y1
; y1
= y2
; y2
= swap
;
310 xend
= trunc(x1
+ 32768);
311 yend
= y1
+ fmul(grad
, xend
-x1
);
313 xgap
= invfrac(x1
+32768);
318 brightness1
= fmul(invfrac(yend
), xgap
);
319 brightness2
= fmul(frac(yend
), xgap
);
321 plot(ix1
, iy1
, brightness1
>> (16-AA_BITS
));
322 plot(ix1
, iy1
+1, brightness2
>> (16-AA_BITS
));
328 xend
= trunc(x2
+ 32768);
329 yend
= y2
+ fmul(grad
, xend
-x2
);
331 xgap
= invfrac(x2
- 32768);
336 brightness1
= fmul(invfrac(yend
), xgap
);
337 brightness2
= fmul(frac(yend
), xgap
);
339 plot(ix2
, iy2
, brightness1
>> (16-AA_BITS
));
340 plot(ix2
, iy2
+1, brightness2
>> (16-AA_BITS
));
342 for(x
= ix1
+1; x
<= ix2
-1; x
++)
344 brightness1
= invfrac(yf
);
345 brightness2
= frac(yf
);
347 plot(x
, (yf
>> 16), brightness1
>> (16-AA_BITS
));
348 plot(x
, 1+(yf
>> 16), brightness2
>> (16-AA_BITS
));
357 swap
= x1
; x1
= x2
; x2
= swap
;
358 swap
= y1
; y1
= y2
; y2
= swap
;
367 yend
= trunc(y1
+ 32768);
368 xend
= x1
+ fmul(grad
, yend
-y1
);
370 ygap
= invfrac(y1
+32768);
375 brightness1
= fmul(invfrac(xend
), ygap
);
376 brightness2
= fmul(frac(xend
), ygap
);
378 plot(ix1
, iy1
, brightness1
>> (16-AA_BITS
));
379 plot(ix1
+1, iy1
, brightness2
>> (16-AA_BITS
));
385 yend
= trunc(y2
+ 32768);
386 xend
= x2
+ fmul(grad
, yend
-y2
);
388 ygap
= invfrac(y2
- 32768);
393 brightness1
= fmul(invfrac(xend
), ygap
);
394 brightness2
= fmul(frac(xend
), ygap
);
396 plot(ix2
, iy2
, brightness1
>> (16-AA_BITS
));
397 plot(ix2
+1, iy2
, brightness2
>> (16-AA_BITS
));
399 for(y
= iy1
+1; y
<= iy2
-1; y
++)
401 brightness1
= invfrac(xf
);
402 brightness2
= frac(xf
);
404 plot((xf
>> 16), y
, brightness1
>> (16-AA_BITS
));
405 plot(1+(xf
>> 16), y
, brightness2
>> (16-AA_BITS
));
423 void gfx_draw_circle (int cx
, int cy
, int radius
, int circle_colour
)
425 if (anti_alias_gfx
&& (circle_colour
== GFX_COL_WHITE
))
426 gfx_draw_aa_circle (cx
, cy
, itofix(radius
));
428 circle (gfx_screen
, cx
+ GFX_X_OFFSET
, cy
+ GFX_Y_OFFSET
, radius
, circle_colour
);
433 void gfx_draw_line (int x1
, int y1
, int x2
, int y2
)
437 hline (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, x2
+ GFX_X_OFFSET
, GFX_COL_WHITE
);
443 vline (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, y2
+ GFX_Y_OFFSET
, GFX_COL_WHITE
);
448 gfx_draw_aa_line (itofix(x1
), itofix(y1
), itofix(x2
), itofix(y2
));
450 line (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, x2
+ GFX_X_OFFSET
, y2
+ GFX_Y_OFFSET
, GFX_COL_WHITE
);
455 void gfx_draw_colour_line (int x1
, int y1
, int x2
, int y2
, int line_colour
)
459 hline (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, x2
+ GFX_X_OFFSET
, line_colour
);
465 vline (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, y2
+ GFX_Y_OFFSET
, line_colour
);
469 if (anti_alias_gfx
&& (line_colour
== GFX_COL_WHITE
))
470 gfx_draw_aa_line (itofix(x1
), itofix(y1
), itofix(x2
), itofix(y2
));
472 line (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, x2
+ GFX_X_OFFSET
, y2
+ GFX_Y_OFFSET
, line_colour
);
477 void gfx_draw_triangle (int x1
, int y1
, int x2
, int y2
, int x3
, int y3
, int col
)
479 triangle (gfx_screen
, x1
+ GFX_X_OFFSET
, y1
+ GFX_Y_OFFSET
, x2
+ GFX_X_OFFSET
, y2
+ GFX_Y_OFFSET
,
480 x3
+ GFX_X_OFFSET
, y3
+ GFX_Y_OFFSET
, col
);
485 void gfx_display_text (int x
, int y
, char *txt
)
488 textout (gfx_screen
, datafile
[ELITE_1
].dat
, txt
, (x
/ (2 / GFX_SCALE
)) + GFX_X_OFFSET
, (y
/ (2 / GFX_SCALE
)) + GFX_Y_OFFSET
, GFX_COL_WHITE
);
492 void gfx_display_colour_text (int x
, int y
, char *txt
, int col
)
495 textout (gfx_screen
, datafile
[ELITE_1
].dat
, txt
, (x
/ (2 / GFX_SCALE
)) + GFX_X_OFFSET
, (y
/ (2 / GFX_SCALE
)) + GFX_Y_OFFSET
, col
);
500 void gfx_display_centre_text (int y
, char *str
, int psize
, int col
)
517 textout_centre (gfx_screen
, datafile
[txt_size
].dat
, str
, (128 * GFX_SCALE
) + GFX_X_OFFSET
, (y
/ (2 / GFX_SCALE
)) + GFX_Y_OFFSET
, txt_colour
);
521 void gfx_clear_display (void)
523 rectfill (gfx_screen
, GFX_X_OFFSET
+ 1, GFX_Y_OFFSET
+ 1, 510 + GFX_X_OFFSET
, 383 + GFX_Y_OFFSET
, GFX_COL_BLACK
);
526 void gfx_clear_text_area (void)
528 rectfill (gfx_screen
, GFX_X_OFFSET
+ 1, GFX_Y_OFFSET
+ 340, 510 + GFX_X_OFFSET
, 383 + GFX_Y_OFFSET
, GFX_COL_BLACK
);
532 void gfx_clear_area (int tx
, int ty
, int bx
, int by
)
534 rectfill (gfx_screen
, tx
+ GFX_X_OFFSET
, ty
+ GFX_Y_OFFSET
,
535 bx
+ GFX_X_OFFSET
, by
+ GFX_Y_OFFSET
, GFX_COL_BLACK
);
538 void gfx_draw_rectangle (int tx
, int ty
, int bx
, int by
, int col
)
540 rectfill (gfx_screen
, tx
+ GFX_X_OFFSET
, ty
+ GFX_Y_OFFSET
,
541 bx
+ GFX_X_OFFSET
, by
+ GFX_Y_OFFSET
, col
);
545 void gfx_display_pretty_text (int tx
, int ty
, int bx
, int by
, char *txt
)
554 maxlen
= (bx
- tx
) / 8;
565 while ((str
[pos
] != ' ') && (str
[pos
] != ',') &&
566 (str
[pos
] != '.') && (str
[pos
] != '\0'))
573 for (bptr
= strbuf
; pos
>= 0; pos
--)
579 textout (gfx_screen
, datafile
[ELITE_1
].dat
, strbuf
, tx
+ GFX_X_OFFSET
, ty
+ GFX_Y_OFFSET
, GFX_COL_WHITE
);
580 ty
+= (8 * GFX_SCALE
);
585 void gfx_draw_scanner (void)
587 blit (scanner_image
, gfx_screen
, 0, 0, GFX_X_OFFSET
, 385+GFX_Y_OFFSET
, scanner_image
->w
, scanner_image
->h
);
590 void gfx_set_clip_region (int tx
, int ty
, int bx
, int by
)
592 set_clip (gfx_screen
, tx
+ GFX_X_OFFSET
, ty
+ GFX_Y_OFFSET
, bx
+ GFX_X_OFFSET
, by
+ GFX_Y_OFFSET
);
596 void gfx_start_render (void)
603 void gfx_render_polygon (int num_points
, int *point_list
, int face_colour
, int zavg
)
609 if (total_polys
== MAX_POLYS
)
615 poly_chain
[x
].no_points
= num_points
;
616 poly_chain
[x
].face_colour
= face_colour
;
617 poly_chain
[x
].z
= zavg
;
618 poly_chain
[x
].next
= -1;
620 for (i
= 0; i
< 16; i
++)
621 poly_chain
[x
].point_list
[i
] = point_list
[i
];
626 if (zavg
> poly_chain
[start_poly
].z
)
628 poly_chain
[x
].next
= start_poly
;
633 for (i
= start_poly
; poly_chain
[i
].next
!= -1; i
= poly_chain
[i
].next
)
635 nx
= poly_chain
[i
].next
;
637 if (zavg
> poly_chain
[nx
].z
)
639 poly_chain
[i
].next
= x
;
640 poly_chain
[x
].next
= nx
;
645 poly_chain
[i
].next
= x
;
649 void gfx_render_line (int x1
, int y1
, int x2
, int y2
, int dist
, int col
)
658 gfx_render_polygon (2, point_list
, col
, dist
);
662 void gfx_finish_render (void)
669 if (total_polys
== 0)
672 for (i
= start_poly
; i
!= -1; i
= poly_chain
[i
].next
)
674 num_points
= poly_chain
[i
].no_points
;
675 pl
= poly_chain
[i
].point_list
;
676 col
= poly_chain
[i
].face_colour
;
680 gfx_draw_colour_line (pl
[0], pl
[1], pl
[2], pl
[3], col
);
684 gfx_polygon (num_points
, pl
, col
);
689 void gfx_polygon (int num_points
, int *poly_list
, int face_colour
)
696 for (i
= 0; i
< num_points
; i
++)
698 poly_list
[x
] += GFX_X_OFFSET
;
699 poly_list
[y
] += GFX_Y_OFFSET
;
704 polygon (gfx_screen
, num_points
, poly_list
, face_colour
);
708 void gfx_draw_sprite (int sprite_no
, int x
, int y
)
715 sprite_bmp
= datafile
[GRNDOT
].dat
;
719 sprite_bmp
= datafile
[REDDOT
].dat
;
723 sprite_bmp
= datafile
[SAFE
].dat
;
727 sprite_bmp
= datafile
[ELITETXT
].dat
;
731 sprite_bmp
= datafile
[ECM
].dat
;
735 sprite_bmp
= datafile
[BLAKE
].dat
;
738 case IMG_MISSILE_GREEN
:
739 sprite_bmp
= datafile
[MISSILE_G
].dat
;
742 case IMG_MISSILE_YELLOW
:
743 sprite_bmp
= datafile
[MISSILE_Y
].dat
;
746 case IMG_MISSILE_RED
:
747 sprite_bmp
= datafile
[MISSILE_R
].dat
;
755 x
= ((256 * GFX_SCALE
) - sprite_bmp
->w
) / 2;
757 draw_sprite (gfx_screen
, sprite_bmp
, x
+ GFX_X_OFFSET
, y
+ GFX_Y_OFFSET
);
761 int gfx_request_file (char *title
, char *path
, char *ext
)
766 okay
= file_select (title
, path
, ext
);