mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-12 16:30:44 +00:00
little endian fixes to gamma handling code
This commit is contained in:
parent
6ecaec47d9
commit
6b89caf030
@ -108,14 +108,12 @@ extern rgb_color mac_pal[256];
|
|||||||
extern uint8 remap_mac_be[256];
|
extern uint8 remap_mac_be[256];
|
||||||
extern uint8 MacCursor[68];
|
extern uint8 MacCursor[68];
|
||||||
|
|
||||||
struct GammaTbl;
|
|
||||||
|
|
||||||
struct VidLocals{
|
struct VidLocals{
|
||||||
uint16 saveMode;
|
uint16 saveMode;
|
||||||
uint32 saveData;
|
uint32 saveData;
|
||||||
uint16 savePage;
|
uint16 savePage;
|
||||||
uint32 saveBaseAddr;
|
uint32 saveBaseAddr;
|
||||||
GammaTbl *gammaTable; // Current gamma table
|
uint32 gammaTable; // Mac address of gamma tble
|
||||||
uint32 maxGammaTableSize; // Biggest gamma table allocated
|
uint32 maxGammaTableSize; // Biggest gamma table allocated
|
||||||
uint32 saveVidParms;
|
uint32 saveVidParms;
|
||||||
bool luminanceMapping; // Luminance mapping on/off
|
bool luminanceMapping; // Luminance mapping on/off
|
||||||
|
@ -216,6 +216,10 @@ enum { // VDSetEntry struct
|
|||||||
csCount = 6
|
csCount = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum { // VDGammaRecord
|
||||||
|
csGTable = 0
|
||||||
|
};
|
||||||
|
|
||||||
enum { // ColorSpec table entry
|
enum { // ColorSpec table entry
|
||||||
csValue = 0,
|
csValue = 0,
|
||||||
csRed = 2,
|
csRed = 2,
|
||||||
@ -281,14 +285,15 @@ enum { // VDDrawHardwareCursor/VDHardwareCursorDrawState struct
|
|||||||
csCursorSet = 12
|
csCursorSet = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GammaTbl {
|
enum { // struct GammaTbl
|
||||||
uint16 gVersion;
|
gVersion = 0,
|
||||||
uint16 gType;
|
gType = 2,
|
||||||
uint16 gFormulaSize;
|
gFormulaSize = 4,
|
||||||
uint16 gChanCnt;
|
gChanCnt = 6,
|
||||||
uint16 gDataCnt;
|
gDataCnt = 8,
|
||||||
uint16 gDataWidth;
|
gDataWidth = 10,
|
||||||
uint16 gFormulaData[1];
|
gFormulaData = 12, // variable size
|
||||||
|
SIZEOF_GammaTbl = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -156,15 +156,15 @@ static int16 VideoOpen(uint32 pb, VidLocals *csSave)
|
|||||||
csSave->saveMode = VModes[cur_mode].viAppleMode;
|
csSave->saveMode = VModes[cur_mode].viAppleMode;
|
||||||
csSave->savePage = 0;
|
csSave->savePage = 0;
|
||||||
csSave->saveVidParms = 0; // Add the right table
|
csSave->saveVidParms = 0; // Add the right table
|
||||||
csSave->gammaTable = NULL; // No gamma table yet
|
|
||||||
csSave->maxGammaTableSize = 0;
|
|
||||||
csSave->luminanceMapping = false;
|
csSave->luminanceMapping = false;
|
||||||
csSave->cursorX = 0;
|
csSave->cursorX = 0;
|
||||||
csSave->cursorY = 0;
|
csSave->cursorY = 0;
|
||||||
csSave->cursorVisible = 0;
|
csSave->cursorVisible = 0;
|
||||||
csSave->cursorSet = 0;
|
csSave->cursorSet = 0;
|
||||||
|
|
||||||
// Activate default gamma table
|
// Find and set default gamma table
|
||||||
|
csSave->gammaTable = 0;
|
||||||
|
csSave->maxGammaTableSize = 0;
|
||||||
set_gamma(csSave, 0);
|
set_gamma(csSave, 0);
|
||||||
|
|
||||||
// Install and activate interrupt service
|
// Install and activate interrupt service
|
||||||
@ -182,83 +182,68 @@ static int16 VideoOpen(uint32 pb, VidLocals *csSave)
|
|||||||
* Video driver control routine
|
* Video driver control routine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static bool allocate_gamma_table(VidLocals *csSave, uint32 size)
|
||||||
|
{
|
||||||
|
if (size > csSave->maxGammaTableSize) {
|
||||||
|
if (csSave->gammaTable) {
|
||||||
|
Mac_sysfree(csSave->gammaTable);
|
||||||
|
csSave->gammaTable = 0;
|
||||||
|
csSave->maxGammaTableSize = 0;
|
||||||
|
}
|
||||||
|
if ((csSave->gammaTable = Mac_sysalloc(size)) == 0)
|
||||||
|
return false;
|
||||||
|
csSave->maxGammaTableSize = size;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int16 set_gamma(VidLocals *csSave, uint32 gamma)
|
static int16 set_gamma(VidLocals *csSave, uint32 gamma)
|
||||||
{
|
{
|
||||||
#warning "FIXME: this code is not little endian aware"
|
return paramErr;
|
||||||
GammaTbl *clientGamma = (GammaTbl *)gamma;
|
|
||||||
GammaTbl *gammaTable = csSave->gammaTable;
|
|
||||||
|
|
||||||
if (clientGamma == NULL) {
|
if (gamma == 0) { // Build linear ramp, 256 entries
|
||||||
|
|
||||||
// No gamma table supplied, build linear ramp
|
// Allocate new table, if necessary
|
||||||
uint32 linearRampSize = sizeof(GammaTbl) + 256 - 2;
|
if (!allocate_gamma_table(csSave, SIZEOF_GammaTbl + 256))
|
||||||
uint8 *correctionData;
|
return memFullErr;
|
||||||
|
|
||||||
// Allocate new gamma table if existing gamma table is smaller than required.
|
// Initialize header
|
||||||
if (linearRampSize > csSave->maxGammaTableSize) {
|
WriteMacInt16(csSave->gammaTable + gVersion, 0); // A version 0 style of the GammaTbl structure
|
||||||
delete[] csSave->gammaTable;
|
WriteMacInt16(csSave->gammaTable + gType, 0); // Frame buffer hardware invariant
|
||||||
csSave->gammaTable = (GammaTbl *)new uint8[linearRampSize];
|
WriteMacInt16(csSave->gammaTable + gFormulaSize, 0); // No formula data, just correction data
|
||||||
csSave->maxGammaTableSize = linearRampSize;
|
WriteMacInt16(csSave->gammaTable + gChanCnt, 1); // Apply same correction to Red, Green, & Blue
|
||||||
gammaTable = csSave->gammaTable;
|
WriteMacInt16(csSave->gammaTable + gDataCnt, 256); // gDataCnt == 2^^gDataWidth
|
||||||
}
|
WriteMacInt16(csSave->gammaTable + gDataWidth, 8); // 8 bits of significant data per entry
|
||||||
|
|
||||||
gammaTable->gVersion = 0; // A version 0 style of the GammaTbl structure
|
|
||||||
gammaTable->gType = 0; // Frame buffer hardware invariant
|
|
||||||
gammaTable->gFormulaSize = 0; // No formula data, just correction data
|
|
||||||
gammaTable->gChanCnt = 1; // Apply same correction to Red, Green, & Blue
|
|
||||||
gammaTable->gDataCnt = 256; // gDataCnt == 2^^gDataWidth
|
|
||||||
gammaTable->gDataWidth = 8; // 8 bits of significant data per entry
|
|
||||||
|
|
||||||
// Find the starting address of the correction data. This can be computed by starting at
|
|
||||||
// the address of gFormula[0] and adding the gFormulaSize.
|
|
||||||
correctionData = (uint8 *)((uint32)&gammaTable->gFormulaData[0] + gammaTable->gFormulaSize);
|
|
||||||
|
|
||||||
// Build the linear ramp
|
// Build the linear ramp
|
||||||
for (int i=0; i<gammaTable->gDataCnt; i++)
|
uint32 p = csSave->gammaTable + gFormulaData;
|
||||||
*correctionData++ = i;
|
for (int i=0; i<256; i++)
|
||||||
|
WriteMacInt8(p + i, i);
|
||||||
|
|
||||||
} else {
|
} else { // User-supplied gamma table
|
||||||
|
|
||||||
// User supplied a gamma table, so make sure it is a valid one
|
// Validate header
|
||||||
if (clientGamma->gVersion != 0)
|
if (ReadMacInt16(gamma + gVersion) != 0)
|
||||||
return paramErr;
|
return paramErr;
|
||||||
if (clientGamma->gType != 0)
|
if (ReadMacInt16(gamma + gType) != 0)
|
||||||
return paramErr;
|
return paramErr;
|
||||||
if ((clientGamma->gChanCnt != 1) && (clientGamma->gChanCnt != 3))
|
int chan_cnt = ReadMacInt16(gamma + gChanCnt);
|
||||||
|
if (chan_cnt != 1 && chan_cnt != 3)
|
||||||
return paramErr;
|
return paramErr;
|
||||||
if (clientGamma->gDataWidth > 8)
|
int data_width = ReadMacInt16(gamma + gDataWidth);
|
||||||
|
if (data_width > 8)
|
||||||
return paramErr;
|
return paramErr;
|
||||||
if (clientGamma->gDataCnt != (1 << clientGamma->gDataWidth))
|
int data_cnt = ReadMacInt16(gamma + gDataWidth);
|
||||||
|
if (data_cnt != (1 << data_width))
|
||||||
return paramErr;
|
return paramErr;
|
||||||
|
|
||||||
uint32 tableSize = sizeof(GammaTbl) // fixed size header
|
// Allocate new table, if necessary
|
||||||
+ clientGamma->gFormulaSize // add formula size
|
int size = SIZEOF_GammaTbl + ReadMacInt16(gamma + gFormulaSize) + chan_cnt * data_cnt;
|
||||||
+ clientGamma->gChanCnt * clientGamma->gDataCnt // assume 1 byte/entry
|
if (!allocate_gamma_table(csSave, size))
|
||||||
- 2; // correct gFormulaData[0] counted twice
|
return memFullErr;
|
||||||
|
|
||||||
// Allocate new gamma table if existing gamma table is smaller than required.
|
// Copy table
|
||||||
if (tableSize > csSave->maxGammaTableSize) {
|
Mac2Mac_memcpy(csSave->gammaTable, gamma, size);
|
||||||
delete[] csSave->gammaTable;
|
|
||||||
csSave->gammaTable = (GammaTbl *)new uint8[tableSize];
|
|
||||||
csSave->maxGammaTableSize = tableSize;
|
|
||||||
gammaTable = csSave->gammaTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy gamma table header
|
|
||||||
*gammaTable = *clientGamma;
|
|
||||||
|
|
||||||
// Copy the formula data (if any)
|
|
||||||
uint8 *newData = (uint8 *)&gammaTable->gFormulaData[0]; // Point to newGamma's formula data
|
|
||||||
uint8 *clientData = (uint8 *)&clientGamma->gFormulaData[0]; // Point to clientGamma's formula data
|
|
||||||
for (int i=0; i<gammaTable->gFormulaSize; i++)
|
|
||||||
*newData++ = *clientData++;
|
|
||||||
|
|
||||||
// Copy the correction data. Convientiently, after copying the formula data, the 'newData'
|
|
||||||
// pointer and the 'clientData' pointer are pointing to the their respective starting points
|
|
||||||
// of their correction data.
|
|
||||||
for (int i=0; i<gammaTable->gChanCnt; i++)
|
|
||||||
for (int j=0; j<gammaTable->gDataCnt; j++)
|
|
||||||
*newData++ = *clientData++;
|
|
||||||
}
|
}
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
@ -299,16 +284,26 @@ static int16 VideoControl(uint32 pb, VidLocals *csSave)
|
|||||||
uint8 *green_gamma = NULL;
|
uint8 *green_gamma = NULL;
|
||||||
uint8 *blue_gamma = NULL;
|
uint8 *blue_gamma = NULL;
|
||||||
int gamma_data_width = 0;
|
int gamma_data_width = 0;
|
||||||
if (display_type == DIS_SCREEN && csSave->gammaTable != NULL) { // Windows are gamma-corrected by BeOS
|
if (csSave->gammaTable) {
|
||||||
do_gamma = true;
|
#ifdef __BEOS__
|
||||||
GammaTbl *gamma = csSave->gammaTable;
|
// Windows are gamma-corrected by BeOS
|
||||||
gamma_data_width = gamma->gDataWidth;
|
const bool can_do_gamma = (display_type == DIS_SCREEN);
|
||||||
red_gamma = (uint8 *)&gamma->gFormulaData + gamma->gFormulaSize;
|
#else
|
||||||
if (gamma->gChanCnt == 1) {
|
const bool can_do_gamma = true;
|
||||||
green_gamma = blue_gamma = red_gamma;
|
#endif
|
||||||
} else {
|
if (can_do_gamma) {
|
||||||
green_gamma = red_gamma + gamma->gDataCnt;
|
uint32 gamma_table = csSave->gammaTable;
|
||||||
blue_gamma = red_gamma + 2 * gamma->gDataCnt;
|
red_gamma = Mac2HostAddr(gamma_table + gFormulaData + ReadMacInt16(gamma_table + gFormulaSize));
|
||||||
|
int chan_cnt = ReadMacInt16(gamma_table + gChanCnt);
|
||||||
|
if (chan_cnt == 1)
|
||||||
|
green_gamma = blue_gamma = red_gamma;
|
||||||
|
else {
|
||||||
|
int ofs = ReadMacInt16(gamma_table + gDataCnt);
|
||||||
|
green_gamma = red_gamma + ofs;
|
||||||
|
blue_gamma = green_gamma + ofs;
|
||||||
|
}
|
||||||
|
gamma_data_width = ReadMacInt16(gamma_table + gDataWidth);
|
||||||
|
do_gamma = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,9 +351,11 @@ static int16 VideoControl(uint32 pb, VidLocals *csSave)
|
|||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
case cscSetGamma: // SetGamma
|
case cscSetGamma: { // SetGamma
|
||||||
D(bug("SetGamma\n"));
|
uint32 user_table = ReadMacInt32(param + csGTable);
|
||||||
return set_gamma(csSave, ReadMacInt32(param));
|
D(bug("SetGamma %08x\n", user_table));
|
||||||
|
return set_gamma(csSave, ReadMacInt32(user_table));
|
||||||
|
}
|
||||||
|
|
||||||
case cscGrayPage: { // GrayPage
|
case cscGrayPage: { // GrayPage
|
||||||
D(bug("GrayPage %d\n", ReadMacInt16(param + csPage)));
|
D(bug("GrayPage %d\n", ReadMacInt16(param + csPage)));
|
||||||
@ -885,8 +882,10 @@ int16 VideoDoDriverIO(uint32 spaceID, uint32 commandID, uint32 commandContents,
|
|||||||
switch (commandCode) {
|
switch (commandCode) {
|
||||||
case kInitializeCommand:
|
case kInitializeCommand:
|
||||||
case kReplaceCommand:
|
case kReplaceCommand:
|
||||||
if (private_data != NULL) // Might be left over from a reboot
|
if (private_data != NULL) { // Might be left over from a reboot
|
||||||
delete private_data->gammaTable;
|
if (private_data->gammaTable)
|
||||||
|
Mac_sysfree(private_data->gammaTable);
|
||||||
|
}
|
||||||
delete private_data;
|
delete private_data;
|
||||||
|
|
||||||
iocic_tvect = FindLibSymbol("\021DriverServicesLib", "\023IOCommandIsComplete");
|
iocic_tvect = FindLibSymbol("\021DriverServicesLib", "\023IOCommandIsComplete");
|
||||||
@ -926,15 +925,15 @@ int16 VideoDoDriverIO(uint32 spaceID, uint32 commandID, uint32 commandContents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private_data = new VidLocals;
|
private_data = new VidLocals;
|
||||||
private_data->gammaTable = NULL;
|
private_data->gammaTable = 0;
|
||||||
Mac2Host_memcpy(&private_data->regEntryID, commandContents + 2, 16); // DriverInitInfo.deviceEntry
|
Mac2Host_memcpy(&private_data->regEntryID, commandContents + 2, 16); // DriverInitInfo.deviceEntry
|
||||||
private_data->interruptsEnabled = false; // Disable interrupts
|
private_data->interruptsEnabled = false; // Disable interrupts
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kFinalizeCommand:
|
case kFinalizeCommand:
|
||||||
case kSupersededCommand:
|
case kSupersededCommand:
|
||||||
if (private_data != NULL)
|
if (private_data != NULL && private_data->gammaTable)
|
||||||
delete private_data->gammaTable;
|
Mac_sysfree(private_data->gammaTable);
|
||||||
delete private_data;
|
delete private_data;
|
||||||
private_data = NULL;
|
private_data = NULL;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user