GB Palette editing (saving doesn't work yet).

More built-in palettes.
Palettes now fade to white correctly instead of getting brighter.
Star Wars, TMNT, Lord Of The Rings, Wii Controls.
Some (disabled) logging functions.
This commit is contained in:
Carl.Kenner 2009-05-27 17:31:18 +00:00
parent 600f410e48
commit 16e3e02d15
17 changed files with 1923 additions and 152 deletions

View File

@ -256,6 +256,10 @@ bool MakeFilePath(char filepath[], int type, int method, char * filename, int fi
sprintf(folder, appPath);
sprintf(file, "%s", PREF_FILE_NAME);
break;
case FILE_PAL:
sprintf(folder, appPath);
sprintf(file, "%s", PAL_FILE_NAME);
break;
}
switch(method)
{

View File

@ -151,6 +151,102 @@ u32 LegoStarWars2Input(unsigned short pad) {
return J;
}
u32 SWObiWanInput(unsigned short pad) {
u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad);
// Rumble when they lose health!
u8 Health = gbReadMemory(0xCFF2);
static u8 OldHealth = 0;
if (Health < OldHealth)
systemGameRumble(20);
OldHealth = Health;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
// Start/Select
if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp->btns_h & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp->exp.type == WPAD_EXP_NONE) {
J |= DecodeWiimote(pad);
} else if (wp->exp.type == WPAD_EXP_NUNCHUK) {
// use the force
if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) {
gbWriteMemory(0xCFF1, 2);
J |= VBA_BUTTON_A;
}
// Jump
if (wp->btns_h & WPAD_BUTTON_A)
J |= VBA_BUTTON_B;
// Shoot
if (wp->btns_h & WPAD_BUTTON_B) {
gbWriteMemory(0xCFF1, 0);
J |= VBA_BUTTON_A;
}
// Light saber
if (fabs(wp->gforce.x)> 1.5 ) {
gbWriteMemory(0xCFF1, 1);
J |= VBA_BUTTON_A;
}
if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2)
J |= VBA_SPEED;
} else if (wp->exp.type == WPAD_EXP_CLASSIC) {
J |= DecodeClassic(pad);
}
#endif
return J;
}
u32 SWEpisode2Input(unsigned short pad) {
u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad);
// Rumble when they lose health!
u8 Health = CPUReadByte(0x3002fb3);
static u8 OldHealth = 0;
if (Health < OldHealth)
systemGameRumble(6);
OldHealth = Health;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
// Start/Select
if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp->btns_h & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp->exp.type == WPAD_EXP_NONE) {
J |= DecodeWiimote(pad);
} else if (wp->exp.type == WPAD_EXP_NUNCHUK) {
// Jump
if (wp->btns_h & WPAD_BUTTON_A)
J |= VBA_BUTTON_B;
// Shoot (N/A)
if (wp->btns_h & WPAD_BUTTON_B) {
J |= VBA_BUTTON_A;
}
// Light saber
if (fabs(wp->gforce.x)> 1.5 ) {
J |= VBA_BUTTON_A;
}
if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2)
J |= VBA_SPEED;
// CAKTODO
if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) {
J |= VBA_BUTTON_L;
}
if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) {
J |= VBA_BUTTON_R;
}
} else if (wp->exp.type == WPAD_EXP_CLASSIC) {
J |= DecodeClassic(pad);
}
#endif
return J;
}
u32 TMNTInput(unsigned short pad) {
u32 J = StandardMovement(pad) | StandardDPad(pad) | DecodeKeyboard(pad);
static u32 LastDir = VBA_RIGHT;
@ -588,6 +684,95 @@ u32 TMNTGBAInput(unsigned short pad) {
return J;
}
u32 TMNTGBA2Input(unsigned short pad) {
u32 J = StandardMovement(pad) | StandardDPad(pad) | DecodeKeyboard(pad);
static u32 LastDir = VBA_RIGHT;
static bool wait = false;
static int holdcount = 0;
bool Jump=0, Attack=0, SpinKick=0, SpecialMove=0, Pause=0, Select=0, Look=0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
if (wp->exp.type == WPAD_EXP_NUNCHUK) {
Jump = (wp->btns_h & WPAD_BUTTON_A);
Attack = (fabs(wp->gforce.x)> 1.5) || (wp->btns_h & WPAD_BUTTON_B);
SpinKick = (fabs(wp->exp.nunchuk.gforce.x)> 0.5);
SpecialMove = (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z);
Pause = (wp->btns_h & WPAD_BUTTON_PLUS);
Select = (wp->btns_h & WPAD_BUTTON_MINUS);
Look = (wp->btns_h & WPAD_NUNCHUK_BUTTON_C);
// Swap Turtles or super turtle summon
if (wp->btns_h & WPAD_BUTTON_B) {
//J |= VBA_BUTTON_START;
}
} else if (wp->exp.type == WPAD_EXP_CLASSIC) {
Jump = (wp->btns_h & WPAD_CLASSIC_BUTTON_B);
Attack = (wp->btns_h & WPAD_CLASSIC_BUTTON_A);
SpinKick = (wp->btns_h & WPAD_CLASSIC_BUTTON_X);
Pause = (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS);
Select = (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS);
SpecialMove = (wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_ZR));
Look = (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL);
// Swap Turtles or super turtle summon
if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) {
//J |= VBA_BUTTON_START;
}
} else {
Jump = (wp->btns_h & WPAD_BUTTON_A);
Attack = (fabs(wp->gforce.x)> 1.5) || (wp->btns_h & WPAD_BUTTON_B);
Pause = (wp->btns_h & WPAD_BUTTON_PLUS);
Select = (wp->btns_h & WPAD_BUTTON_MINUS);
// Swap Turtles or super turtle summon
if (wp->btns_h & WPAD_BUTTON_B) {
Look = true;
}
SpinKick = (wp->btns_h & WPAD_BUTTON_1);
SpecialMove = (wp->btns_h & WPAD_BUTTON_2);
}
#endif
u32 gc = PAD_ButtonsHeld(pad);
u32 released = PAD_ButtonsUp(pad);
// DPad moves
if (gc & PAD_BUTTON_UP)
J |= VBA_UP;
if (gc & PAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (gc & PAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (gc & PAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
// Jump
if (gc & PAD_BUTTON_A) J |= VBA_BUTTON_A;
// Swap turtles
if (gc & PAD_BUTTON_B) {
Look = true;
}
// Attack
if (gc & PAD_BUTTON_X) Attack = true;
// Spin kick
if (gc & PAD_BUTTON_Y) SpinKick = true;
// Pause
if (gc & PAD_BUTTON_START) Pause = true;
// Select
if (gc & PAD_TRIGGER_Z) Select = true;
// SpecialMove
if (gc & PAD_TRIGGER_L || gc & PAD_TRIGGER_R) SpecialMove = true;
if (Jump) J |= VBA_BUTTON_A;
if (Attack) J |= VBA_BUTTON_B;
if (SpinKick) J |= VBA_BUTTON_R;
if (Pause) J |= VBA_BUTTON_START;
if (Select) J |= VBA_BUTTON_SELECT;
if (SpecialMove) {
J |= VBA_UP | VBA_BUTTON_A; // CAKTODO, currently works for Don and Mike
}
if (J & VBA_RIGHT) LastDir = VBA_RIGHT;
else if (J & VBA_LEFT) LastDir = VBA_LEFT;
return J;
}
u32 HarryPotter1GBCInput(unsigned short pad) {
u32 J = StandardMovement(pad) | StandardDPad(pad) | DecodeKeyboard(pad)
| DecodeGamecube(pad);
@ -1289,3 +1474,143 @@ u32 OnePieceInput(unsigned short pad) {
return J;
}
u32 HobbitInput(unsigned short pad) {
// Only Nunchuk and Keyboard controls available
// Wiimote, Gamecube and Classic controls depend on user configuration
u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DPadWASD(pad) |
DPadArrowKeys(pad) | DecodeWiimote(pad) | DecodeClassic(pad);
bool AbilityButton=0, AttackButton=0, UseButton=0, ChangeSkillButton=0, PauseButton=0,
ItemsButton=0, SpeedButton=0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
// Nunchuk controls are made up
if (wp->exp.type == WPAD_EXP_NUNCHUK) {
J |= StandardDPad(pad);
AbilityButton = wp->btns_h & WPAD_BUTTON_B;
UseButton = wp->btns_h & WPAD_BUTTON_A;
PauseButton = wp->btns_h & WPAD_BUTTON_PLUS;
ItemsButton = wp->btns_h & WPAD_BUTTON_MINUS;
SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C;
ChangeSkillButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z;
AttackButton = (fabs(wp->gforce.x)> 1.5);
}
#endif
if (DownUsbKeys[KB_E]) UseButton = true;
if (DownUsbKeys[KB_LSHIFT]) {
if (DownUsbKeys[KB_MOUSEL] || DownUsbKeys[KB_MOUSER]) AbilityButton = true;
} else {
if (DownUsbKeys[KB_MOUSEL] || DownUsbKeys[KB_MOUSER]) AttackButton = true;
}
if (DownUsbKeys[KB_F5]) AbilityButton = true;
if (DownUsbKeys[KB_LCTRL]) AttackButton = true;
if (DownUsbKeys[KB_SPACE]) AttackButton = true;
if (DownUsbKeys[KB_Q]) AttackButton = true;
if (DownUsbKeys[KB_C]) ChangeSkillButton = true;
if (DownUsbKeys[KB_ENTER]) ItemsButton = true;
if (DownUsbKeys[KB_BKSP]) PauseButton = true;
if (DownUsbKeys[KB_F]) SpeedButton = true;
if (AbilityButton) J |= VBA_BUTTON_B;
if (AttackButton) J |= VBA_BUTTON_L;
if (ChangeSkillButton) J |= VBA_BUTTON_L;
if (ItemsButton) J |= VBA_BUTTON_SELECT;
if (UseButton) J |= VBA_BUTTON_A;
if (SpeedButton) J |= VBA_BUTTON_R;
if (PauseButton) J |= VBA_BUTTON_START;
return J;
}
u32 FellowshipOfTheRingInput(unsigned short pad) {
// Only Nunchuk and Keyboard controls available
// Wiimote, Gamecube and Classic controls depend on user configuration
u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DPadWASD(pad) |
DPadArrowKeys(pad) | DecodeWiimote(pad) | DecodeClassic(pad);
bool CancelButton=0, UseButton=0, ChangeCharButton=0, PauseButton=0,
ItemsButton=0, SpeedButton=0, SelectButton=0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
// Nunchuk controls are made up
if (wp->exp.type == WPAD_EXP_NUNCHUK) {
J |= StandardDPad(pad);
CancelButton = wp->btns_h & WPAD_BUTTON_B;
UseButton = wp->btns_h & WPAD_BUTTON_A;
PauseButton = wp->btns_h & WPAD_BUTTON_PLUS;
ItemsButton = wp->btns_h & WPAD_BUTTON_MINUS;
SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C;
ChangeCharButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z;
CancelButton = CancelButton || (fabs(wp->gforce.x)> 1.5);
SelectButton = wp->btns_h & WPAD_BUTTON_1;
}
#endif
if (DownUsbKeys[KB_E]) UseButton = true;
if (DownUsbKeys[KB_Q]) CancelButton = true;
if (DownUsbKeys[KB_MOUSEL]) UseButton = true;
if (DownUsbKeys[KB_MOUSER]) CancelButton = true;
if (DownUsbKeys[KB_C]) ChangeCharButton = true;
if (DownUsbKeys[KB_ENTER]) PauseButton = true;
if (DownUsbKeys[KB_BKSP]) ItemsButton = true;
if (DownUsbKeys[KB_TAB]) SelectButton = true;
if (DownUsbKeys[KB_F]) SpeedButton = true;
if (DownUsbKeys[KB_SPACE]) SpeedButton = true;
if (DownUsbKeys[KB_F5]) UseButton = true;
if (DownUsbKeys[KB_LCTRL]) UseButton = true;
if (UseButton) J |= VBA_BUTTON_A;
if (CancelButton) J |= VBA_BUTTON_B;
if (ChangeCharButton) J |= VBA_BUTTON_L;
if (ItemsButton) J |= VBA_BUTTON_R;
if (SpeedButton) J |= VBA_SPEED;
if (PauseButton) J |= VBA_BUTTON_START;
if (SelectButton) J |= VBA_BUTTON_SELECT;
return J;
}
u32 ReturnOfTheKingInput(unsigned short pad) {
// Only Nunchuk and Keyboard controls available
// Wiimote, Gamecube and Classic controls depend on user configuration
u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DPadWASD(pad) |
DPadArrowKeys(pad) | DecodeWiimote(pad) | DecodeClassic(pad);
bool AbilityButton=0, AttackButton=0, UseButton=0, ChangeSkillButton=0, PauseButton=0,
ItemsButton=0, SpeedButton=0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
// Nunchuk controls are made up
if (wp->exp.type == WPAD_EXP_NUNCHUK) {
J |= StandardDPad(pad);
AbilityButton = wp->btns_h & WPAD_BUTTON_B;
UseButton = wp->btns_h & WPAD_BUTTON_A;
PauseButton = wp->btns_h & WPAD_BUTTON_PLUS;
ItemsButton = wp->btns_h & WPAD_BUTTON_MINUS;
SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C;
ChangeSkillButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z;
AttackButton = (fabs(wp->gforce.x)> 1.5);
}
#endif
if (DownUsbKeys[KB_E]) UseButton = true;
if (DownUsbKeys[KB_LSHIFT]) {
if (DownUsbKeys[KB_MOUSEL] || DownUsbKeys[KB_MOUSER]) AbilityButton = true;
} else {
if (DownUsbKeys[KB_MOUSEL] || DownUsbKeys[KB_MOUSER]) AttackButton = true;
}
if (DownUsbKeys[KB_F5]) AbilityButton = true;
if (DownUsbKeys[KB_LCTRL]) AttackButton = true;
if (DownUsbKeys[KB_SPACE]) AttackButton = true;
if (DownUsbKeys[KB_Q]) AttackButton = true;
if (DownUsbKeys[KB_C]) ChangeSkillButton = true;
if (DownUsbKeys[KB_ENTER]) ItemsButton = true;
if (DownUsbKeys[KB_BKSP]) PauseButton = true;
if (DownUsbKeys[KB_F]) SpeedButton = true;
if (AbilityButton) J |= VBA_BUTTON_A;
if (AttackButton) J |= VBA_BUTTON_B;
if (ChangeSkillButton) J |= VBA_BUTTON_L;
if (ItemsButton) J |= VBA_BUTTON_START;
if (UseButton) J |= VBA_BUTTON_R;
if (SpeedButton) J |= VBA_SPEED;
if (PauseButton) J |= VBA_BUTTON_SELECT;
return J;
}

View File

@ -53,6 +53,7 @@
#define TMNT2 0xFF000C
#define TMNT3 0xFF000D
#define TMNTGBA gid('B','N','T')
#define TMNTGBA2 gid('B','T','2')
#define TMNT gid('B','E','X')
#define RESIDENTEVIL gid('B','I','O')
@ -71,9 +72,13 @@
#define MARIOKART gid('A','M','K')
#define BIONICLEHEROES gid('B','I','H')
#define LSW1 gid('B','L','W')
#define LSW2 gid('B','L','7')
#define BIONICLEHEROES gid('B','I','H')
#define SWOBIWAN gid('B','O','W')
#define SWEP2 gid('A','S','2')
#define SWNDA gid('A','2','W')
#define MK1 0xFF0002
#define MK2 0xFF0003
@ -88,6 +93,13 @@
#define ONEPIECE gid('B','O','N')
#define HOBBIT gid('A','H','9')
#define LOTR1 gid('A','L','O')
#define LOTR2 gid('A','L','P')
#define LOTR3 gid('B','L','R')
#define LOTR3RDAGE gid('B','3','A')
#define MARBLEMADNESS 0xFF000A
u8 gbReadMemory(register u16 address);
@ -116,6 +128,9 @@ u32 MarioLand1Input(unsigned short pad);
u32 MarioLand2Input(unsigned short pad);
u32 LegoStarWars1Input(unsigned short pad);
u32 LegoStarWars2Input(unsigned short pad);
u32 SWObiWanInput(unsigned short pad);
u32 SWEpisode2Input(unsigned short pad);
u32 SWNDAInput(unsigned short pad);
u32 MarioKartInput(unsigned short pad);
u32 MK1Input(unsigned short pad);
u32 MK12Input(unsigned short pad);
@ -141,6 +156,7 @@ u32 TMNT1Input(unsigned short pad);
u32 TMNT2Input(unsigned short pad);
u32 TMNT3Input(unsigned short pad);
u32 TMNTGBAInput(unsigned short pad);
u32 TMNTGBA2Input(unsigned short pad);
u32 HarryPotter1Input(unsigned short pad);
u32 HarryPotter1GBCInput(unsigned short pad);
u32 HarryPotter2Input(unsigned short pad);
@ -162,6 +178,9 @@ u32 KirbyTntInput(unsigned short pad);
u32 BoktaiInput(unsigned short pad);
u32 Boktai2Input(unsigned short pad);
u32 OnePieceInput(unsigned short pad);
u32 HobbitInput(unsigned short pad);
u32 FellowshipOfTheRingInput(unsigned short pad);
u32 ReturnOfTheKingInput(unsigned short pad);
#endif

View File

@ -12,20 +12,24 @@
#include "gamesettings.h"
int gamePalettesCount = 10;
gamePalette CurrentPalette;
int gamePalettesCount = 19;
// 0xRRGGBB
// TITLE, 4 Background Colours (brightest to black), 4 Status Bar Colours (brightest to black),
// 3 Sprite 1 Colours (brightest to dark), 3 Sprite 2 Colours (brightest to dark)
gamePalette gamePalettes[10] = {
{"", {0xFFFFFF,0xADADAD,0x636363,0x000000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFFFFFF,0xADADAD,0x636363, 0xFFFFFF,0xADADAD,0x636363}}
gamePalette gamePalettes[19] = {
{"default", {0x00FF00,0x00AD00,0x006300,0x002000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFF0000,0xAD0000,0x630000, 0x0000FF,0x0000AD,0x000063}}
,{"MAGNETIC SOCCER", {0x00FF00,0x00AD00,0x006300,0x002000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
,{"BASEBALL", {0x009000,0x006000,0x003000,0x000000, 0xFFFFFF,0xAD0000,0x630000,0x000000,
0xFFD060,0xAD0000,0x630000, 0x0050AD,0xFFD060,0x0040A0}}
,{"MAGNETIC SOCCER", {0x009000,0x006000,0x003000,0x000000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFF0000,0xAD0000,0x630000, 0x0000FF,0x0000AD,0x000063}}
,{"BEACH,VOLLEYBALL", {0xD4B4A4,0xADAD30,0x000063,0x000020, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xB49E90,0x00B000,0x31271E, 0x0000FF,0x0000AD,0x000063}}
0xB49E90,0xB00000,0x31271E, 0x0000FF,0x0000AD,0x000063}}
,{"MARBLE MADNESS", {0x00FFFF,0x00ADAD,0x006363,0x303030, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFF0000,0xAD0000,0x630000, 0xFFFF00,0xAD8000,0x634000}}
,{"METROID2", {0xFF7B30,0xAD5230,0x300063,0x000018, 0xFFFFFF,0xADADAD,0x636363,0x000000,
@ -39,6 +43,24 @@ gamePalette gamePalettes[10] = {
,{"MR.DO!", {0x38F038,0x00C800,0x705000,0x600000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFFFFFF,0xADADAD,0x636363, 0xFFFFFF,0xADADAD,0x636363}}
,{"SIMPSONS3", {0x80FF40,0x00AD50,0x006300,0x402000, 0xE0D000,0xADADAD,0x636363,0x000000,
0xF0E000,0xAD4000,0x0000FF, 0xFF0000,0xAD0000,0x630000}}
,{"SUPER MARIO LAND", {0x90A0FF,0x80AD00,0x636300,0x301800, 0xFFFF40,0xADAD00,0x636300,0x000000,
0xFFE080,0x0000AD,0xFF0000, 0xFFFFFF,0xADADAD,0x636363}}
,{"TMNT FOOT CLAN", {0xFFFF80,0xADB800,0x636300,0x302000, 0x8080FF,0x0000AD,0x000063,0x000030,
0x60A060,0x633030,0x533000, 0xFFFFFF,0xADADAD,0x636363}}
,{"TENNIS", {0x008000,0xB49E90,0x630000,0x000000, 0xFFFFFF,0xB49E90,0x630000,0x201000,
0xB4A880,0xADAD00,0x632000, 0x0000AD,0xA48E80,0x636300}}
,{"TETRIS", {0xAD0000,0x00AD00,0x0000AD,0x000000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0x00AD00,0x0000AD,0xAD0000, 0xFFFFFF,0xADADAD,0x636363}}
,{"DUCK TALES", {0x80FF00,0x68AD00,0x633100,0x201000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFFFFFF,0xAD5800,0xAD5800, 0xFFFFFF,0xADADAD,0x636363}}
,{"ALLEY WAY", {0x00FF00,0xAD0000,0x000063,0x636300, 0xFFFFFF,0xAD0000,0x630000,0x000000,
0xFF0000,0xAD0000,0x630000, 0x0000FF,0x0000AD,0x000063}}
,{"KID ICARUS", {0xFFFFFF,0xADADAD,0x314278,0x003163, 0xFFFFFF,0xAD0000,0x630000,0x000000,
0xFFFF00,0xB80000,0x436300, 0xFFFFFF,0xD4B4A4,0x633100}}
,{"", {0xFFFFFF,0xADADAD,0x636363,0x000000, 0xFFFFFF,0xADADAD,0x636363,0x000000,
0xFFFFFF,0xADADAD,0x636363, 0xFFFFFF,0xADADAD,0x636363}}
};

View File

@ -32,5 +32,6 @@ struct gamePalette {
extern gamePalette gamePalettes[];
extern int gamePalettesCount;
extern gamePalette CurrentPalette;
#endif

View File

@ -760,6 +760,8 @@ static u32 DecodeJoy(unsigned short pad)
return TMNT3Input(pad);
case TMNTGBA:
return TMNTGBAInput(pad);
case TMNTGBA2:
return TMNTGBA2Input(pad);
case TMNT:
return TMNTInput(pad);
@ -816,6 +818,12 @@ static u32 DecodeJoy(unsigned short pad)
case LSW2:
return LegoStarWars2Input(pad);
// Star Wars
case SWOBIWAN:
return SWObiWanInput(pad);
case SWEP2:
return SWEpisode2Input(pad);
// Mortal Kombat
case MK1:
return MK1Input(pad);
@ -853,6 +861,15 @@ static u32 DecodeJoy(unsigned short pad)
// One Piece
case ONEPIECE:
return OnePieceInput(pad);
// Lord of the Rings
case HOBBIT:
return HobbitInput(pad);
case LOTR1:
return FellowshipOfTheRingInput(pad);
case LOTR2:
case LOTR3:
return ReturnOfTheKingInput(pad);
}
// the function result, J, is a combination of flags for all the VBA buttons that are down

View File

@ -37,6 +37,7 @@
#include "gui/gui.h"
#include "menu.h"
#include "wiiusbsupport.h"
#include "gamesettings.h"
#define THREAD_SLEEP 100
@ -44,6 +45,10 @@
GuiImageData * pointer[4];
#endif
static int MenuPalette();
void gbSetPalette(u32 RRGGBB[]);
extern char RomTitle[17];
static GuiButton * btnLogo = NULL;
static GuiImage * gameScreenImg = NULL;
static GuiImage * bgImg = NULL;
@ -1838,6 +1843,10 @@ static int MenuGameSettings()
{
menu = MENU_GAMESETTINGS_VIDEO;
}
/*else if(cheatsBtn.GetState() == STATE_CLICKED)
{
menu = MENU_GAMESETTINGS_PALETTE;
}*/
else if(wiiControlsBtn.GetState() == STATE_CLICKED)
{
GCSettings.WiiControls ^= 1;
@ -2634,6 +2643,7 @@ static int MenuSettingsVideo()
int ret;
int i = 0;
OptionList options;
char Buffer[1024];
sprintf(options.name[i++], "Rendering");
sprintf(options.name[i++], "Scaling");
@ -2641,11 +2651,12 @@ static int MenuSettingsVideo()
sprintf(options.name[i++], "Screen Position");
sprintf(options.name[i++], "Video Mode");
sprintf(options.name[i++], "Colorize Mono GB");
sprintf(options.name[i++], "Choose Palette");
options.length = i;
GuiText titleTxt("Game Settings - Video", 28, (GXColor){255, 255, 255, 255});
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt.SetPosition(50,50);
titleTxt.SetPosition(50,50);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM);
GuiSound btnSoundClick(button_click_pcm, button_click_pcm_size, SOUND_PCM);
@ -2727,6 +2738,7 @@ static int MenuSettingsVideo()
sprintf (options.value[5], "On");
else
sprintf (options.value[5], "Off");
sprintf(options.value[6], "click here");
ret = optionBrowser.GetClickedOption();
@ -2767,6 +2779,10 @@ static int MenuSettingsVideo()
if (GCSettings.colorize) GCSettings.colorize = 0;
else GCSettings.colorize = 1;
break;
case 6:
menu = MENU_GAMESETTINGS_PALETTE;
break;
}
if(backBtn.GetState() == STATE_CLICKED)
@ -3497,6 +3513,9 @@ MainMenu (int menu)
/*case MENU_GAMESETTINGS_CHEATS:
currentMenu = MenuGameCheats();
break;*/
case MENU_GAMESETTINGS_PALETTE:
currentMenu = MenuPalette();
break;
case MENU_SETTINGS:
currentMenu = MenuSettings();
break;
@ -3554,3 +3573,687 @@ MainMenu (int menu)
gameScreenTex2 = NULL;
}
}
static int redAmount=128, greenAmount=128, blueAmount=128;
static GuiText *redText;
static GuiText *greenText;
static GuiText *blueText;
static GuiText *sampleText;
static void RGBWindowUpdate(void * ptr, int red, int green, int blue)
{
GuiButton * b = (GuiButton *)ptr;
if(b->GetState() == STATE_CLICKED)
{
redAmount += red;
if (redAmount>255) redAmount=255;
else if (redAmount<0) redAmount=0;
greenAmount += green;
if (greenAmount>255) greenAmount=255;
else if (greenAmount<0) greenAmount=0;
blueAmount += blue;
if (blueAmount>255) blueAmount=255;
else if (blueAmount<0) blueAmount=0;
redText->SetColor((GXColor){redAmount, 0, 0, 255});
greenText->SetColor((GXColor){0, greenAmount, 0, 255});
blueText->SetColor((GXColor){0, 0, blueAmount, 255});
sampleText->SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
char shift[10];
sprintf(shift, "%2x", redAmount);
redText->SetText(shift);
sprintf(shift, "%2x", greenAmount);
greenText->SetText(shift);
sprintf(shift, "%2x", blueAmount);
blueText->SetText(shift);
b->ResetState();
}
}
static void LessRedClick(void * ptr) { RGBWindowUpdate(ptr, -8, 0, 0); }
static void LessGreenClick(void * ptr) { RGBWindowUpdate(ptr, 0, -8, 0); }
static void LessBlueClick(void * ptr) { RGBWindowUpdate(ptr, 0, 0, -8); }
static void MoreRedClick(void * ptr) { RGBWindowUpdate(ptr, +8, 0, 0); }
static void MoreGreenClick(void * ptr) { RGBWindowUpdate(ptr, 0, +8, 0); }
static void MoreBlueClick(void * ptr) { RGBWindowUpdate(ptr, 0, 0, +8); }
static void PaletteWindow(const char *name)
{
GuiWindow * w = new GuiWindow(500,480);
w->SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
w->SetPosition(0, -10);
GuiTrigger trigA;
if(GCSettings.WiimoteOrientation)
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
else
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiImageData arrowUp(button_arrow_up_png);
GuiImageData arrowDown(button_arrow_down_png);
GuiImageData arrowUpOver(button_arrow_up_over_png);
GuiImageData arrowDownOver(button_arrow_down_over_png);
GuiImage moreRedImg(&arrowUp);
GuiImage moreRedOverImg(&arrowUpOver);
GuiButton moreRedBtn(arrowUp.GetWidth(), arrowUp.GetHeight());
moreRedBtn.SetImage(&moreRedImg);
moreRedBtn.SetImageOver(&moreRedOverImg);
moreRedBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
moreRedBtn.SetPosition(-150,-60);
moreRedBtn.SetTrigger(0, &trigA);
moreRedBtn.SetSelectable(true);
moreRedBtn.SetUpdateCallback(MoreRedClick);
GuiImage lessRedImg(&arrowDown);
GuiImage lessRedOverImg(&arrowDownOver);
GuiButton lessRedBtn(arrowDown.GetWidth(), arrowDown.GetHeight());
lessRedBtn.SetImage(&lessRedImg);
lessRedBtn.SetImageOver(&lessRedOverImg);
lessRedBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
lessRedBtn.SetPosition(-150,+50);
lessRedBtn.SetTrigger(0, &trigA);
lessRedBtn.SetSelectable(true);
lessRedBtn.SetUpdateCallback(LessRedClick);
GuiImage moreGreenImg(&arrowUp);
GuiImage moreGreenOverImg(&arrowUpOver);
GuiButton moreGreenBtn(arrowUp.GetWidth(), arrowUp.GetHeight());
moreGreenBtn.SetImage(&moreGreenImg);
moreGreenBtn.SetImageOver(&moreGreenOverImg);
moreGreenBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
moreGreenBtn.SetPosition(-50,-60);
moreGreenBtn.SetTrigger(0, &trigA);
moreGreenBtn.SetSelectable(true);
moreGreenBtn.SetUpdateCallback(MoreGreenClick);
GuiImage lessGreenImg(&arrowDown);
GuiImage lessGreenOverImg(&arrowDownOver);
GuiButton lessGreenBtn(arrowDown.GetWidth(), arrowDown.GetHeight());
lessGreenBtn.SetImage(&lessGreenImg);
lessGreenBtn.SetImageOver(&lessGreenOverImg);
lessGreenBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
lessGreenBtn.SetPosition(-50,+50);
lessGreenBtn.SetTrigger(0, &trigA);
lessGreenBtn.SetSelectable(true);
lessGreenBtn.SetUpdateCallback(LessGreenClick);
GuiImage moreBlueImg(&arrowUp);
GuiImage moreBlueOverImg(&arrowUpOver);
GuiButton moreBlueBtn(arrowUp.GetWidth(), arrowUp.GetHeight());
moreBlueBtn.SetImage(&moreBlueImg);
moreBlueBtn.SetImageOver(&moreBlueOverImg);
moreBlueBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
moreBlueBtn.SetPosition(50,-60);
moreBlueBtn.SetTrigger(0, &trigA);
moreBlueBtn.SetSelectable(true);
moreBlueBtn.SetUpdateCallback(MoreBlueClick);
GuiImage lessBlueImg(&arrowDown);
GuiImage lessBlueOverImg(&arrowDownOver);
GuiButton lessBlueBtn(arrowDown.GetWidth(), arrowDown.GetHeight());
lessBlueBtn.SetImage(&lessBlueImg);
lessBlueBtn.SetImageOver(&lessBlueOverImg);
lessBlueBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
lessBlueBtn.SetPosition(50,+50);
lessBlueBtn.SetTrigger(0, &trigA);
lessBlueBtn.SetSelectable(true);
lessBlueBtn.SetUpdateCallback(LessBlueClick);
GuiImageData box(screen_position_png);
GuiImage redBoxImg(&box);
redBoxImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
redBoxImg.SetPosition(-150, 0);
GuiImage greenBoxImg(&box);
greenBoxImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
greenBoxImg.SetPosition(-50, 0);
GuiImage blueBoxImg(&box);
blueBoxImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
blueBoxImg.SetPosition(+50, 0);
char shift[10];
redText = new GuiText(NULL, 22, (GXColor){128, 0, 0, 255});
redText->SetPosition(-150,0);
sprintf(shift, "%2x", redAmount);
redText->SetText(shift);
greenText = new GuiText(NULL, 22, (GXColor){0, 128, 0, 255});
greenText->SetPosition(-50, 0);
sprintf(shift, "%2x", greenAmount);
greenText->SetText(shift);
blueText = new GuiText(NULL, 22, (GXColor){0, 0, 128, 255});
blueText->SetPosition(+50,0);
sprintf(shift, "%2x", blueAmount);
blueText->SetText(shift);
sampleText = new GuiText(NULL, 22, (GXColor){redAmount, greenAmount, blueAmount, 255});
sampleText->SetPosition(+150,0);
sampleText->SetText(name);
int currentRed = redAmount;
int currentGreen = greenAmount;
int currentBlue = blueAmount;
w->Append(&lessRedBtn);
w->Append(&moreRedBtn);
w->Append(&lessGreenBtn);
w->Append(&moreGreenBtn);
w->Append(&lessBlueBtn);
w->Append(&moreBlueBtn);
w->Append(&redBoxImg);
w->Append(&greenBoxImg);
w->Append(&blueBoxImg);
w->Append(sampleText);
w->Append(redText);
w->Append(greenText);
w->Append(blueText);
if(!SettingWindow("Red Green Blue",w))
{
redAmount = currentRed; // undo changes
greenAmount = currentGreen;
blueAmount = currentBlue;
}
delete(w);
delete(redText);
delete(greenText);
delete(blueText);
}
GXColor GetCol(int i) {
u32 c;
if (i>=0 && i<=13) c = CurrentPalette.palette[i];
else c = 0;
u8 r = (c >> 16) & 255;
u8 g = (c >> 8) & 255;
u8 b = (c) & 255;
return (GXColor){r,g,b,255};
}
/****************************************************************************
* MenuPalette
*
* Menu displayed when returning to the menu from in-game.
***************************************************************************/
static int MenuPalette()
{
int menu = MENU_NONE;
char s[4];
GuiText titleTxt("Palette", 28, (GXColor){255, 255, 255, 255});
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt.SetPosition(50,50);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM);
GuiSound btnSoundClick(button_click_pcm, button_click_pcm_size, SOUND_PCM);
GuiImageData btnOutline(button_png);
GuiImageData btnOutlineOver(button_over_png);
GuiImageData btnLargeOutline(button_large_png);
GuiImageData btnLargeOutlineOver(button_large_over_png);
GuiImageData btnCloseOutline(button_small_png);
GuiImageData btnCloseOutlineOver(button_small_over_png);
GuiTrigger trigA;
if(GCSettings.WiimoteOrientation)
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
else
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigHome;
trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
GuiText bg0BtnTxt("BG 0", 24, GetCol(0));
GuiImage bg0BtnImg(&btnCloseOutline);
GuiImage bg0BtnImgOver(&btnCloseOutlineOver);
GuiButton bg0Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
bg0Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
bg0Btn.SetPosition(-200, 120);
bg0Btn.SetLabel(&bg0BtnTxt);
bg0Btn.SetImage(&bg0BtnImg);
bg0Btn.SetImageOver(&bg0BtnImgOver);
bg0Btn.SetSoundOver(&btnSoundOver);
bg0Btn.SetSoundClick(&btnSoundClick);
bg0Btn.SetTrigger(&trigA);
bg0Btn.SetEffectGrow();
GuiText bg1BtnTxt("BG 1", 24, GetCol(1));
GuiImage bg1BtnImg(&btnCloseOutline);
GuiImage bg1BtnImgOver(&btnCloseOutlineOver);
GuiButton bg1Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
bg1Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
bg1Btn.SetPosition(-200, 180);
bg1Btn.SetLabel(&bg1BtnTxt);
bg1Btn.SetImage(&bg1BtnImg);
bg1Btn.SetImageOver(&bg1BtnImgOver);
bg1Btn.SetSoundOver(&btnSoundOver);
bg1Btn.SetSoundClick(&btnSoundClick);
bg1Btn.SetTrigger(&trigA);
bg1Btn.SetEffectGrow();
GuiText bg2BtnTxt("BG 2", 24, GetCol(2));
GuiImage bg2BtnImg(&btnCloseOutline);
GuiImage bg2BtnImgOver(&btnCloseOutlineOver);
GuiButton bg2Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
bg2Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
bg2Btn.SetPosition(-200, 240);
bg2Btn.SetLabel(&bg2BtnTxt);
bg2Btn.SetImage(&bg2BtnImg);
bg2Btn.SetImageOver(&bg2BtnImgOver);
bg2Btn.SetSoundOver(&btnSoundOver);
bg2Btn.SetSoundClick(&btnSoundClick);
bg2Btn.SetTrigger(&trigA);
bg2Btn.SetEffectGrow();
GuiText bg3BtnTxt("BG 3", 24, GetCol(3));
GuiImage bg3BtnImg(&btnCloseOutline);
GuiImage bg3BtnImgOver(&btnCloseOutlineOver);
GuiButton bg3Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
bg3Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
bg3Btn.SetPosition(-200, 300);
bg3Btn.SetLabel(&bg3BtnTxt);
bg3Btn.SetImage(&bg3BtnImg);
bg3Btn.SetImageOver(&bg3BtnImgOver);
bg3Btn.SetSoundOver(&btnSoundOver);
bg3Btn.SetSoundClick(&btnSoundClick);
bg3Btn.SetTrigger(&trigA);
bg3Btn.SetEffectGrow();
GuiText win0BtnTxt("WIN 0", 24, GetCol(4));
GuiImage win0BtnImg(&btnCloseOutline);
GuiImage win0BtnImgOver(&btnCloseOutlineOver);
GuiButton win0Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
win0Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
win0Btn.SetPosition(-70, 120);
win0Btn.SetLabel(&win0BtnTxt);
win0Btn.SetImage(&win0BtnImg);
win0Btn.SetImageOver(&win0BtnImgOver);
win0Btn.SetSoundOver(&btnSoundOver);
win0Btn.SetSoundClick(&btnSoundClick);
win0Btn.SetTrigger(&trigA);
win0Btn.SetEffectGrow();
GuiText win1BtnTxt("WIN 1", 24, GetCol(5));
GuiImage win1BtnImg(&btnCloseOutline);
GuiImage win1BtnImgOver(&btnCloseOutlineOver);
GuiButton win1Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
win1Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
win1Btn.SetPosition(-70, 180);
win1Btn.SetLabel(&win1BtnTxt);
win1Btn.SetImage(&win1BtnImg);
win1Btn.SetImageOver(&win1BtnImgOver);
win1Btn.SetSoundOver(&btnSoundOver);
win1Btn.SetSoundClick(&btnSoundClick);
win1Btn.SetTrigger(&trigA);
win1Btn.SetEffectGrow();
GuiText win2BtnTxt("WIN 2", 24, GetCol(6));
GuiImage win2BtnImg(&btnCloseOutline);
GuiImage win2BtnImgOver(&btnCloseOutlineOver);
GuiButton win2Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
win2Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
win2Btn.SetPosition(-70, 240);
win2Btn.SetLabel(&win2BtnTxt);
win2Btn.SetImage(&win2BtnImg);
win2Btn.SetImageOver(&win2BtnImgOver);
win2Btn.SetSoundOver(&btnSoundOver);
win2Btn.SetSoundClick(&btnSoundClick);
win2Btn.SetTrigger(&trigA);
win2Btn.SetEffectGrow();
GuiText win3BtnTxt("WIN 3", 24, GetCol(7));
GuiImage win3BtnImg(&btnCloseOutline);
GuiImage win3BtnImgOver(&btnCloseOutlineOver);
GuiButton win3Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
win3Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
win3Btn.SetPosition(-70, 300);
win3Btn.SetLabel(&win3BtnTxt);
win3Btn.SetImage(&win3BtnImg);
win3Btn.SetImageOver(&win3BtnImgOver);
win3Btn.SetSoundOver(&btnSoundOver);
win3Btn.SetSoundClick(&btnSoundClick);
win3Btn.SetTrigger(&trigA);
win3Btn.SetEffectGrow();
GuiText obj0BtnTxt("OBJ 0", 24, GetCol(8));
GuiImage obj0BtnImg(&btnCloseOutline);
GuiImage obj0BtnImgOver(&btnCloseOutlineOver);
GuiButton obj0Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
obj0Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
obj0Btn.SetPosition(+70, 120);
obj0Btn.SetLabel(&obj0BtnTxt);
obj0Btn.SetImage(&obj0BtnImg);
obj0Btn.SetImageOver(&obj0BtnImgOver);
obj0Btn.SetSoundOver(&btnSoundOver);
obj0Btn.SetSoundClick(&btnSoundClick);
obj0Btn.SetTrigger(&trigA);
obj0Btn.SetEffectGrow();
GuiText obj1BtnTxt("OBJ 1", 24, GetCol(9));
GuiImage obj1BtnImg(&btnCloseOutline);
GuiImage obj1BtnImgOver(&btnCloseOutlineOver);
GuiButton obj1Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
obj1Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
obj1Btn.SetPosition(+70, 180);
obj1Btn.SetLabel(&obj1BtnTxt);
obj1Btn.SetImage(&obj1BtnImg);
obj1Btn.SetImageOver(&obj1BtnImgOver);
obj1Btn.SetSoundOver(&btnSoundOver);
obj1Btn.SetSoundClick(&btnSoundClick);
obj1Btn.SetTrigger(&trigA);
obj1Btn.SetEffectGrow();
GuiText obj2BtnTxt("OBJ 2", 24, GetCol(10));
GuiImage obj2BtnImg(&btnCloseOutline);
GuiImage obj2BtnImgOver(&btnCloseOutlineOver);
GuiButton obj2Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
obj2Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
obj2Btn.SetPosition(+70, 240);
obj2Btn.SetLabel(&obj2BtnTxt);
obj2Btn.SetImage(&obj2BtnImg);
obj2Btn.SetImageOver(&obj2BtnImgOver);
obj2Btn.SetSoundOver(&btnSoundOver);
obj2Btn.SetSoundClick(&btnSoundClick);
obj2Btn.SetTrigger(&trigA);
obj2Btn.SetEffectGrow();
GuiText spr0BtnTxt("SPR 0", 24, GetCol(11));
GuiImage spr0BtnImg(&btnCloseOutline);
GuiImage spr0BtnImgOver(&btnCloseOutlineOver);
GuiButton spr0Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
spr0Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
spr0Btn.SetPosition(+200, 120);
spr0Btn.SetLabel(&spr0BtnTxt);
spr0Btn.SetImage(&spr0BtnImg);
spr0Btn.SetImageOver(&spr0BtnImgOver);
spr0Btn.SetSoundOver(&btnSoundOver);
spr0Btn.SetSoundClick(&btnSoundClick);
spr0Btn.SetTrigger(&trigA);
spr0Btn.SetEffectGrow();
GuiText spr1BtnTxt("SPR 1", 24, GetCol(12));
GuiImage spr1BtnImg(&btnCloseOutline);
GuiImage spr1BtnImgOver(&btnCloseOutlineOver);
GuiButton spr1Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
spr1Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
spr1Btn.SetPosition(+200, 180);
spr1Btn.SetLabel(&spr1BtnTxt);
spr1Btn.SetImage(&spr1BtnImg);
spr1Btn.SetImageOver(&spr1BtnImgOver);
spr1Btn.SetSoundOver(&btnSoundOver);
spr1Btn.SetSoundClick(&btnSoundClick);
spr1Btn.SetTrigger(&trigA);
spr1Btn.SetEffectGrow();
GuiText spr2BtnTxt("SPR 2", 24, GetCol(13));
GuiImage spr2BtnImg(&btnCloseOutline);
GuiImage spr2BtnImgOver(&btnCloseOutlineOver);
GuiButton spr2Btn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
spr2Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
spr2Btn.SetPosition(+200, 240);
spr2Btn.SetLabel(&spr2BtnTxt);
spr2Btn.SetImage(&spr2BtnImg);
spr2Btn.SetImageOver(&spr2BtnImgOver);
spr2Btn.SetSoundOver(&btnSoundOver);
spr2Btn.SetSoundClick(&btnSoundClick);
spr2Btn.SetTrigger(&trigA);
spr2Btn.SetEffectGrow();
GuiText importBtnTxt("Load / Save", 24, (GXColor){0, 0, 0, 255});
importBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage importBtnImg(&btnOutline);
GuiImage importBtnImgOver(&btnOutlineOver);
GuiButton importBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
importBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
importBtn.SetPosition(140, 300);
importBtn.SetLabel(&importBtnTxt);
importBtn.SetImage(&importBtnImg);
importBtn.SetImageOver(&importBtnImgOver);
importBtn.SetSoundOver(&btnSoundOver);
importBtn.SetSoundClick(&btnSoundClick);
importBtn.SetTrigger(&trigA);
importBtn.SetEffectGrow();
GuiText closeBtnTxt("Close", 22, (GXColor){0, 0, 0, 255});
GuiImage closeBtnImg(&btnCloseOutline);
GuiImage closeBtnImgOver(&btnCloseOutlineOver);
GuiButton closeBtn(btnCloseOutline.GetWidth(), btnCloseOutline.GetHeight());
closeBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
closeBtn.SetPosition(-50, 35);
closeBtn.SetLabel(&closeBtnTxt);
closeBtn.SetImage(&closeBtnImg);
closeBtn.SetImageOver(&closeBtnImgOver);
closeBtn.SetSoundOver(&btnSoundOver);
closeBtn.SetSoundClick(&btnSoundClick);
closeBtn.SetTrigger(&trigA);
closeBtn.SetTrigger(&trigHome);
closeBtn.SetEffectGrow();
GuiText backBtnTxt("Go Back", 24, (GXColor){0, 0, 0, 255});
GuiImage backBtnImg(&btnOutline);
GuiImage backBtnImgOver(&btnOutlineOver);
GuiButton backBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
backBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
backBtn.SetPosition(100, -35);
backBtn.SetLabel(&backBtnTxt);
backBtn.SetImage(&backBtnImg);
backBtn.SetImageOver(&backBtnImgOver);
backBtn.SetSoundOver(&btnSoundOver);
backBtn.SetSoundClick(&btnSoundClick);
backBtn.SetTrigger(&trigA);
backBtn.SetEffectGrow();
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&titleTxt);
w.Append(&bg0Btn);
w.Append(&bg1Btn);
w.Append(&bg2Btn);
w.Append(&bg3Btn);
w.Append(&win0Btn);
w.Append(&win1Btn);
w.Append(&win2Btn);
w.Append(&win3Btn);
w.Append(&obj0Btn);
w.Append(&obj1Btn);
w.Append(&obj2Btn);
w.Append(&spr0Btn);
w.Append(&spr1Btn);
w.Append(&spr2Btn);
w.Append(&importBtn);
w.Append(&closeBtn);
w.Append(&backBtn);
mainWindow->Append(&w);
ResumeGui();
while(menu == MENU_NONE)
{
VIDEO_WaitVSync ();
if(bg0Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[0] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[0] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[0] >> 0) & 0xFF;
PaletteWindow("BG 0");
CurrentPalette.palette[0] = redAmount << 16 | greenAmount << 8 | blueAmount;
bg0BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
bg0Btn.ResetState();
}
else if(bg1Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[1] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[1] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[1] >> 0) & 0xFF;
PaletteWindow("BG 1");
CurrentPalette.palette[1] = redAmount << 16 | greenAmount << 8 | blueAmount;
bg1BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
bg1Btn.ResetState();
}
else if(bg2Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[2] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[2] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[2] >> 0) & 0xFF;
PaletteWindow("BG 2");
CurrentPalette.palette[2] = redAmount << 16 | greenAmount << 8 | blueAmount;
bg2BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
bg2Btn.ResetState();
}
else if(bg3Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[3] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[3] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[3] >> 0) & 0xFF;
PaletteWindow("BG 3");
CurrentPalette.palette[3] = redAmount << 16 | greenAmount << 8 | blueAmount;
bg3BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
bg3Btn.ResetState();
}
else if(win0Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[4] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[4] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[4] >> 0) & 0xFF;
PaletteWindow("WIN 0");
CurrentPalette.palette[4] = redAmount << 16 | greenAmount << 8 | blueAmount;
win0BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
win0Btn.ResetState();
}
else if(win1Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[5] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[5] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[5] >> 0) & 0xFF;
PaletteWindow("WIN 1");
CurrentPalette.palette[5] = redAmount << 16 | greenAmount << 8 | blueAmount;
win1BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
win1Btn.ResetState();
}
else if(win2Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[6] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[6] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[6] >> 0) & 0xFF;
PaletteWindow("WIN 2");
CurrentPalette.palette[6] = redAmount << 16 | greenAmount << 8 | blueAmount;
win2BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
win2Btn.ResetState();
}
else if(win3Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[7] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[7] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[7] >> 0) & 0xFF;
PaletteWindow("WIN 3");
CurrentPalette.palette[7] = redAmount << 16 | greenAmount << 8 | blueAmount;
win3BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
win3Btn.ResetState();
}
else if(obj0Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[8] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[8] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[8] >> 0) & 0xFF;
PaletteWindow("OBJ 0");
CurrentPalette.palette[8] = redAmount << 16 | greenAmount << 8 | blueAmount;
obj0BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
obj0Btn.ResetState();
}
else if(obj1Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[9] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[9] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[9] >> 0) & 0xFF;
PaletteWindow("OBJ 1");
CurrentPalette.palette[9] = redAmount << 16 | greenAmount << 8 | blueAmount;
obj1BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
obj1Btn.ResetState();
}
else if(obj2Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[10] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[10] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[10] >> 0) & 0xFF;
PaletteWindow("OBJ 2");
CurrentPalette.palette[10] = redAmount << 16 | greenAmount << 8 | blueAmount;
obj2BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
obj2Btn.ResetState();
}
else if(spr0Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[11] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[11] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[11] >> 0) & 0xFF;
PaletteWindow("SPR 0");
CurrentPalette.palette[11] = redAmount << 16 | greenAmount << 8 | blueAmount;
spr0BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
spr0Btn.ResetState();
}
else if(spr1Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[12] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[12] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[12] >> 0) & 0xFF;
PaletteWindow("SPR 1");
CurrentPalette.palette[12] = redAmount << 16 | greenAmount << 8 | blueAmount;
spr1BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
spr1Btn.ResetState();
}
else if(spr2Btn.GetState() == STATE_CLICKED)
{
redAmount = (CurrentPalette.palette[13] >> 16) & 0xFF;
greenAmount = (CurrentPalette.palette[13] >> 8) & 0xFF;
blueAmount = (CurrentPalette.palette[13] >> 0) & 0xFF;
PaletteWindow("SPR 2");
CurrentPalette.palette[13] = redAmount << 16 | greenAmount << 8 | blueAmount;
spr2BtnTxt.SetColor((GXColor){redAmount, greenAmount, blueAmount, 255});
spr2Btn.ResetState();
}
else if(importBtn.GetState() == STATE_CLICKED)
{
SavePalette(NOTSILENT, RomTitle);
menu = MENU_GAMESETTINGS_PALETTE;
}
else if(closeBtn.GetState() == STATE_CLICKED)
{
menu = MENU_EXIT;
SavePalette(SILENT, CurrentPalette.gameName);
SavePrefs(NOTSILENT);
exitSound->Play();
bgTopImg->SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 15);
closeBtn.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 15);
titleTxt.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 15);
backBtn.SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_OUT, 15);
bgBottomImg->SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_OUT, 15);
btnLogo->SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_OUT, 15);
w.SetEffect(EFFECT_FADE, -15);
usleep(350000); // wait for effects to finish
}
else if(backBtn.GetState() == STATE_CLICKED)
{
menu = MENU_GAMESETTINGS_VIDEO;
}
}
if(menu == MENU_GAME)
SavePrefs(NOTSILENT);
gbSetPalette(CurrentPalette.palette);
HaltGui();
mainWindow->Remove(&w);
return menu;
}

