156 |
|
csSave->saveMode = VModes[cur_mode].viAppleMode; |
157 |
|
csSave->savePage = 0; |
158 |
|
csSave->saveVidParms = 0; // Add the right table |
159 |
– |
csSave->gammaTable = NULL; // No gamma table yet |
160 |
– |
csSave->maxGammaTableSize = 0; |
159 |
|
csSave->luminanceMapping = false; |
160 |
|
csSave->cursorX = 0; |
161 |
|
csSave->cursorY = 0; |
162 |
|
csSave->cursorVisible = 0; |
163 |
|
csSave->cursorSet = 0; |
164 |
|
|
165 |
< |
// Activate default gamma table |
165 |
> |
// Find and set default gamma table |
166 |
> |
csSave->gammaTable = 0; |
167 |
> |
csSave->maxGammaTableSize = 0; |
168 |
|
set_gamma(csSave, 0); |
169 |
|
|
170 |
|
// Install and activate interrupt service |
182 |
|
* Video driver control routine |
183 |
|
*/ |
184 |
|
|
185 |
< |
static int16 set_gamma(VidLocals *csSave, uint32 gamma) |
185 |
> |
static bool allocate_gamma_table(VidLocals *csSave, uint32 size) |
186 |
|
{ |
187 |
< |
#warning "FIXME: this code is not little endian aware" |
188 |
< |
GammaTbl *clientGamma = (GammaTbl *)gamma; |
189 |
< |
GammaTbl *gammaTable = csSave->gammaTable; |
190 |
< |
|
191 |
< |
if (clientGamma == NULL) { |
192 |
< |
|
193 |
< |
// No gamma table supplied, build linear ramp |
194 |
< |
uint32 linearRampSize = sizeof(GammaTbl) + 256 - 2; |
195 |
< |
uint8 *correctionData; |
196 |
< |
|
197 |
< |
// Allocate new gamma table if existing gamma table is smaller than required. |
198 |
< |
if (linearRampSize > csSave->maxGammaTableSize) { |
199 |
< |
delete[] csSave->gammaTable; |
200 |
< |
csSave->gammaTable = (GammaTbl *)new uint8[linearRampSize]; |
201 |
< |
csSave->maxGammaTableSize = linearRampSize; |
202 |
< |
gammaTable = csSave->gammaTable; |
187 |
> |
if (size > csSave->maxGammaTableSize) { |
188 |
> |
if (csSave->gammaTable) { |
189 |
> |
Mac_sysfree(csSave->gammaTable); |
190 |
> |
csSave->gammaTable = 0; |
191 |
> |
csSave->maxGammaTableSize = 0; |
192 |
|
} |
193 |
< |
|
194 |
< |
gammaTable->gVersion = 0; // A version 0 style of the GammaTbl structure |
195 |
< |
gammaTable->gType = 0; // Frame buffer hardware invariant |
196 |
< |
gammaTable->gFormulaSize = 0; // No formula data, just correction data |
197 |
< |
gammaTable->gChanCnt = 1; // Apply same correction to Red, Green, & Blue |
198 |
< |
gammaTable->gDataCnt = 256; // gDataCnt == 2^^gDataWidth |
199 |
< |
gammaTable->gDataWidth = 8; // 8 bits of significant data per entry |
200 |
< |
|
201 |
< |
// Find the starting address of the correction data. This can be computed by starting at |
202 |
< |
// the address of gFormula[0] and adding the gFormulaSize. |
203 |
< |
correctionData = (uint8 *)((uint32)&gammaTable->gFormulaData[0] + gammaTable->gFormulaSize); |
193 |
> |
if ((csSave->gammaTable = Mac_sysalloc(size)) == 0) |
194 |
> |
return false; |
195 |
> |
csSave->maxGammaTableSize = size; |
196 |
> |
} |
197 |
> |
return true; |
198 |
> |
} |
199 |
> |
|
200 |
> |
static int16 set_gamma(VidLocals *csSave, uint32 gamma) |
201 |
> |
{ |
202 |
> |
return paramErr; |
203 |
> |
|
204 |
> |
if (gamma == 0) { // Build linear ramp, 256 entries |
205 |
> |
|
206 |
> |
// Allocate new table, if necessary |
207 |
> |
if (!allocate_gamma_table(csSave, SIZEOF_GammaTbl + 256)) |
208 |
> |
return memFullErr; |
209 |
> |
|
210 |
> |
// Initialize header |
211 |
> |
WriteMacInt16(csSave->gammaTable + gVersion, 0); // A version 0 style of the GammaTbl structure |
212 |
> |
WriteMacInt16(csSave->gammaTable + gType, 0); // Frame buffer hardware invariant |
213 |
> |
WriteMacInt16(csSave->gammaTable + gFormulaSize, 0); // No formula data, just correction data |
214 |
> |
WriteMacInt16(csSave->gammaTable + gChanCnt, 1); // Apply same correction to Red, Green, & Blue |
215 |
> |
WriteMacInt16(csSave->gammaTable + gDataCnt, 256); // gDataCnt == 2^^gDataWidth |
216 |
> |
WriteMacInt16(csSave->gammaTable + gDataWidth, 8); // 8 bits of significant data per entry |
217 |
|
|
218 |
|
// Build the linear ramp |
219 |
< |
for (int i=0; i<gammaTable->gDataCnt; i++) |
220 |
< |
*correctionData++ = i; |
219 |
> |
uint32 p = csSave->gammaTable + gFormulaData; |
220 |
> |
for (int i=0; i<256; i++) |
221 |
> |
WriteMacInt8(p + i, i); |
222 |
|
|
223 |
< |
} else { |
223 |
> |
} else { // User-supplied gamma table |
224 |
|
|
225 |
< |
// User supplied a gamma table, so make sure it is a valid one |
226 |
< |
if (clientGamma->gVersion != 0) |
225 |
> |
// Validate header |
226 |
> |
if (ReadMacInt16(gamma + gVersion) != 0) |
227 |
|
return paramErr; |
228 |
< |
if (clientGamma->gType != 0) |
228 |
> |
if (ReadMacInt16(gamma + gType) != 0) |
229 |
|
return paramErr; |
230 |
< |
if ((clientGamma->gChanCnt != 1) && (clientGamma->gChanCnt != 3)) |
230 |
> |
int chan_cnt = ReadMacInt16(gamma + gChanCnt); |
231 |
> |
if (chan_cnt != 1 && chan_cnt != 3) |
232 |
|
return paramErr; |
233 |
< |
if (clientGamma->gDataWidth > 8) |
233 |
> |
int data_width = ReadMacInt16(gamma + gDataWidth); |
234 |
> |
if (data_width > 8) |
235 |
|
return paramErr; |
236 |
< |
if (clientGamma->gDataCnt != (1 << clientGamma->gDataWidth)) |
236 |
> |
int data_cnt = ReadMacInt16(gamma + gDataWidth); |
237 |
> |
if (data_cnt != (1 << data_width)) |
238 |
|
return paramErr; |
239 |
|
|
240 |
< |
uint32 tableSize = sizeof(GammaTbl) // fixed size header |
241 |
< |
+ clientGamma->gFormulaSize // add formula size |
242 |
< |
+ clientGamma->gChanCnt * clientGamma->gDataCnt // assume 1 byte/entry |
243 |
< |
- 2; // correct gFormulaData[0] counted twice |
238 |
< |
|
239 |
< |
// Allocate new gamma table if existing gamma table is smaller than required. |
240 |
< |
if (tableSize > csSave->maxGammaTableSize) { |
241 |
< |
delete[] csSave->gammaTable; |
242 |
< |
csSave->gammaTable = (GammaTbl *)new uint8[tableSize]; |
243 |
< |
csSave->maxGammaTableSize = tableSize; |
244 |
< |
gammaTable = csSave->gammaTable; |
245 |
< |
} |
240 |
> |
// Allocate new table, if necessary |
241 |
> |
int size = SIZEOF_GammaTbl + ReadMacInt16(gamma + gFormulaSize) + chan_cnt * data_cnt; |
242 |
> |
if (!allocate_gamma_table(csSave, size)) |
243 |
> |
return memFullErr; |
244 |
|
|
245 |
< |
// Copy gamma table header |
246 |
< |
*gammaTable = *clientGamma; |
249 |
< |
|
250 |
< |
// Copy the formula data (if any) |
251 |
< |
uint8 *newData = (uint8 *)&gammaTable->gFormulaData[0]; // Point to newGamma's formula data |
252 |
< |
uint8 *clientData = (uint8 *)&clientGamma->gFormulaData[0]; // Point to clientGamma's formula data |
253 |
< |
for (int i=0; i<gammaTable->gFormulaSize; i++) |
254 |
< |
*newData++ = *clientData++; |
255 |
< |
|
256 |
< |
// Copy the correction data. Convientiently, after copying the formula data, the 'newData' |
257 |
< |
// pointer and the 'clientData' pointer are pointing to the their respective starting points |
258 |
< |
// of their correction data. |
259 |
< |
for (int i=0; i<gammaTable->gChanCnt; i++) |
260 |
< |
for (int j=0; j<gammaTable->gDataCnt; j++) |
261 |
< |
*newData++ = *clientData++; |
245 |
> |
// Copy table |
246 |
> |
Mac2Mac_memcpy(csSave->gammaTable, gamma, size); |
247 |
|
} |
248 |
|
return noErr; |
249 |
|
} |
284 |
|
uint8 *green_gamma = NULL; |
285 |
|
uint8 *blue_gamma = NULL; |
286 |
|
int gamma_data_width = 0; |
287 |
< |
if (display_type == DIS_SCREEN && csSave->gammaTable != NULL) { // Windows are gamma-corrected by BeOS |
288 |
< |
do_gamma = true; |
289 |
< |
GammaTbl *gamma = csSave->gammaTable; |
290 |
< |
gamma_data_width = gamma->gDataWidth; |
291 |
< |
red_gamma = (uint8 *)&gamma->gFormulaData + gamma->gFormulaSize; |
292 |
< |
if (gamma->gChanCnt == 1) { |
293 |
< |
green_gamma = blue_gamma = red_gamma; |
294 |
< |
} else { |
295 |
< |
green_gamma = red_gamma + gamma->gDataCnt; |
296 |
< |
blue_gamma = red_gamma + 2 * gamma->gDataCnt; |
287 |
> |
if (csSave->gammaTable) { |
288 |
> |
#ifdef __BEOS__ |
289 |
> |
// Windows are gamma-corrected by BeOS |
290 |
> |
const bool can_do_gamma = (display_type == DIS_SCREEN); |
291 |
> |
#else |
292 |
> |
const bool can_do_gamma = true; |
293 |
> |
#endif |
294 |
> |
if (can_do_gamma) { |
295 |
> |
uint32 gamma_table = csSave->gammaTable; |
296 |
> |
red_gamma = Mac2HostAddr(gamma_table + gFormulaData + ReadMacInt16(gamma_table + gFormulaSize)); |
297 |
> |
int chan_cnt = ReadMacInt16(gamma_table + gChanCnt); |
298 |
> |
if (chan_cnt == 1) |
299 |
> |
green_gamma = blue_gamma = red_gamma; |
300 |
> |
else { |
301 |
> |
int ofs = ReadMacInt16(gamma_table + gDataCnt); |
302 |
> |
green_gamma = red_gamma + ofs; |
303 |
> |
blue_gamma = green_gamma + ofs; |
304 |
> |
} |
305 |
> |
gamma_data_width = ReadMacInt16(gamma_table + gDataWidth); |
306 |
> |
do_gamma = true; |
307 |
|
} |
308 |
|
} |
309 |
|
|
351 |
|
return noErr; |
352 |
|
} |
353 |
|
|
354 |
< |
case cscSetGamma: // SetGamma |
355 |
< |
D(bug("SetGamma\n")); |
356 |
< |
return set_gamma(csSave, ReadMacInt32(param)); |
354 |
> |
case cscSetGamma: { // SetGamma |
355 |
> |
uint32 user_table = ReadMacInt32(param + csGTable); |
356 |
> |
D(bug("SetGamma %08x\n", user_table)); |
357 |
> |
return set_gamma(csSave, ReadMacInt32(user_table)); |
358 |
> |
} |
359 |
|
|
360 |
|
case cscGrayPage: { // GrayPage |
361 |
|
D(bug("GrayPage %d\n", ReadMacInt16(param + csPage))); |
882 |
|
switch (commandCode) { |
883 |
|
case kInitializeCommand: |
884 |
|
case kReplaceCommand: |
885 |
< |
if (private_data != NULL) // Might be left over from a reboot |
886 |
< |
delete private_data->gammaTable; |
885 |
> |
if (private_data != NULL) { // Might be left over from a reboot |
886 |
> |
if (private_data->gammaTable) |
887 |
> |
Mac_sysfree(private_data->gammaTable); |
888 |
> |
} |
889 |
|
delete private_data; |
890 |
|
|
891 |
|
iocic_tvect = FindLibSymbol("\021DriverServicesLib", "\023IOCommandIsComplete"); |
925 |
|
} |
926 |
|
|
927 |
|
private_data = new VidLocals; |
928 |
< |
private_data->gammaTable = NULL; |
928 |
> |
private_data->gammaTable = 0; |
929 |
|
Mac2Host_memcpy(&private_data->regEntryID, commandContents + 2, 16); // DriverInitInfo.deviceEntry |
930 |
|
private_data->interruptsEnabled = false; // Disable interrupts |
931 |
|
break; |
932 |
|
|
933 |
|
case kFinalizeCommand: |
934 |
|
case kSupersededCommand: |
935 |
< |
if (private_data != NULL) |
936 |
< |
delete private_data->gammaTable; |
935 |
> |
if (private_data != NULL && private_data->gammaTable) |
936 |
> |
Mac_sysfree(private_data->gammaTable); |
937 |
|
delete private_data; |
938 |
|
private_data = NULL; |
939 |
|
break; |