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.14 by cebix, 2001-06-30T17:21:51Z

# 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
# 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 >        int inc = 256 / num, value = 0;
173 >        uint8 *p = VidLocal.palette;
174 >        for (int i=0; i<num; i++) {
175 >                uint8 red = value, green = value, blue = value;
176 >                if (have_gamma) {
177 >                        red = red_gamma[red >> (8 - data_width)];
178 >                        green = green_gamma[green >> (8 - data_width)];
179 >                        blue = blue_gamma[blue >> (8 - data_width)];
180 >                }
181 >                *p++ = red;
182 >                *p++ = green;
183 >                *p++ = blue;
184 >                value += inc;
185 >        }
186 >
187 >        video_set_palette(VidLocal.palette);
188 > }
189 >
190 >
191 > /*
192 > *  Allocate gamma table of specified size
193 > */
194 >
195 > static bool allocate_gamma_table(int size)
196 > {
197 >        M68kRegisters r;
198 >
199 >        if (size > VidLocal.alloc_gamma_table_size) {
200 >                if (VidLocal.gamma_table) {
201 >                        r.a[0] = VidLocal.gamma_table;
202 >                        Execute68kTrap(0xa01f, &r);     // DisposePtr()
203 >                        VidLocal.gamma_table = 0;
204 >                        VidLocal.alloc_gamma_table_size = 0;
205                  }
206 <                video_set_palette(VidLocal.palette);
206 >                r.d[0] = size;
207 >                Execute68kTrap(0xa71e, &r);     // NewPtrSysClear()
208 >                if (r.a[0] == 0)
209 >                        return false;
210 >                VidLocal.gamma_table = r.a[0];
211 >                VidLocal.alloc_gamma_table_size = size;
212          }
213 +        return true;
214 + }
215 +
216 +
217 + /*
218 + *  Set gamma table (0 = build linear ramp)
219 + */
220 +
221 + static bool set_gamma_table(uint32 user_table)
222 + {
223 +        if (user_table == 0) { // Build linear ramp, 256 entries
224 +
225 +                // Allocate new table, if necessary
226 +                if (!allocate_gamma_table(SIZEOF_GammaTbl + 256))
227 +                        return memFullErr;
228 +                uint32 table = VidLocal.gamma_table;
229 +
230 +                // Initialize header
231 +                WriteMacInt16(table + gVersion, 0);
232 +                WriteMacInt16(table + gType, 0);
233 +                WriteMacInt16(table + gFormulaSize, 0);
234 +                WriteMacInt16(table + gChanCnt, 1);
235 +                WriteMacInt16(table + gDataCnt, 256);
236 +                WriteMacInt16(table + gDataWidth, 8);
237 +
238 +                // Build ramp
239 +                uint32 p = table + gFormulaData;
240 +                for (int i=0; i<256; i++)
241 +                        WriteMacInt8(p + i, i);
242 +
243 +        } else { // User-supplied gamma table
244 +
245 +                // Validate header
246 +                if (ReadMacInt16(user_table + gVersion))
247 +                        return paramErr;
248 +                if (ReadMacInt16(user_table + gType))
249 +                        return paramErr;
250 +                int chan_cnt = ReadMacInt16(user_table + gChanCnt);
251 +                if (chan_cnt != 1 && chan_cnt != 3)
252 +                        return paramErr;
253 +                int data_width = ReadMacInt16(user_table + gDataWidth);
254 +                if (data_width > 8)
255 +                        return paramErr;
256 +                int data_cnt = ReadMacInt16(user_table + gDataCnt);
257 +                if (data_cnt != (1 << data_width))
258 +                        return paramErr;
259 +
260 +                // Allocate new table, if necessary
261 +                int size = SIZEOF_GammaTbl + ReadMacInt16(user_table + gFormulaSize) + chan_cnt * data_cnt;
262 +                if (!allocate_gamma_table(size))
263 +                        return memFullErr;
264 +                uint32 table = VidLocal.gamma_table;
265 +
266 +                // Copy table
267 +                Mac2Mac_memcpy(table, user_table, size);
268 +        }
269 +
270 +        if (IsDirectMode(VidLocal.current_mode))
271 +                load_ramp_palette();
272 +
273 +        return true;
274   }
275  
276  
# Line 175 | Line 305 | int16 VideoDriverOpen(uint32 pb, uint32
305          D(bug("SPBlock at %08x\n", VidLocal.sp));
306  
307          // Find and set default gamma table
308 <        VidLocal.gamma_table = 0; //!!
308 >        VidLocal.gamma_table = 0;
309 >        VidLocal.alloc_gamma_table_size = 0;
310 >        set_gamma_table(0);
311  
312          // Init color palette (solid gray)
313          set_gray_palette();
# Line 218 | Line 350 | int16 VideoDriverControl(uint32 pb, uint
350                          return noErr;
351                  }
352  
353 <                case cscSetEntries: {   // Set palette
354 <                        D(bug(" SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
355 <                        if (IsDirectMode(VidLocal.current_mode))
353 >                case cscSetEntries:             // Set palette
354 >                case cscDirectSetEntries: {
355 >                        D(bug(" (Direct)SetEntries table %08x, count %d, start %d\n", ReadMacInt32(param + csTable), ReadMacInt16(param + csCount), ReadMacInt16(param + csStart)));
356 >                        bool is_direct = IsDirectMode(VidLocal.current_mode);
357 >                        if (code == cscSetEntries && is_direct)
358 >                                return controlErr;
359 >                        if (code == cscDirectSetEntries && !is_direct)
360                                  return controlErr;
361  
362                          uint32 s_pal = ReadMacInt32(param + csTable);   // Source palette
# Line 230 | Line 366 | int16 VideoDriverControl(uint32 pb, uint
366                          if (s_pal == 0 || count > 255)
367                                  return paramErr;
368  
369 +                        // Find tables for gamma correction
370 +                        uint8 *red_gamma, *green_gamma, *blue_gamma;
371 +                        bool have_gamma = false;
372 +                        int data_width = 0;
373 +                        if (VidLocal.gamma_table) {
374 +                                uint32 table = VidLocal.gamma_table;
375 +                                red_gamma = Mac2HostAddr(table + gFormulaData + ReadMacInt16(table + gFormulaSize));
376 +                                int chan_cnt = ReadMacInt16(table + gChanCnt);
377 +                                if (chan_cnt == 1)
378 +                                        green_gamma = blue_gamma = red_gamma;
379 +                                else {
380 +                                        int ofs = ReadMacInt16(table + gDataCnt);
381 +                                        green_gamma = red_gamma + ofs;
382 +                                        blue_gamma = green_gamma + ofs;
383 +                                }
384 +                                data_width = ReadMacInt16(table + gDataWidth);
385 +                                have_gamma = true;
386 +                        }
387 +
388 +                        // Convert palette
389                          if (start == 0xffff) {  // Indexed
390                                  for (uint32 i=0; i<=count; i++) {
391                                          d_pal = VidLocal.palette + (ReadMacInt16(s_pal) & 0xff) * 3;
392                                          uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
393                                          uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
394                                          uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
395 <                                        if (VidLocal.luminance_mapping)
395 >                                        if (VidLocal.luminance_mapping && !is_direct)
396                                                  red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
397 <                                        //!! gamma correction
397 >                                        if (have_gamma) {
398 >                                                red = red_gamma[red >> (8 - data_width)];
399 >                                                green = green_gamma[green >> (8 - data_width)];
400 >                                                blue = blue_gamma[blue >> (8 - data_width)];
401 >                                        }
402                                          *d_pal++ = red;
403                                          *d_pal++ = green;
404                                          *d_pal++ = blue;
# Line 252 | Line 412 | int16 VideoDriverControl(uint32 pb, uint
412                                          uint8 red = (uint16)ReadMacInt16(s_pal + 2) >> 8;
413                                          uint8 green = (uint16)ReadMacInt16(s_pal + 4) >> 8;
414                                          uint8 blue = (uint16)ReadMacInt16(s_pal + 6) >> 8;
415 <                                        if (VidLocal.luminance_mapping)
415 >                                        if (VidLocal.luminance_mapping && !is_direct)
416                                                  red = green = blue = (red * 0x4ccc + green * 0x970a + blue * 0x1c29) >> 16;
417 <                                        //!! gamma correction
417 >                                        if (have_gamma) {
418 >                                                red = red_gamma[red >> (8 - data_width)];
419 >                                                green = green_gamma[green >> (8 - data_width)];
420 >                                                blue = blue_gamma[blue >> (8 - data_width)];
421 >                                        }
422                                          *d_pal++ = red;
423                                          *d_pal++ = green;
424                                          *d_pal++ = blue;
# Line 265 | Line 429 | int16 VideoDriverControl(uint32 pb, uint
429                          return noErr;
430                  }
431  
432 <                case cscSetGamma:               // Set gamma table
433 <                        D(bug(" SetGamma\n"));
434 <                        //!!
435 <                        return controlErr;
432 >                case cscSetGamma: {             // Set gamma table
433 >                        uint32 user_table = ReadMacInt32(param + csGTable);
434 >                        D(bug(" SetGamma %08x\n", user_table));
435 >                        return set_gamma_table(user_table) ? noErr : memFullErr;
436 >                }
437  
438                  case cscGrayPage: {             // Fill page with dithered gray pattern
439                          D(bug(" GrayPage %d\n", ReadMacInt16(param + csPage)));
# Line 295 | Line 460 | int16 VideoDriverControl(uint32 pb, uint
460                                  p += VidLocal.desc->mode.bytes_per_row;
461                                  pat = ~pat;
462                          }
463 <                        //!! if direct mode, load gamma table to CLUT
463 >
464 >                        if (IsDirectMode(VidLocal.current_mode))
465 >                                load_ramp_palette();
466 >
467                          return noErr;
468                  }
469  
# Line 487 | Line 655 | int16 VideoDriverStatus(uint32 pb, uint3
655                          return noErr;
656  
657                  case cscGetGamma:
658 <                        D(bug(" GetGamma -> \n"));
659 <                        //!!
660 <                        return statusErr;
658 >                        D(bug(" GetGamma -> %08x\n", VidLocal.gamma_table));
659 >                        WriteMacInt32(param + csGTable, VidLocal.gamma_table);
660 >                        return noErr;
661  
662                  case cscGetDefaultMode:         // Get default color depth
663                          D(bug(" GetDefaultMode -> %04x\n", VidLocal.preferred_mode));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines