ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/video.cpp
(Generate patch)

Comparing BasiliskII/src/video.cpp (file contents):
Revision 1.13 by cebix, 2001-06-29T12:51:20Z vs.
Revision 1.16 by cebix, 2001-07-01T00:46:31Z

# Line 52 | Line 52 | struct {
52          bool luminance_mapping;         // Luminance mapping on/off
53          bool interrupts_enabled;        // VBL interrupts on/off
54          uint32 gamma_table;                     // Mac address of gamma table
55 +        int alloc_gamma_table_size;     // Allocated size of gamma table
56          uint16 current_mode;            // Currently selected depth/resolution
57          uint32 current_id;
58          uint16 preferred_mode;          // Preferred depth/resolution
59          uint32 preferred_id;
60 <        uint32 sp;                                      // Mac address of Slot Manager parameter block
60 >        uint32 slot_param;                      // Mac address of Slot Manager parameter block
61   } VidLocal;
62  
63  
# Line 133 | Line 134 | static void get_size_of_resolution(uint3
134  
135   static void set_gray_palette(void)
136   {
137 <        if (!IsDirectMode(VidLocal.current_mode)) {
138 <                for (int i=0; i<256; i++) {
139 <                        VidLocal.palette[i * 3 + 0] = 127;
140 <                        VidLocal.palette[i * 3 + 1] = 127;
141 <                        VidLocal.palette[i * 3 + 2] = 127;
137 >        for (int i=0; i<256; i++) {
138 >                VidLocal.palette[i * 3 + 0] = 127;
139 >                VidLocal.palette[i * 3 + 1] = 127;
140 >                VidLocal.palette[i * 3 + 2] = 127;
141 >        }
142 >        video_set_palette(VidLocal.palette);
143 > }
144 >
145 >
146 > /*
147 > *  Load gamma-corrected black-to-white ramp to palette for direct-color mode
148 > */
149 >
150 > static void load_ramp_palette(void)
151 > {
152 >        // Find tables for gamma correction
153 >        uint8 *red_gamma, *green_gamma, *blue_gamma;
154 >        bool have_gamma = false;
155 >        int data_width = 0;
156 >        if (VidLocal.gamma_table) {
157 >                uint32 table = VidLocal.gamma_table;
158 >                red_gamma = Mac2HostAddr(table + gFormulaData + ReadMacInt16(table + gFormulaSize));
159 >                int chan_cnt = ReadMacInt16(table + gChanCnt);
160 >                if (chan_cnt == 1)
161 >                        green_gamma = blue_gamma = red_gamma;
162 >                else {
163 >                        int ofs = ReadMacInt16(table + gDataCnt);
164 >                        green_gamma = red_gamma + ofs;
165 >                        blue_gamma = green_gamma + ofs;
166 >                }
167 >                data_width = ReadMacInt16(table + gDataWidth);
168 >                have_gamma = true;
169 >        }
170 >
171 >        int num = (VidLocal.desc->mode.depth == VDEPTH_16BIT ? 32 : 256);
172 >        uint8 *p = VidLocal.palette;
173 >        for (int i=0; i<num; i++) {
174 >                uint8 red = (i * 256 / num), green = red, blue = red;
175 >                if (have_gamma) {
176 >                        red = red_gamma[red >> (8 - data_width)];
177 >                        green = green_gamma[green >> (8 - data_width)];
178 >                        blue = blue_gamma[blue >> (8 - data_width)];
179 >                }
180 >                *p++ = red;
181 >                *p++ = green;
182 >                *p++ = blue;
183 >        }
184 >
185 >        video_set_palette(VidLocal.palette);
186 > }
187 >
188 >
189 > /*
190 > *  Allocate gamma table of specified size
191 > */
192 >
193 > static bool allocate_gamma_table(int size)
194 > {
195 >        M68kRegisters r;
196 >
197 >        if (size > VidLocal.alloc_gamma_table_size) {
198 >                if (VidLocal.gamma_table) {
199 >                        r.a[0] = VidLocal.gamma_table;
200 >                        Execute68kTrap(0xa01f, &r);     // DisposePtr()
201 >                        VidLocal.gamma_table = 0;
202 >                        VidLocal.alloc_gamma_table_size = 0;
203                  }
204 <                video_set_palette(VidLocal.palette);
204 >                r.d[0] = size;
205 >                Execute68kTrap(0xa71e, &r);     // NewPtrSysClear()
206 >                if (r.a[0] == 0)
207 >                        return false;
208 >                VidLocal.gamma_table = r.a[0];
209 >                VidLocal.alloc_gamma_table_size = size;
210          }
211 +        return true;
212 + }
213 +
214 +
215 + /*
216 + *  Set gamma table (0 = build linear ramp)
217 + */
218 +
219 + static bool set_gamma_table(uint32 user_table)
220 + {
221 +        if (user_table == 0) { // Build linear ramp, 256 entries
222 +
223 +                // Allocate new table, if necessary
224 +                if (!allocate_gamma_table(SIZEOF_GammaTbl + 256))
225 +                        return memFullErr;
226 +                uint32 table = VidLocal.gamma_table;
227 +
228 +                // Initialize header
229 +                WriteMacInt16(table + gVersion, 0);
230 +                WriteMacInt16(table + gType, 0);
231 +                WriteMacInt16(table + gFormulaSize, 0);
232 +                WriteMacInt16(table + gChanCnt, 1);
233 +                WriteMacInt16(table + gDataCnt, 256);
234 +                WriteMacInt16(table + gDataWidth, 8);
235 +
236 +                // Build ramp
237 +                uint32 p = table + gFormulaData;
238 +                for (int i=0; i<256; i++)
239 +                        WriteMacInt8(p + i, i);
240 +
241 +        } else { // User-supplied gamma table
242 +
243 +                // Validate header
244 +                if (ReadMacInt16(user_table + gVersion))
245 +                        return paramErr;
246 +                if (ReadMacInt16(user_table + gType))
247 +                        return paramErr;
248 +                int chan_cnt = ReadMacInt16(user_table + gChanCnt);
249 +                if (chan_cnt != 1 && chan_cnt != 3)
250 +                        return paramErr;
251 +                int data_width = ReadMacInt16(user_table + gDataWidth);
252 +                if (data_width > 8)
253 +                        return paramErr;
254 +                int data_cnt = ReadMacInt16(user_table + gDataCnt);
255 +                if (data_cnt != (1 << data_width))
256 +                        return paramErr;
257 +
258 +                // Allocate new table, if necessary
259 +                int size = SIZEOF_GammaTbl + ReadMacInt16(user_table + gFormulaSize) + chan_cnt * data_cnt;
260 +                if (!allocate_gamma_table(size))
261 +                        return memFullErr;
262 +                uint32 table = VidLocal.gamma_table;
263 +
264 +                // Copy table
265 +                Mac2Mac_memcpy(table, user_table, size);
266 +        }
267 +
268 +        if (IsDirectMode(VidLocal.current_mode))
269 +                load_ramp_palette();
270 +
271 +        return true;
272   }
273  
274  
# Line 171 | Line 299 | int16 VideoDriverOpen(uint32 pb, uint32
299          Execute68kTrap(0xa71e, &r);     // NewPtrSysClear()
300          if (r.a[0] == 0)
301                  return memFullErr;
302 <        VidLocal.sp = r.a[0];
303 <        D(bug("SPBlock at %08x\n", VidLocal.sp));
302 >        VidLocal.slot_param = r.a[0];
303 >        D(bug("SPBlock at %08x\n", VidLocal.slot_param));
304  
305          // Find and set default gamma table
306 <        VidLocal.gamma_table = 0; //!!
306 >        VidLocal.gamma_table = 0;
307 >        VidLocal.alloc_gamma_table_size = 0;
308 >        set_gamma_table(0);
309  
310          // Init color palette (solid gray)
311          set_gray_palette();
# Line 218 | Line 348 | int16 VideoDriverControl(uint32 pb, uint
348                          return noErr;
349                  }
350  
351 <                case cscSetEntries: {   // Set palette
352 <                        D(bug(" SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
353 <                        if (IsDirectMode(VidLocal.current_mode))
351 >                case cscSetEntries:             // Set palette
352 >                case cscDirectSetEntries: {
353 >                        D(bug(" (Direct)SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
354 >                        bool is_direct = IsDirectMode(VidLocal.current_mode);
355 >                        if (code == cscSetEntries && is_direct)
356 >                                return controlErr;
357 >                        if (code == cscDirectSetEntries && !is_direct)
358                                  return controlErr;
359  
360                          uint32 s_pal = ReadMacInt32(param + csTable);   // Source palette
# Line 230 | Line 364 | int16 VideoDriverControl(uint32 pb, uint
364                          if (s_pal == 0 || count > 255)
365                                  return paramErr;
366  
367 +                        // Find tables for gamma correction
368 +                        uint8 *red_gamma, *green_gamma, *blue_gamma;
369 +                        bool have_gamma = false;
370 +                        int data_width = 0;
371 +                        if (VidLocal.gamma_table) {
372 +                                uint32 table = VidLocal.gamma_table;
373 +                                red_gamma = Mac2HostAddr(table + gFormulaData + ReadMacInt16(table + gFormulaSize));
374 +                                int chan_cnt = ReadMacInt16(table + gChanCnt);
375 +                                if (chan_cnt == 1)
376 +                                        green_gamma = blue_gamma = red_gamma;
377 +                                else {
378 +                                        int ofs = ReadMacInt16(table + gDataCnt);
379 +                                        green_gamma = red_gamma + ofs;
380 +                                        blue_gamma = green_gamma + ofs;
381 +                                }
382 +                                data_width = ReadMacInt16(table + gDataWidth);
383 +                                have_gamma = true;
384 +                        }
385 +
386 +                        // Convert palette
387                          if (start == 0xffff) {  // Indexed
388                                  for (uint32 i=0; i<=count; i++) {
389                                          d_pal = VidLocal.palette + (ReadMacInt16(s_pal) & 0xff) * 3;
390                                          uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
391                                          uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
392                                          uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
393 <                                        if (VidLocal.luminance_mapping)
393 >                                        if (VidLocal.luminance_mapping && !is_direct)
394                                                  red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
395 <                                        //!! gamma correction
395 >                                        if (have_gamma) {
396 >                                                red = red_gamma[red >> (8 - data_width)];
397 >                                                green = green_gamma[green >> (8 - data_width)];
398 >                                                blue = blue_gamma[blue >> (8 - data_width)];
399 >                                        }
400                                          *d_pal++ = red;
401                                          *d_pal++ = green;
402                                          *d_pal++ = blue;
# Line 252 | Line 410 | int16 VideoDriverControl(uint32 pb, uint
410                                          uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
411                                          uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
412                                          uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
413 <                                        if (VidLocal.luminance_mapping)
413 >                                        if (VidLocal.luminance_mapping && !is_direct)
414                                                  red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
415 <                                        //!! gamma correction
415 >                                        if (have_gamma) {
416 >                                                red = red_gamma[red >> (8 - data_width)];
417 >                                                green = green_gamma[green >> (8 - data_width)];
418 >                                                blue = blue_gamma[blue >> (8 - data_width)];
419 >                                        }
420                                          *d_pal++ = red;
421                                          *d_pal++ = green;
422                                          *d_pal++ = blue;
# Line 265 | Line 427 | int16 VideoDriverControl(uint32 pb, uint
427                          return noErr;
428                  }
429  
430 <                case cscSetGamma:               // Set gamma table
431 <                        D(bug(" SetGamma\n"));
432 <                        //!!
433 <                        return controlErr;
430 >                case cscSetGamma: {             // Set gamma table
431 >                        uint32 user_table = ReadMacInt32(param + csGTable);
432 >                        D(bug(" SetGamma %08x\n", user_table));
433 >                        return set_gamma_table(user_table) ? noErr : memFullErr;
434 >                }
435  
436                  case cscGrayPage: {             // Fill page with dithered gray pattern
437                          D(bug(" GrayPage %d\n", ReadMacInt16(param + csPage)));
# Line 295 | Line 458 | int16 VideoDriverControl(uint32 pb, uint
458                                  p += VidLocal.desc->mode.bytes_per_row;
459                                  pat = ~pat;
460                          }
461 <                        //!! if direct mode, load gamma table to CLUT
461 >
462 >                        if (IsDirectMode(VidLocal.current_mode))
463 >                                load_ramp_palette();
464 >
465                          return noErr;
466                  }
467  
# Line 339 | Line 505 | int16 VideoDriverControl(uint32 pb, uint
505                                  WriteMacInt32(param + csBaseAddr, frame_base);
506  
507                                  M68kRegisters r;
508 <                                uint32 sp = VidLocal.sp;
508 >                                uint32 sp = VidLocal.slot_param;
509                                  r.a[0] = sp;
510  
511                                  // Find functional sResource for this display
# Line 487 | Line 653 | int16 VideoDriverStatus(uint32 pb, uint3
653                          return noErr;
654  
655                  case cscGetGamma:
656 <                        D(bug(" GetGamma -> \n"));
657 <                        //!!
658 <                        return statusErr;
656 >                        D(bug(" GetGamma -> %08x\n", VidLocal.gamma_table));
657 >                        WriteMacInt32(param + csGTable, VidLocal.gamma_table);
658 >                        return noErr;
659  
660                  case cscGetDefaultMode:         // Get default color depth
661                          D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines