|
|
1.1 root 1: /*
2: * Data used for communication between custom.c and drawing.c.
1.1.1.13 root 3: *
1.1 root 4: * Copyright 1996-1998 Bernd Schmidt
5: */
6:
7: #define SMART_UPDATE 1
8:
9: #ifdef SUPPORT_PENGUINS
10: #undef SMART_UPDATE
11: #define SMART_UPDATE 1
12: #endif
13:
14: #define MAX_PLANES 8
15:
1.1.1.4 root 16: #define RES_LORES 0
17: #define RES_HIRES 1
18: #define RES_SUPERHIRES 2
19:
20: /* calculate shift depending on resolution (replaced "decided_hires ? 4 : 8") (TW) */
21: #define RES_SHIFT(res) ((res) == RES_LORES ? 8 : (res) == RES_HIRES ? 4 : 2)
22:
1.1.1.9 root 23: /* According to the HRM, pixel data spends a couple of cycles somewhere in the chips
24: before it appears on-screen. */
25: #define DIW_DDF_OFFSET 9
26:
1.1 root 27: /* We ignore that many lores pixels at the start of the display. These are
28: * invisible anyway due to hardware DDF limits. */
1.1.1.11 root 29: #define DISPLAY_LEFT_SHIFT 0x40
1.1.1.9 root 30: #define PIXEL_XPOS(HPOS) (((HPOS)*2 - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift)
1.1 root 31:
1.1.1.11 root 32: #define max_diwlastword (PIXEL_XPOS(maxhpos) + 16)
1.1 root 33:
1.1.1.14 root 34: extern int lores_factor, lores_shift;
1.1 root 35:
1.1.1.7 root 36: STATIC_INLINE int coord_hw_to_window_x (int x)
1.1 root 37: {
38: x -= DISPLAY_LEFT_SHIFT;
39: return x << lores_shift;
40: }
41:
1.1.1.11 root 42: STATIC_INLINE int coord_window_to_hw_x (int x)
43: {
44: x >>= lores_shift;
45: return x + DISPLAY_LEFT_SHIFT;
46: }
47:
1.1.1.9 root 48: STATIC_INLINE int coord_diw_to_window_x (int x)
49: {
50: return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift;
51: }
52:
1.1.1.11 root 53: STATIC_INLINE int coord_window_to_diw_x (int x)
54: {
55: x = coord_window_to_hw_x (x);
56: return x - DIW_DDF_OFFSET;
57: }
58:
1.1 root 59: extern int framecnt;
60:
1.1.1.8 root 61:
62: /* color values in two formats: 12 (OCS/ECS) or 24 (AGA) bit Amiga RGB (color_regs),
1.1.1.13 root 63: * and the native color value; both for each Amiga hardware color register.
1.1.1.8 root 64: *
65: * !!! See color_reg_xxx functions below before touching !!!
66: */
1.1 root 67: struct color_entry {
1.1.1.8 root 68: uae_u16 color_regs_ecs[32];
69: xcolnr acolors[256];
70: uae_u32 color_regs_aga[256];
1.1 root 71: };
72:
1.1.1.8 root 73: /* convert 24 bit AGA Amiga RGB to native color */
74: /* warning: ugly and works with little-endian cpu's only */
75: #define CONVERT_RGB(c) \
76: ( xbluecolors[((uae_u8*)(&c))[0]] | xgreencolors[((uae_u8*)(&c))[1]] | xredcolors[((uae_u8*)(&c))[2]] )
77:
78: STATIC_INLINE xcolnr getxcolor (int c)
79: {
80: if (currprefs.chipset_mask & CSMASK_AGA)
81: return CONVERT_RGB(c);
82: else
83: return xcolors[c];
84: }
85:
86: /* functions for reading, writing, copying and comparing struct color_entry */
87: STATIC_INLINE int color_reg_get (struct color_entry *ce, int c)
88: {
89: if (currprefs.chipset_mask & CSMASK_AGA)
90: return ce->color_regs_aga[c];
91: else
92: return ce->color_regs_ecs[c];
93: }
94: STATIC_INLINE void color_reg_set (struct color_entry *ce, int c, int v)
95: {
96: if (currprefs.chipset_mask & CSMASK_AGA)
97: ce->color_regs_aga[c] = v;
98: else
99: ce->color_regs_ecs[c] = v;
100: }
101: STATIC_INLINE int color_reg_cmp (struct color_entry *ce1, struct color_entry *ce2)
102: {
103: if (currprefs.chipset_mask & CSMASK_AGA)
104: return memcmp (ce1->color_regs_aga, ce2->color_regs_aga, sizeof (uae_u32) * 256);
105: else
1.1.1.13 root 106: return memcmp (ce1->color_regs_ecs, ce2->color_regs_ecs, sizeof (uae_u16) * 32);
1.1.1.8 root 107: }
108: /* ugly copy hack, is there better solution? */
109: STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *src)
110: {
111: if (currprefs.chipset_mask & CSMASK_AGA) {
112: /* copy acolors and color_regs_aga */
113: memcpy (dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32);
114: } else {
115: /* copy first 32 acolors and color_regs_ecs */
116: memcpy (dst->color_regs_ecs, src->color_regs_ecs,
117: sizeof(struct color_entry) - sizeof(uae_u32) * 256 - sizeof(xcolnr) * (256-32));
118: }
119: }
120:
1.1 root 121: /*
122: * The idea behind this code is that at some point during each horizontal
123: * line, we decide how to draw this line. There are many more-or-less
124: * independent decisions, each of which can be taken at a different horizontal
125: * position.
1.1.1.9 root 126: * Sprites and color changes are handled specially: There isn't a single decision,
127: * but a list of structures containing information on how to draw the line.
1.1 root 128: */
129:
130: struct color_change {
131: int linepos;
132: int regno;
133: unsigned long value;
134: };
135:
1.1.1.9 root 136: /* 440 rather than 880, since sprites are always lores. */
1.1.1.10 root 137: #define MAX_PIXELS_PER_LINE 1760
138:
1.1.1.11 root 139: /* No divisors for MAX_PIXELS_PER_LINE; we support AGA and may one day
140: want to use SHRES sprites. */
141: #define MAX_SPR_PIXELS (((MAXVPOS + 1)*2 + 1) * MAX_PIXELS_PER_LINE)
1.1.1.9 root 142:
143: struct sprite_entry
144: {
145: unsigned short pos;
146: unsigned short max;
147: unsigned int first_pixel;
148: unsigned int has_attached;
1.1 root 149: };
150:
1.1.1.9 root 151: union sps_union {
152: uae_u8 bytes[2 * MAX_SPR_PIXELS];
153: uae_u32 words[2 * MAX_SPR_PIXELS / 4];
1.1 root 154: };
1.1.1.9 root 155: extern union sps_union spixstate;
156: extern uae_u16 spixels[MAX_SPR_PIXELS * 2];
1.1 root 157:
158: /* Way too much... */
1.1.1.4 root 159: #define MAX_REG_CHANGE ((MAXVPOS + 1) * 2 * MAXHPOS)
1.1 root 160:
161: #ifdef OS_WITHOUT_MEMORY_MANAGEMENT
162: extern struct color_change *color_changes[2];
163: #else
164: extern struct color_change color_changes[2][MAX_REG_CHANGE];
165: #endif
166:
1.1.1.4 root 167: extern struct color_entry color_tables[2][(MAXVPOS+1) * 2];
1.1 root 168: extern struct color_entry *curr_color_tables, *prev_color_tables;
169:
1.1.1.9 root 170: extern struct sprite_entry *curr_sprite_entries, *prev_sprite_entries;
1.1 root 171: extern struct color_change *curr_color_changes, *prev_color_changes;
172: extern struct draw_info *curr_drawinfo, *prev_drawinfo;
173:
174: /* struct decision contains things we save across drawing frames for
175: * comparison (smart update stuff). */
176: struct decision {
1.1.1.7 root 177: /* Records the leftmost access of BPL1DAT. */
1.1.1.9 root 178: int plfleft, plfright, plflinelen;
1.1 root 179: /* Display window: native coordinates, depend on lores state. */
180: int diwfirstword, diwlastword;
181: int ctable;
182:
1.1.1.9 root 183: uae_u16 bplcon0, bplcon2;
1.1.1.10 root 184: uae_u16 bplcon3, bplcon4;
1.1.1.9 root 185: uae_u8 nr_planes;
186: uae_u8 bplres;
1.1.1.11 root 187: unsigned int any_hires_sprites:1;
1.1.1.12 root 188: unsigned int ham_seen:1;
189: unsigned int ham_at_start:1;
1.1 root 190: };
191:
192: /* Anything related to changes in hw registers during the DDF for one
193: * line. */
194: struct draw_info {
1.1.1.9 root 195: int first_sprite_entry, last_sprite_entry;
1.1 root 196: int first_color_change, last_color_change;
197: int nr_color_changes, nr_sprites;
198: };
199:
1.1.1.4 root 200: extern struct decision line_decisions[2 * (MAXVPOS+1) + 1];
201: extern struct draw_info line_drawinfo[2][2 * (MAXVPOS+1) + 1];
1.1 root 202:
1.1.1.4 root 203: extern uae_u8 line_data[(MAXVPOS+1) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2];
1.1 root 204:
1.1.1.7 root 205: extern uae_u8 *real_bplpt[8];
206:
1.1 root 207: /* Functions in drawing.c. */
208: extern int coord_native_to_amiga_y (int);
209: extern int coord_native_to_amiga_x (int);
210:
211: extern void record_diw_line (int first, int last);
212: extern void hardware_line_completed (int lineno);
213:
214: /* Determine how to draw a scan line. */
215: enum nln_how {
216: /* All lines on a non-doubled display. */
217: nln_normal,
218: /* Non-interlace, doubled display. */
219: nln_doubled,
220: /* Interlace, doubled display, upper line. */
221: nln_upper,
222: /* Interlace, doubled display, lower line. */
1.1.1.2 root 223: nln_lower,
224: /* This line normal, next one black. */
225: nln_nblack
1.1 root 226: };
227:
1.1.1.2 root 228: extern void hsync_record_line_state (int lineno, enum nln_how, int changed);
1.1 root 229: extern void vsync_handle_redraw (int long_frame, int lof_changed);
230: extern void init_hardware_for_drawing_frame (void);
231: extern void finish_drawing_frame (void);
232: extern void reset_drawing (void);
1.1.1.15! root 233: extern void init_drawing_at_reset (void);
1.1 root 234: extern void drawing_init (void);
235: extern void notice_interlace_seen (void);
236:
237: /* Finally, stuff that shouldn't really be shared. */
238:
239: extern int thisframe_first_drawn_line, thisframe_last_drawn_line;
240: extern int diwfirstword,diwlastword;
1.1.1.3 root 241:
242: #define IHF_SCROLLLOCK 0
243: #define IHF_QUIT_PROGRAM 1
244: #define IHF_PICASSO 2
245: #define IHF_SOUNDADJUST 3
246:
247: extern int inhibit_frame;
248:
1.1.1.5 root 249: STATIC_INLINE void set_inhibit_frame (int bit)
1.1.1.3 root 250: {
251: inhibit_frame |= 1 << bit;
252: }
1.1.1.5 root 253: STATIC_INLINE void clear_inhibit_frame (int bit)
1.1.1.3 root 254: {
255: inhibit_frame &= ~(1 << bit);
256: }
1.1.1.5 root 257: STATIC_INLINE void toggle_inhibit_frame (int bit)
1.1.1.3 root 258: {
1.1.1.8 root 259: inhibit_frame ^= 1 << bit;
1.1.1.3 root 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.