View File

@ -41,7 +41,8 @@ enum
MENU_GAMESETTINGS_MAPPINGS,
MENU_GAMESETTINGS_MAPPINGS_MAP,
MENU_GAMESETTINGS_VIDEO,
MENU_GAMESETTINGS_CHEATS
MENU_GAMESETTINGS_CHEATS,
MENU_GAMESETTINGS_PALETTE
};
#endif

View File

@ -22,6 +22,10 @@
#include "filebrowser.h"
#include "input.h"
#include "button_mapping.h"
#include "gamesettings.h"
void StopColorizing();
void gbSetPalette(u32 RRGGBB[]);
/****************************************************************************
* Prepare Preferences Data
@ -34,6 +38,16 @@ static mxml_node_t *section = NULL;
static mxml_node_t *item = NULL;
static mxml_node_t *elem = NULL;
static mxml_node_t *mxmlFindNewElement(mxml_node_t *parent, const char *nodename, const char *attr=NULL, const char *value=NULL) {
mxml_node_t *node = mxmlFindElement(parent, xml, nodename, attr, value, MXML_DESCEND);
if (!node) {
node = mxmlNewElement(parent, nodename);
if (attr && value) mxmlElementSetAttr(node, attr, value);
}
return node;
}
static char temp[20];
static const char * toStr(int i)
@ -41,6 +55,11 @@ static const char * toStr(int i)
sprintf(temp, "%d", i);
return temp;
}
static const char * toHex(u32 i)
{
sprintf(temp, "0x%06X", i);
return temp;
}
static const char * FtoStr(float i)
{
sprintf(temp, "%.2f", i);
@ -104,6 +123,31 @@ static const char * XMLSaveCallback(mxml_node_t *node, int where)
return (NULL);
}
static const char * XMLSavePalCallback(mxml_node_t *node, int where)
{
const char *name;
name = node->value.element.name;
if(where == MXML_WS_BEFORE_CLOSE)
{
if(!strcmp(name, "palette") || !strcmp(name, "game"))
return ("\n");
else if(!strcmp(name, "bkgr") || !strcmp(name, "wind") || !strcmp(name, "obj0") || !strcmp(name, "obj1"))
return ("\n\t");
}
if (where == MXML_WS_BEFORE_OPEN)
{
if(!strcmp(name, "palette"))
return ("\n");
else if(!strcmp(name, "game"))
return ("\n\n");
else if(!strcmp(name, "bkgr") || !strcmp(name, "wind") || !strcmp(name, "obj0") || !strcmp(name, "obj1"))
return ("\n\t");
}
return (NULL);
}
static int
preparePrefsData (int method)
@ -166,6 +210,89 @@ preparePrefsData (int method)
return datasize;
}
static void createXMLPalette(gamePalette *p, bool overwrite, const char *newname = NULL)
{
if (!newname) newname = p->gameName;
section = mxmlFindElement(xml, xml, "game", "name", newname, MXML_DESCEND);
if (section && !overwrite) {
return;
} else if (!section) {
section = mxmlNewElement(data, "game");
}
mxmlElementSetAttr(section, "name", newname);
mxmlElementSetAttr(section, "use", "1");
item = mxmlFindNewElement(section, "bkgr");
mxmlElementSetAttr(item, "c0", toHex(p->palette[0]));
mxmlElementSetAttr(item, "c1", toHex(p->palette[1]));
mxmlElementSetAttr(item, "c2", toHex(p->palette[2]));
mxmlElementSetAttr(item, "c3", toHex(p->palette[3]));
item = mxmlFindNewElement(section, "wind");
mxmlElementSetAttr(item, "c0", toHex(p->palette[4]));
mxmlElementSetAttr(item, "c1", toHex(p->palette[5]));
mxmlElementSetAttr(item, "c2", toHex(p->palette[6]));
mxmlElementSetAttr(item, "c3", toHex(p->palette[7]));
item = mxmlFindNewElement(section, "obj0");
mxmlElementSetAttr(item, "c0", toHex(p->palette[8]));
mxmlElementSetAttr(item, "c1", toHex(p->palette[9]));
mxmlElementSetAttr(item, "c2", toHex(p->palette[10]));
item = mxmlFindNewElement(section, "obj1");
mxmlElementSetAttr(item, "c0", toHex(p->palette[11]));
mxmlElementSetAttr(item, "c1", toHex(p->palette[12]));
mxmlElementSetAttr(item, "c2", toHex(p->palette[13]));
}
static int
preparePalData (int method)
{
xml = mxmlNewXML("1.0");
mxmlSetWrapMargin(0); // disable line wrapping
data = mxmlNewElement(xml, "palette");
mxmlElementSetAttr(data, "app", APPNAME);
mxmlElementSetAttr(data, "version", APPVERSION);
for (int i=0; i<gamePalettesCount; i++) {
createXMLPalette(&gamePalettes[i], false);
}
int datasize = mxmlSaveString(xml, (char *)savebuffer, SAVEBUFFERSIZE, XMLSavePalCallback);
mxmlDelete(xml);
return datasize;
}
static int
prepareExistingPalData (int method, const char *gameName)
{
int datasize = 0;
xml = mxmlLoadString(NULL, (char *)savebuffer, MXML_TEXT_CALLBACK);
if(xml)
{
// check settings version
// we don't do anything with the version #, but we'll store it anyway
data = mxmlFindElement(xml, xml, "palette", "version", NULL, MXML_DESCEND);
if(data) // a version entry exists
{
mxmlElementSetAttr(data, "app", APPNAME);
mxmlElementSetAttr(data, "version", APPVERSION);
} else {
data = mxmlNewElement(xml, "palette");
mxmlElementSetAttr(data, "app", APPNAME);
mxmlElementSetAttr(data, "version", APPVERSION);
}
for (int i=0; i<gamePalettesCount; i++) {
createXMLPalette(&gamePalettes[i], false);
}
createXMLPalette(&CurrentPalette, true, gameName);
datasize = mxmlSaveString(xml, (char *)savebuffer, SAVEBUFFERSIZE, XMLSavePalCallback);
mxmlDelete(xml);
}
return datasize;
}
/****************************************************************************
* loadXMLSetting
*
@ -327,6 +454,115 @@ decodePrefsData (int method)
return result;
}
static bool
decodePalData (int method, const char *gameName)
{
bool result = false;
xml = mxmlLoadString(NULL, (char *)savebuffer, MXML_TEXT_CALLBACK);
if(xml)
{
// check settings version
// we don't do anything with the version #, but we'll store it anyway
item = mxmlFindElement(xml, xml, "palette", "version", NULL, MXML_DESCEND);
if(item) // a version entry exists
{
const char * version = mxmlElementGetAttr(item, "version");
if(version && strlen(version) == 5)
{
// this code assumes version in format X.X.X
// XX.X.X, X.XX.X, or X.X.XX will NOT work
int verMajor = version[0] - '0';
int verMinor = version[2] - '0';
int verPoint = version[4] - '0';
int curMajor = APPVERSION[0] - '0';
int curMinor = APPVERSION[2] - '0';
int curPoint = APPVERSION[4] - '0';
// first we'll check that the versioning is valid
if(!(verMajor >= 0 && verMajor <= 9 &&
verMinor >= 0 && verMinor <= 9 &&
verPoint >= 0 && verPoint <= 9))
result = false;
else if(verMajor < 2) // less than version 2.0.0
result = false; // reset settings (sorry, should update settings instead)
else if(verMajor > curMajor || verMinor > curMinor || verPoint > curPoint) // some future version
result = true; // don't reset settings!
else
result = true;
}
}
if(result)
{
// load palette for this game
section = mxmlFindElement(xml, xml, "game", "name", gameName, MXML_DESCEND);
// if not found, load default palette
if (!section) section = mxmlFindElement(xml, xml, "game", "name", "default", MXML_DESCEND);
// we have either the XML default palette or the XML game palette
if (section) {
item = mxmlFindElement(section, xml, "bkgr", NULL, NULL, MXML_DESCEND);
if(item) {
const char * tmp = mxmlElementGetAttr(item, "c0");
if(tmp) CurrentPalette.palette[0] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c1");
if(tmp) CurrentPalette.palette[1] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c2");
if(tmp) CurrentPalette.palette[2] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c3");
if(tmp) CurrentPalette.palette[3] = strtoul(tmp, NULL, 16);
}
item = mxmlFindElement(section, xml, "wind", NULL, NULL, MXML_DESCEND);
if(item) {
const char * tmp = mxmlElementGetAttr(item, "c0");
if(tmp) CurrentPalette.palette[4] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c1");
if(tmp) CurrentPalette.palette[5] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c2");
if(tmp) CurrentPalette.palette[6] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c3");
if(tmp) CurrentPalette.palette[7] = strtoul(tmp, NULL, 16);
}
item = mxmlFindElement(section, xml, "obj0", NULL, NULL, MXML_DESCEND);
if(item) {
const char * tmp = mxmlElementGetAttr(item, "c0");
if(tmp) CurrentPalette.palette[8] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c1");
if(tmp) CurrentPalette.palette[9] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c2");
if(tmp) CurrentPalette.palette[10] = strtoul(tmp, NULL, 16);
}
item = mxmlFindElement(section, xml, "obj1", NULL, NULL, MXML_DESCEND);
if(item) {
const char * tmp = mxmlElementGetAttr(item, "c0");
if(tmp) CurrentPalette.palette[11] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c1");
if(tmp) CurrentPalette.palette[12] = strtoul(tmp, NULL, 16);
tmp = mxmlElementGetAttr(item, "c2");
if(tmp) CurrentPalette.palette[13] = strtoul(tmp, NULL, 16);
}
const char *use = mxmlElementGetAttr(section, "use");
if (use) {
if (atoi(use)==0) StopColorizing();
else gbSetPalette(CurrentPalette.palette);
} else {
gbSetPalette(CurrentPalette.palette);
}
// there is no palette for this game and no default in XML
} else {
// use the hardcoded default palette
CurrentPalette = gamePalettes[0];
gbSetPalette(CurrentPalette.palette);
}
}
mxmlDelete(xml);
}
return result;
}
/****************************************************************************
* Save Preferences
***************************************************************************/
@ -380,6 +616,135 @@ SavePrefs (bool silent)
return false;
}
bool
CreateAndLoadPalette(bool silent, const char *gameName)
{
// Load palette from hardcoded palettes
int snum = -1;
for(int i=1; i < gamePalettesCount; i++) {
if(strcmp(gameName, gamePalettes[i].gameName)==0)
{
snum = i;
break;
}
}
// match found!
if(snum >= 0)
{
CurrentPalette = gamePalettes[snum];
} else {
CurrentPalette = gamePalettes[0];
}
gbSetPalette(CurrentPalette.palette);
// Now create the XML palette file
char filepath[1024];
int datasize;
int offset = 0;
// We'll save using the first available method (probably SD) since this
// is the method preferences will be loaded from by default
int method = autoSaveMethod(silent);
if(method == METHOD_AUTO)
return false;
if(!MakeFilePath(filepath, FILE_PAL, method))
return false;
if (!silent)
ShowAction ("Saving palette...");
AllocSaveBuffer ();
datasize = preparePalData (method);
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
// Set the comments
char prefscomment[2][32];
memset(prefscomment, 0, 64);
sprintf (prefscomment[0], "%s Pal", APPNAME);
sprintf (prefscomment[1], "Palette");
SetMCSaveComments(prefscomment);
}
offset = SaveFile(filepath, datasize, method, silent);
FreeSaveBuffer ();
CancelAction();
if (offset > 0)
{
if (!silent)
InfoPrompt("Palette saved");
return true;
}
return false;
}
bool
SavePaletteMethod(bool silent, int method, const char *gameName)
{
char filepath[1024];
int offset = 0;
if(!MakeFilePath(filepath, FILE_PAL, method))
return false;
AllocSaveBuffer ();
offset = LoadFile(filepath, method, SILENT);
int datasize = 0;
if (offset > 0)
datasize = prepareExistingPalData (method, gameName);
if (!datasize) {
FreeSaveBuffer();
CancelAction();
return false;
}
if (!silent)
ShowAction ("Saving palette...");
// We'll save using the first available method (probably SD) since this
// is the method preferences will be loaded from by default
method = autoSaveMethod(silent);
if(method == METHOD_AUTO)
return false;
if(!MakeFilePath(filepath, FILE_PREF, method))
return false;
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
// Set the comments
char prefscomment[2][32];
memset(prefscomment, 0, 64);
sprintf (prefscomment[0], "%s Pal", APPNAME);
sprintf (prefscomment[1], "Palette");
SetMCSaveComments(prefscomment);
}
offset = SaveFile(filepath, datasize, method, silent);
FreeSaveBuffer ();
CancelAction();
if (offset > 0)
{
if (!silent)
InfoPrompt("Palette saved");
return true;
}
return false;
}
/****************************************************************************
* Load Preferences from specified method
***************************************************************************/
@ -405,6 +770,28 @@ LoadPrefsFromMethod (int method)
return retval;
}
bool
LoadPalFromMethod (int method, const char *gameName)
{
bool retval = false;
char filepath[1024];
int offset = 0;
if(!MakeFilePath(filepath, FILE_PAL, method))
return false;
AllocSaveBuffer ();
offset = LoadFile(filepath, method, SILENT);
if (offset > 0)
retval = decodePalData (method, gameName);
FreeSaveBuffer ();
return retval;
}
/****************************************************************************
* Load Preferences
* Checks sources consecutively until we find a preference file
@ -435,3 +822,47 @@ bool LoadPrefs()
return prefFound;
}
bool LoadPalette(const char *gameName)
{
bool prefFound = false;
if(ChangeInterface(METHOD_SD, SILENT))
prefFound = LoadPalFromMethod(METHOD_SD, gameName);
if(!prefFound && ChangeInterface(METHOD_USB, SILENT))
prefFound = LoadPalFromMethod(METHOD_USB, gameName);
if(!prefFound && TestMC(CARD_SLOTA, SILENT))
prefFound = LoadPalFromMethod(METHOD_MC_SLOTA, gameName);
if(!prefFound && TestMC(CARD_SLOTB, SILENT))
prefFound = LoadPalFromMethod(METHOD_MC_SLOTB, gameName);
if(!prefFound && ChangeInterface(METHOD_SMB, SILENT))
prefFound = LoadPalFromMethod(METHOD_SMB, gameName);
if(!prefFound) {
return CreateAndLoadPalette(SILENT, gameName);
}
return true;
}
bool SavePalette(bool silent, const char *gameName)
{
bool prefFound = false;
if(ChangeInterface(METHOD_SD, SILENT))
prefFound = SavePaletteMethod(silent, METHOD_SD, gameName);
if(!prefFound && ChangeInterface(METHOD_USB, SILENT))
prefFound = SavePaletteMethod(silent, METHOD_USB, gameName);
if(!prefFound && TestMC(CARD_SLOTA, SILENT))
prefFound = SavePaletteMethod(silent, METHOD_MC_SLOTA, gameName);
if(!prefFound && TestMC(CARD_SLOTB, SILENT))
prefFound = SavePaletteMethod(silent, METHOD_MC_SLOTB, gameName);
if(!prefFound && ChangeInterface(METHOD_SMB, SILENT))
prefFound = SavePaletteMethod(silent, METHOD_SMB, gameName);
if(!prefFound) {
gamePalette pal = CurrentPalette;
CreateAndLoadPalette(silent, gameName);
CurrentPalette = pal;
gbSetPalette(CurrentPalette.palette);
SavePaletteMethod(silent, METHOD_SD, gameName);
}
return true;
}

View File

@ -10,3 +10,5 @@
bool SavePrefs (bool silent);
bool LoadPrefs ();
bool SavePalette (bool silent, const char *gameName);
bool LoadPalette (const char *gameName);

View File

@ -47,6 +47,8 @@ int ExitRequested = 0;
char appPath[1024];
FreeTypeGX *fontSystem;
extern FILE *out;
/****************************************************************************
* Shutdown / Reboot / Exit
***************************************************************************/
@ -59,6 +61,7 @@ static void ExitCleanup()
#endif
ShutdownAudio();
StopGX();
if (out) fclose(out);
HaltDeviceThread();
UnmountAllFAT();
@ -296,4 +299,5 @@ int main(int argc, char *argv[])
}
} // emulation loop
} // main loop
return 0;
}

View File

@ -16,6 +16,7 @@
#define APPNAME "Visual Boy Advance GX"
#define APPVERSION "2.0.2"
#define PREF_FILE_NAME "settings.xml"
#define PAL_FILE_NAME "palette.xml"
#define NOTSILENT 0
#define SILENT 1
@ -37,7 +38,8 @@ enum {
FILE_SNAPSHOT,
FILE_ROM,
FILE_CHEAT,
FILE_PREF
FILE_PREF,
FILE_PAL
};
struct SGCSettings{

View File

@ -46,10 +46,15 @@
#include "menu.h"
#include "gcunzip.h"
#include "gamesettings.h"
#include "preferences.h"
//#define CARLLOG
static u32 start;
int cartridgeType = 0;
u32 RomIdCode;
char RomTitle[17];
int SunBars = 3;
bool TiltSideways = false;
@ -728,7 +733,6 @@ bool ValidGameId(u32 id)
static void gbApplyPerImagePreferences()
{
char title[17];
// Only works for some GB Colour roms
u8 Colour = gbRom[0x143];
if (Colour == 0x80 || Colour == 0xC0)
@ -741,60 +745,54 @@ static void gbApplyPerImagePreferences()
else
RomIdCode = 0;
// Otherwise we need to make up our own code
title[15] = '\0';
title[16] = '\0';
RomTitle[15] = '\0';
RomTitle[16] = '\0';
if (gbRom[0x143] < 0x7F && gbRom[0x143] > 0x20)
strncpy(title, (const char *) &gbRom[0x134], 16);
strncpy(RomTitle, (const char *) &gbRom[0x134], 16);
else
strncpy(title, (const char *) &gbRom[0x134], 15);
strncpy(RomTitle, (const char *) &gbRom[0x134], 15);
#ifdef CARLLOG
if (RomIdCode !=0) {
log("******** %2x \"%c%c%c%c\" \"%s\"", Colour, gbRom[0x13f], gbRom[0x140], gbRom[0x141], gbRom[0x142], title);
} else {
log("******** %2x \"%s\"", Colour, title);
}
#endif
if (RomIdCode == 0)
{
if (strcmp(title, "ZELDA") == 0)
if (strcmp(RomTitle, "ZELDA") == 0)
RomIdCode = LINKSAWAKENING;
else if (strcmp(title, "MORTAL KOMBAT") == 0)
else if (strcmp(RomTitle, "MORTAL KOMBAT") == 0)
RomIdCode = MK1;
else if (strcmp(title, "MORTALKOMBATI&II") == 0)
else if (strcmp(RomTitle, "MORTALKOMBATI&II") == 0)
RomIdCode = MK12;
else if (strcmp(title, "MORTAL KOMBAT II") == 0)
else if (strcmp(RomTitle, "MORTAL KOMBAT II") == 0)
RomIdCode = MK2;
else if (strcmp(title, "MORTAL KOMBAT 3") == 0)
else if (strcmp(RomTitle, "MORTAL KOMBAT 3") == 0)
RomIdCode = MK3;
else if (strcmp(title, "MORTAL KOMBAT 4") == 0)
else if (strcmp(RomTitle, "MORTAL KOMBAT 4") == 0)
RomIdCode = MK4;
else if (strcmp(title, "SUPER MARIOLAND") == 0)
else if (strcmp(RomTitle, "SUPER MARIOLAND") == 0)
RomIdCode = MARIOLAND1;
else if (strcmp(title, "MARIOLAND2") == 0)
else if (strcmp(RomTitle, "MARIOLAND2") == 0)
RomIdCode = MARIOLAND2;
else if (strcmp(title, "METROID2") == 0)
else if (strcmp(RomTitle, "METROID2") == 0)
RomIdCode = METROID2;
else if (strcmp(title, "MARBLE MADNESS") == 0)
else if (strcmp(RomTitle, "MARBLE MADNESS") == 0)
RomIdCode = MARBLEMADNESS;
else if (strcmp(title, "TMNT FOOT CLAN") == 0)
else if (strcmp(RomTitle, "TMNT FOOT CLAN") == 0)
RomIdCode = TMNT1;
else if (strcmp(title, "TMNT BACK FROM") == 0 || strcmp(title, "TMNT 2") == 0)
else if (strcmp(RomTitle, "TMNT BACK FROM") == 0 || strcmp(RomTitle, "TMNT 2") == 0)
RomIdCode = TMNT2;
else if (strcmp(title, "TMNT3") == 0)
else if (strcmp(RomTitle, "TMNT3") == 0)
RomIdCode = TMNT3;
}
// look for matching palettes if a monochrome gameboy game
// (or if a Super Gameboy game, but the palette will be ignored later in that case)
int snum = -1;
if ((Colour != 0x80) && (Colour != 0xC0)) {
for(int i=1; i < gamePalettesCount; i++)
{
if(strcmp(title, gamePalettes[i].gameName)==0)
{
snum = i;
break;
}
}
// match found!
if(snum >= 0)
{
gbSetPalette(gamePalettes[snum].palette);
} else {
gbSetPalette(gamePalettes[0].palette);
}
LoadPalette(RomTitle);
}
}
@ -808,6 +806,7 @@ static void ApplyPerImagePreferences()
// look for matching game setting
int snum = -1;
RomIdCode = rom[0xac] | (rom[0xad] << 8) | (rom[0xae] << 16) | (rom[0xaf] << 24);
RomTitle[0] = '\0';
for(int i=0; i < gameSettingsCount; i++)
{
@ -1099,6 +1098,7 @@ bool LoadVBAROM(int method)
void InitialisePalette()
{
log("InitialisePalette();");
int i;
// Build GBPalette
for( i = 0; i < 24; )

View File

@ -20,6 +20,7 @@
void gbSetBGPalette(u8 value, bool ColoursChanged=false);
void gbSetObj0Palette(u8 value, bool ColoursChanged=false);
void gbSetObj1Palette(u8 value, bool ColoursChanged=false);
void gbPaletteReset();
extern u8 *pix;
extern bool speedup;
@ -2140,6 +2141,7 @@ void gbReset()
{
systemCartridgeRumble(false);
gbGetHardwareType();
gbPaletteReset();
oldRegister_WY = 146;
gbInterruptLaunched = 0;

View File

@ -11,6 +11,8 @@
#include "vba.h"
#include "../ngc/menu.h"
#define CARLLOG
bool ColorizeGameboy = true;
// The 14-colour palette for a monochrome gameboy game
@ -26,8 +28,35 @@ u16 systemMonoPalette[14];
// drawing functions.
//u16 gbPalette[12];
static bool HadBgPal = false, HadObj0Pal = false, HadObj1Pal = false;
const float BL[4] = {0.1f, 0.4f, 0.7f, 1.0f};
// Averages colour with white
// factor is from 0 to 1. 0 = no extra whiteness, 1 = 100% whiteness
u16 changeColourWhiteness(u16 rgb, float factor) {
if (factor==0.0f) return rgb;
int r = (rgb & 0x1f);
r = (r * (1-factor))+(0x1f*factor);
if (r>31) {
r=31;
}
int g = ((rgb >> 5) & 0x1f);
g = (g * (1-factor))+(0x1f*factor);
if (g>31) {
g=31;
}
int b = ((rgb >> 10) & 0x1f);
b = (b * (1-factor))+(0x1f*factor);
if (b>31) {
b=31;
}
return r | (g << 5) | (b << 10);
}
// Brightens or darkens a colour
// factor is a multiple of normal brightness
u16 changeColourBrightness(u16 rgb, float factor) {
if (factor==1.0f) return rgb;
int bonus = 0;
@ -71,58 +100,120 @@ void gbSetBGPalette(u8 value, bool ColoursChanged=false) {
gbBgp[1] = (value & 0x0c)>>2;
gbBgp[2] = (value & 0x30)>>4;
gbBgp[3] = (value & 0xc0)>>6;
// Don't mess with the palette unless we have a Mono gameboy and either the colours changed
// or the brightness palette changed.
if ((value==oldBgp && !ColoursChanged) || gbCgbMode || gbSgbMode || !ColorizeGameboy) return;
// check for duplicates
bool dup = false;
for (int i=0; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbBgp[i]==gbBgp[j]) {
dup=true;
break;
}
if (!dup) { // no duplicates, therefore a complete palette change
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=0; index<=3; index++) {
if (gbBgp[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
Colour++;
int dupDarkness = -1;
if (value!=oldBgp) {
#ifdef CARLLOG
const char DN[5] = "3210";
log("Bg Pal: %c %c %c %c", DN[gbObp0[0]], DN[gbObp0[1]], DN[gbObp0[2]], DN[gbObp0[3]]);
#endif
// check for duplicates
for (int i=0; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbBgp[i]==gbBgp[j]) {
dup=true;
dupDarkness = gbBgp[i];
break;
}
// We haven't had a full palette yet, so guess...
if (dup && !HadBgPal) {
int index;
if (gbBgp[0]>gbBgp[3]) {
for (int Colour=0; Colour<=3; Colour++) {
index = Colour;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
}
} else {
for (int Colour=0; Colour<=3; Colour++) {
index = 3-Colour;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
}
}
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbBgp[DarkestToBrightestIndex[3]]];
BrightnessForDarkest = BL[3-gbBgp[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbBgp[DarkestToBrightestIndex[3]]];
BrightnessForDarkest = BL[3-gbBgp[DarkestToBrightestIndex[0]]];
} else if (!dup) { // no duplicates, therefore a complete palette change
HadBgPal = true;
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=0; index<=3; index++) {
if (gbBgp[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbBgp[index];
Colour++;
break;
}
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbBgp[DarkestToBrightestIndex[3]]];
BrightnessForDarkest = BL[3-gbBgp[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
}
float NewBrightnessForBrightest = BL[3-gbBgp[DarkestToBrightestIndex[3]]];
float BrightnessFactor;
float WhitenessFactor = 0;
// check if they are trying to make the palette whiter
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=0; i<=3; i++) {
WhitenessFactor+=BL[3-gbBgp[i]]-BL[3-i];
MaxWhiteness+=BL[3]-BL[3-i];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.4f);
// check if they are trying to make the palette brighter
if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbBgp[DarkestToBrightestIndex[0]]];
BrightnessFactor = NewBrightnessForDarkest/BrightnessForDarkest;
// Perhaps they are trying to make the palette darker
} else {
BrightnessFactor = NewBrightnessForBrightest/BrightnessForBrightest;
}
// BG colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[0+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
// Window colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[4+colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[4+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
if (WhitenessFactor) {
// BG colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]];
colourRGB = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
gbPalette[0+DarkestToBrightestIndex[colour]] = changeColourWhiteness(colourRGB, WhitenessFactor);
}
// Window colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[4+colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]];
colourRGB = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
gbPalette[4+DarkestToBrightestIndex[colour]] = changeColourWhiteness(colourRGB, WhitenessFactor);
}
} else {
// BG colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[0+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
// Window colours
for (int colour = 0; colour <= 3; colour++) {
u16 colourRGB = systemMonoPalette[4+colour];
float colourBrightness = BL[colour];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[4+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
}
}
@ -138,50 +229,103 @@ void gbSetObj0Palette(u8 value, bool ColoursChanged = false) {
gbObp0[1] = (value & 0x0c)>>2;
gbObp0[2] = (value & 0x30)>>4;
gbObp0[3] = (value & 0xc0)>>6;
// Don't mess with the palette unless we have a Mono gameboy and either the colours changed
// or the brightness palette changed.
if ((value==oldObp0 && !ColoursChanged) || gbCgbMode || gbSgbMode || !ColorizeGameboy) return;
// check for duplicates
bool dup = false;
for (int i=1; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbObp0[i]==gbObp0[j]) {
dup=true;
break;
}
if (!dup) { // no duplicates, therefore a complete palette change
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=1; index<=3; index++) {
if (gbObp0[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
Colour++;
int dupDarkness = -1;
if (value!=oldObp0) {
#ifdef CARLLOG
const char DN[5] = "3210";
log("Obj0 Pal: %c %c %c", DN[gbObp0[1]], DN[gbObp0[2]], DN[gbObp0[3]]);
#endif
// check for duplicates
for (int i=1; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbObp0[i]==gbObp0[j]) {
dup=true;
dupDarkness = gbObp0[i];
break;
}
// We haven't had a full palette yet, so guess...
if (dup && !HadObj1Pal) {
int index;
if (gbObp0[1]>gbObp0[3]) {
for (int Colour=0; Colour<=2; Colour++) {
index = Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
}
} else {
for (int Colour=0; Colour<=2; Colour++) {
index = 2-Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp0[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp0[DarkestToBrightestIndex[0]]];
} else if (!dup) { // no duplicates, therefore a complete brightness palette change
HadObj0Pal = true;
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=1; index<=3; index++) {
if (gbObp0[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp0[index];
Colour++;
break;
}
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp0[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp0[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp0[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp0[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
}
float NewBrightnessForBrightest = BL[3-gbObp0[DarkestToBrightestIndex[2]]];
float BrightnessFactor;
float WhitenessFactor = 0;
// check if they are trying to make the palette whiter
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=1; i<=3; i++) {
WhitenessFactor+=BL[3-gbObp0[i]]-BL[3-(i-1)];
MaxWhiteness+=BL[3]-BL[3-(i-1)];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.3f);
// check if they are trying to make the palette brighter
if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbObp0[DarkestToBrightestIndex[0]]];
BrightnessFactor = NewBrightnessForDarkest/BrightnessForDarkest;
} else {
BrightnessFactor = NewBrightnessForBrightest/BrightnessForBrightest;
}
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+8];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[8+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
if (WhitenessFactor) {
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+8];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]];
colourRGB = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
gbPalette[8+DarkestToBrightestIndex[colour]] = changeColourWhiteness(colourRGB, WhitenessFactor);
}
} else {
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+8];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[8+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
}
gbPalette[8] = 0; // always transparent
}
@ -198,50 +342,102 @@ void gbSetObj1Palette(u8 value, bool ColoursChanged = false) {
gbObp1[1] = (value & 0x0c)>>2;
gbObp1[2] = (value & 0x30)>>4;
gbObp1[3] = (value & 0xc0)>>6;
// Don't mess with the palette unless we have a Mono gameboy and either the colours changed
// or the brightness palette changed.
if ((value==oldObp1 && !ColoursChanged) || gbCgbMode || gbSgbMode || !ColorizeGameboy) return;
// check for duplicates
bool dup = false;
for (int i=1; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbObp1[i]==gbObp1[j]) {
dup=true;
break;
}
if (!dup) { // no duplicates, therefore a complete palette change
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=1; index<=3; index++) {
if (gbObp1[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
Colour++;
int dupDarkness = -1;
if (value!=oldObp1) {
#ifdef CARLLOG
const char DN[5] = "3210";
log("Obj1 Pal: %c %c %c", DN[gbObp1[1]], DN[gbObp1[2]], DN[gbObp1[3]]);
#endif
// check for duplicates
for (int i=1; i<=2; i++)
for (int j=i+1; j<=3; j++)
if (gbObp1[i]==gbObp1[j]) {
dup=true;
dupDarkness=gbObp1[i];
break;
}
// We haven't had a full palette yet, so guess...
if (dup && !HadObj1Pal) {
int index;
if (gbObp1[1]>gbObp1[3]) {
for (int Colour=0; Colour<=2; Colour++) {
index = Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
}
} else {
for (int Colour=0; Colour<=2; Colour++) {
index = 2-Colour+1;
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
}
}
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp1[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp1[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp1[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp1[DarkestToBrightestIndex[0]]];
} else if (!dup) { // no duplicates, therefore a complete palette change
HadObj1Pal = true;
// now we need to map them from darkest to brightest
int Colour = 0;
for (int darkness = 3; darkness>=0; darkness--) {
for (int index=1; index<=3; index++) {
if (gbObp1[index]==darkness) {
DarkestToBrightestIndex[Colour]=index;
Darkness[Colour]=gbObp1[index];
Colour++;
break;
}
}
}
// brightness of brightest colour
BrightnessForBrightest = BL[3-gbObp1[DarkestToBrightestIndex[2]]];
BrightnessForDarkest = BL[3-gbObp1[DarkestToBrightestIndex[0]]];
} else { // duplicates implies fading in or out
// since we are really trying to fade, not change palette,
// rely on previous DarkestToBrightest list
}
}
float NewBrightnessForBrightest = BL[3-gbObp1[DarkestToBrightestIndex[2]]];
float BrightnessFactor;
float WhitenessFactor = 0;
// check if they are trying to make the palette whiter
if (dupDarkness==0) {
// Multiple colours set to white
BrightnessFactor = 0;
float MaxWhiteness = 0;
int i;
for (i=1; i<=3; i++) {
WhitenessFactor+=BL[3-gbObp1[i]]-BL[3-(i-1)];
MaxWhiteness+=BL[3]-BL[3-(i-1)];
}
WhitenessFactor = WhitenessFactor / (MaxWhiteness+0.3f);
// check if they are trying to make the palette brighter
if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
} else if (NewBrightnessForBrightest==1.0f && BrightnessForBrightest==1.0f) {
float NewBrightnessForDarkest = BL[3-gbObp1[DarkestToBrightestIndex[0]]];
BrightnessFactor = NewBrightnessForDarkest/BrightnessForDarkest;
} else {
BrightnessFactor = NewBrightnessForBrightest/BrightnessForBrightest;
}
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+11];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[12+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
if (WhitenessFactor) {
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+11];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]];
colourRGB = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
gbPalette[12+DarkestToBrightestIndex[colour]] = changeColourWhiteness(colourRGB, WhitenessFactor);
}
} else {
for (int colour = 0; colour <= 2; colour++) {
u16 colourRGB = systemMonoPalette[colour+11];
float colourBrightness = BL[colour+1];
float indexBrightness = BL[3-Darkness[colour]]*BrightnessFactor;
gbPalette[12+DarkestToBrightestIndex[colour]] = changeColourBrightness(colourRGB, indexBrightness/colourBrightness);
}
}
gbPalette[12] = 0; // always transparent
}
@ -267,18 +463,28 @@ u16 Make15Bit(u32 rgb) {
return ((rgb >> 19) & 0x1F) | (((rgb >> 11) & 0x1F) << 5) | (((rgb >> 3) & 0x1F) << 10);
}
u32 OldObpBright[2]={0}, OldObpMedium[2]={0}, OldObpDark[2]={0};
void gbSetSpritePal(u8 WhichPal, u32 bright, u32 medium, u32 dark) {
if (!StartColorizing()) return;
// cancel if we already set to these colours
if (WhichPal>0) {
int p = WhichPal-1;
if (OldObpBright[p]==bright && OldObpMedium[p]==medium && OldObpDark[p]==dark) return;
}
int index = 0;
// check if we are setting both sprite palettes at once
if (WhichPal==0) {
gbSetSpritePal(1, bright, medium, dark);
gbSetSpritePal(2, bright, medium, dark);
return;
} else if (WhichPal==1) index = 8; // Obj0
else if (WhichPal==2) index=11; // Obj1
// save colours as 15 bit
systemMonoPalette[index]=Make15Bit(dark);
systemMonoPalette[index+1]=Make15Bit(medium);
systemMonoPalette[index+2]=Make15Bit(bright);
// change the brightness palette
if (WhichPal==1) {
u8 old = oldObp0;
oldObp0 +=1;
@ -299,8 +505,12 @@ void gbSetSpritePal(u8 WhichPal, u32 bright) {
gbSetSpritePal(WhichPal, bright, medium, dark);
}
u32 OldBgBright=0, OldBgMedium=0, OldBgDark=0, OldBgBlack=0;
void gbSetBgPal(u8 WhichPal, u32 bright, u32 medium, u32 dark, u32 black=0x000000) {
if (!StartColorizing()) return;
if (OldBgBright==bright && OldBgMedium==medium && OldBgDark==dark && OldBgBlack==black)
return;
int index = 0;
if (WhichPal==0) {
gbSetBgPal(1, bright, medium, dark, black);
@ -313,6 +523,10 @@ void gbSetBgPal(u8 WhichPal, u32 bright, u32 medium, u32 dark, u32 black=0x00000
systemMonoPalette[index+2]=Make15Bit(medium);
systemMonoPalette[index+3]=Make15Bit(bright);
gbSetBGPalette(oldBgp, true);
OldBgBright = bright;
OldBgMedium = medium;
OldBgDark = dark;
OldBgBlack = black;
}
void gbSetBgPal(u8 WhichPal, u32 bright) {
@ -332,3 +546,13 @@ void gbSetPalette(u32 RRGGBB[]) {
gbSetSpritePal(1, RRGGBB[8], RRGGBB[9], RRGGBB[10]);
gbSetSpritePal(2, RRGGBB[11], RRGGBB[12], RRGGBB[13]);
}
void gbPaletteReset() {
HadBgPal = HadObj0Pal = HadObj1Pal = false;
oldBgp = 0xFC;
oldObp0 = oldObp1 = 0xFF;
OldBgBright=0; OldBgMedium=0; OldBgDark=0; OldBgBlack=0;
for (int i=0; i<=1; i++) {
OldObpBright[i]=OldObpMedium[i]=OldObpDark[i]=0;
}
}

View File

@ -3377,7 +3377,6 @@ void CPUInterrupt()
biosProtected[3] = 0xe5;
}
#ifdef SDL
void log(const char *defaultMsg, ...)
{
char buffer[2048];
@ -3387,16 +3386,31 @@ void log(const char *defaultMsg, ...)
vsprintf(buffer, defaultMsg, valist);
if(out == NULL) {
out = fopen("trace.log","w");
out = fopen("sd:/trace.log","w");
}
fputs(buffer, out);
fprintf(out,"%s\n",buffer);
va_end(valist);
}
void winlog(const char *defaultMsg, ...)
{
char buffer[2048];
va_list valist;
va_start(valist, defaultMsg);
vsprintf(buffer, defaultMsg, valist);
if(out == NULL) {
out = fopen("sd:/trace.log","w");
}
fprintf(out,"%s\n",buffer);
//fputs(buffer, out);
va_end(valist);
}
#else
extern void winlog(const char *, ...);
#endif
void CPULoop(int ticks)
{

File diff suppressed because one or more lines are too long