more and more formating issues, I keep doing it in parts for my own reasons

This commit is contained in:
Zach Bacon 2016-07-09 10:13:54 -04:00
parent 48086ba62f
commit 1f37311a4a
No known key found for this signature in database
GPG Key ID: 7D110798AFE84B3A
50 changed files with 30207 additions and 30645 deletions

View File

@ -1,11 +1,10 @@
#include <memory.h> #include <memory.h>
#include "../Util.h" #include "../Util.h"
#include "../common/Types.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbSGB.h" #include "gbSGB.h"
u8 gbInvertTab[256] = { uint8_t gbInvertTab[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
@ -40,16 +39,16 @@ u8 gbInvertTab[256] = {
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
}; };
u16 gbLineMix[160]; uint16_t gbLineMix[160];
u16 gbWindowColor[160]; uint16_t gbWindowColor[160];
extern int inUseRegister_WY; extern int inUseRegister_WY;
extern int layerSettings; extern int layerSettings;
void gbRenderLine() void gbRenderLine()
{ {
memset(gbLineMix, 0, sizeof(gbLineMix)); memset(gbLineMix, 0, sizeof(gbLineMix));
u8* bank0; uint8_t* bank0;
u8* bank1; uint8_t* bank1;
if (gbCgbMode) { if (gbCgbMode) {
bank0 = &gbVram[0x0000]; bank0 = &gbVram[0x0000];
bank1 = &gbVram[0x2000]; bank1 = &gbVram[0x2000];
@ -91,11 +90,11 @@ void gbRenderLine()
int tile_map_address = tile_map_line_y + tx; int tile_map_address = tile_map_line_y + tx;
u8 attrs = 0; uint8_t attrs = 0;
if (bank1 != NULL) if (bank1 != NULL)
attrs = bank1[tile_map_address]; attrs = bank1[tile_map_address];
u8 tile = bank0[tile_map_address]; uint8_t tile = bank0[tile_map_address];
tile_map_address++; tile_map_address++;
@ -108,8 +107,8 @@ void gbRenderLine()
if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) { if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while (x < 160) { while (x < 160) {
u8 tile_a = 0; uint8_t tile_a = 0;
u8 tile_b = 0; uint8_t tile_b = 0;
if (attrs & 0x40) { if (attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2; tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
@ -129,7 +128,7 @@ void gbRenderLine()
} }
while (bx > 0) { while (bx > 0) {
u8 c = (tile_a & bx) ? 1 : 0; uint8_t c = (tile_a & bx) ? 1 : 0;
c += ((tile_b & bx) ? 2 : 0); c += ((tile_b & bx) ? 2 : 0);
gbLineBuffer[x] = c; // mark the gbLineBuffer color gbLineBuffer[x] = c; // mark the gbLineBuffer color
@ -204,7 +203,7 @@ void gbRenderLine()
// (this fixes white flashes on Last Bible II) // (this fixes white flashes on Last Bible II)
// Also added the gbColorOption (fixes Dracula Densetsu II color problems) // Also added the gbColorOption (fixes Dracula Densetsu II color problems)
for (int i = 0; i < 160; i++) { for (int i = 0; i < 160; i++) {
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode) if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF] : gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF; color = gbColorOption ? gbColorFilter[gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF] : gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF;
gbLineMix[i] = color; gbLineMix[i] = color;
@ -279,7 +278,7 @@ void gbRenderLine()
x = wx; x = wx;
tile = bank0[tile_map_address]; tile = bank0[tile_map_address];
u8 attrs = 0; uint8_t attrs = 0;
if (bank1) if (bank1)
attrs = bank1[tile_map_address]; attrs = bank1[tile_map_address];
tile_map_address++; tile_map_address++;
@ -298,8 +297,8 @@ void gbRenderLine()
gbLineMix[i] = gbWindowColor[i]; gbLineMix[i] = gbWindowColor[i];
while (x < 160) { while (x < 160) {
u8 tile_a = 0; uint8_t tile_a = 0;
u8 tile_b = 0; uint8_t tile_b = 0;
if (attrs & 0x40) { if (attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2; tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
@ -319,7 +318,7 @@ void gbRenderLine()
} }
while (bx > 0) { while (bx > 0) {
u8 c = (tile_a & bx) != 0 ? 1 : 0; uint8_t c = (tile_a & bx) != 0 ? 1 : 0;
c += ((tile_b & bx) != 0 ? 2 : 0); c += ((tile_b & bx) != 0 ? 2 : 0);
if (x >= 0) { if (x >= 0) {
@ -386,7 +385,7 @@ void gbRenderLine()
gbWindowLine = 0; gbWindowLine = 0;
} }
} else { } else {
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode) if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF; color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF;
for (int i = 0; i < 160; i++) { for (int i = 0; i < 160; i++) {
@ -399,8 +398,8 @@ void gbRenderLine()
void gbDrawSpriteTile(int tile, int x, int y, int t, int flags, void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
int size, int spriteNumber) int size, int spriteNumber)
{ {
u8* bank0; uint8_t* bank0;
u8* bank1; uint8_t* bank1;
if (gbCgbMode) { if (gbCgbMode) {
bank0 = &gbVram[0x0000]; bank0 = &gbVram[0x0000];
bank1 = &gbVram[0x2000]; bank1 = &gbVram[0x2000];
@ -415,7 +414,7 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
gbObp0[i] = (gbObp0Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3; gbObp0[i] = (gbObp0Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3;
gbObp1[i] = (gbObp1Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3; gbObp1[i] = (gbObp1Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3;
} }
u8* pal = gbObp0; uint8_t* pal = gbObp0;
int flipx = (flags & 0x20); int flipx = (flags & 0x20);
int flipy = (flags & 0x40); int flipy = (flags & 0x40);
@ -442,8 +441,8 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
} }
for (int xx = 0; xx < 8; xx++) { for (int xx = 0; xx < 8; xx++) {
u8 mask = 1 << (7 - xx); uint8_t mask = 1 << (7 - xx);
u8 c = 0; uint8_t c = 0;
if ((a & mask)) if ((a & mask))
c++; c++;
if ((b & mask)) if ((b & mask))
@ -459,7 +458,7 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
if (xxx < 0 || xxx > 159) if (xxx < 0 || xxx > 159)
continue; continue;
u16 color = gbLineBuffer[xxx]; uint16_t color = gbLineBuffer[xxx];
// Fixes OAM-BG priority // Fixes OAM-BG priority
if (prio && (register_LCDC & 1)) { if (prio && (register_LCDC & 1)) {

File diff suppressed because it is too large Load Diff

View File

@ -3,34 +3,30 @@
#include "../common/Types.h" #include "../common/Types.h"
#define readWord(addr) \ #define readWord(addr) \
((map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \ ((map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + ((map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8) + ((map[(addr + 2) >> 24].address[(addr + 2) & map[(addr + 2) >> 24].mask]) << 16) + ((map[(addr + 3) >> 24].address[(addr + 3) & map[(addr + 3) >> 24].mask]) << 24))
((map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8) + \
((map[(addr + 2) >> 24].address[(addr + 2) & map[(addr + 2) >> 24].mask]) << 16) + \
((map[(addr + 3) >> 24].address[(addr + 3) & map[(addr + 3) >> 24].mask]) << 24))
#define readHalfWord(addr) \ #define readHalfWord(addr) \
((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \ ((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + ((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8))
((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8))
#define readByte(addr) map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] #define readByte(addr) map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]
struct ConditionalBreakNode { struct ConditionalBreakNode {
char *address; char* address;
char *value; char* value;
u8 cond_flags; u8 cond_flags;
u8 exp_type_flags; u8 exp_type_flags;
struct ConditionalBreakNode *next; struct ConditionalBreakNode* next;
}; };
struct ConditionalBreak { struct ConditionalBreak {
u32 break_address; u32 break_address;
u8 type_flags; u8 type_flags;
struct ConditionalBreakNode *firstCond; struct ConditionalBreakNode* firstCond;
struct ConditionalBreak *next; struct ConditionalBreak* next;
}; };
extern struct ConditionalBreak *conditionals[16]; extern struct ConditionalBreak* conditionals[16];
// conditional break manipulators // conditional break manipulators
// case '*': flag = 0xf; break; // case '*': flag = 0xf; break;
@ -40,7 +36,7 @@ extern struct ConditionalBreak *conditionals[16];
// case 'r': flag = 0x2; break; // mem read // case 'r': flag = 0x2; break; // mem read
// case 'w': flag = 0x1; break; // mem write // case 'w': flag = 0x1; break; // mem write
// case 'i': flag = 0x3; break; // case 'i': flag = 0x3; break;
struct ConditionalBreak *addConditionalBreak(u32 address, u8 flag); struct ConditionalBreak* addConditionalBreak(u32 address, u8 flag);
int removeConditionalBreakNo(u32 address, u8 number); int removeConditionalBreakNo(u32 address, u8 number);
int removeFlagFromConditionalBreakNo(u32 address, u8 number, u8 flag); int removeFlagFromConditionalBreakNo(u32 address, u8 number, u8 flag);
@ -49,17 +45,17 @@ int removeConditionalWithFlag(u8 flag, bool orMode);
int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode); int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode);
// void freeConditionalBreak(struct ConditionalBreak* toFree); // void freeConditionalBreak(struct ConditionalBreak* toFree);
void addCondition(struct ConditionalBreak *base, struct ConditionalBreakNode *toAdd); void addCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toAdd);
// bool removeCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toDel); // bool removeCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toDel);
// bool removeCondition(u32 address, u8 flags, u8 num); // bool removeCondition(u32 address, u8 flags, u8 num);
void freeConditionalNode(struct ConditionalBreakNode *toDel); void freeConditionalNode(struct ConditionalBreakNode* toDel);
void parseAndCreateConditionalBreaks(u32 address, u8 flags, char **exp, int n); void parseAndCreateConditionalBreaks(u32 address, u8 flags, char** exp, int n);
bool isCorrectBreak(struct ConditionalBreak *toTest, u8 accessType); bool isCorrectBreak(struct ConditionalBreak* toTest, u8 accessType);
bool doesBreak(u32 address, u8 allowedFlags); bool doesBreak(u32 address, u8 allowedFlags);
bool doBreak(struct ConditionalBreak *toTest); bool doBreak(struct ConditionalBreak* toTest);
// printing the structure(AKA list Breaks) // printing the structure(AKA list Breaks)
// void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress); // void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress);

View File

@ -1,311 +1,310 @@
#include <stdlib.h>
#include <memory.h> #include <memory.h>
#include <stdlib.h>
#include "CheatSearch.h" #include "CheatSearch.h"
CheatSearchBlock cheatSearchBlocks[4]; CheatSearchBlock cheatSearchBlocks[4];
CheatSearchData cheatSearchData = { CheatSearchData cheatSearchData = {
0, 0,
cheatSearchBlocks cheatSearchBlocks
}; };
static bool cheatSearchEQ(u32 a, u32 b) static bool cheatSearchEQ(u32 a, u32 b)
{ {
return a == b; return a == b;
} }
static bool cheatSearchNE(u32 a, u32 b) static bool cheatSearchNE(u32 a, u32 b)
{ {
return a != b; return a != b;
} }
static bool cheatSearchLT(u32 a, u32 b) static bool cheatSearchLT(u32 a, u32 b)
{ {
return a < b; return a < b;
} }
static bool cheatSearchLE(u32 a, u32 b) static bool cheatSearchLE(u32 a, u32 b)
{ {
return a <= b; return a <= b;
} }
static bool cheatSearchGT(u32 a, u32 b) static bool cheatSearchGT(u32 a, u32 b)
{ {
return a > b; return a > b;
} }
static bool cheatSearchGE(u32 a, u32 b) static bool cheatSearchGE(u32 a, u32 b)
{ {
return a >= b; return a >= b;
} }
static bool cheatSearchSignedEQ(s32 a, s32 b) static bool cheatSearchSignedEQ(s32 a, s32 b)
{ {
return a == b; return a == b;
} }
static bool cheatSearchSignedNE(s32 a, s32 b) static bool cheatSearchSignedNE(s32 a, s32 b)
{ {
return a != b; return a != b;
} }
static bool cheatSearchSignedLT(s32 a, s32 b) static bool cheatSearchSignedLT(s32 a, s32 b)
{ {
return a < b; return a < b;
} }
static bool cheatSearchSignedLE(s32 a, s32 b) static bool cheatSearchSignedLE(s32 a, s32 b)
{ {
return a <= b; return a <= b;
} }
static bool cheatSearchSignedGT(s32 a, s32 b) static bool cheatSearchSignedGT(s32 a, s32 b)
{ {
return a > b; return a > b;
} }
static bool cheatSearchSignedGE(s32 a, s32 b) static bool cheatSearchSignedGE(s32 a, s32 b)
{ {
return a >= b; return a >= b;
} }
static bool (*cheatSearchFunc[])(u32,u32) = { static bool (*cheatSearchFunc[])(u32, u32) = {
cheatSearchEQ, cheatSearchEQ,
cheatSearchNE, cheatSearchNE,
cheatSearchLT, cheatSearchLT,
cheatSearchLE, cheatSearchLE,
cheatSearchGT, cheatSearchGT,
cheatSearchGE cheatSearchGE
}; };
static bool (*cheatSearchSignedFunc[])(s32,s32) = { static bool (*cheatSearchSignedFunc[])(s32, s32) = {
cheatSearchSignedEQ, cheatSearchSignedEQ,
cheatSearchSignedNE, cheatSearchSignedNE,
cheatSearchSignedLT, cheatSearchSignedLT,
cheatSearchSignedLE, cheatSearchSignedLE,
cheatSearchSignedGT, cheatSearchSignedGT,
cheatSearchSignedGE cheatSearchSignedGE
}; };
void cheatSearchCleanup(CheatSearchData *cs) void cheatSearchCleanup(CheatSearchData* cs)
{ {
int count = cs->count; int count = cs->count;
for(int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
free(cs->blocks[i].saved); free(cs->blocks[i].saved);
free(cs->blocks[i].bits); free(cs->blocks[i].bits);
} }
cs->count = 0; cs->count = 0;
} }
void cheatSearchStart(const CheatSearchData *cs) void cheatSearchStart(const CheatSearchData* cs)
{ {
int count = cs->count; int count = cs->count;
for(int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
CheatSearchBlock *block = &cs->blocks[i]; CheatSearchBlock* block = &cs->blocks[i];
memset(block->bits, 0xff, block->size >> 3); memset(block->bits, 0xff, block->size >> 3);
memcpy(block->saved, block->data, block->size); memcpy(block->saved, block->data, block->size);
} }
} }
s32 cheatSearchSignedRead(u8 *data, int off, int size) s32 cheatSearchSignedRead(u8* data, int off, int size)
{ {
u32 res = data[off++]; u32 res = data[off++];
switch(size) { switch (size) {
case BITS_8: case BITS_8:
res <<= 24; res <<= 24;
return ((s32)res) >> 24; return ((s32)res) >> 24;
case BITS_16: case BITS_16:
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++]) << 8;
res <<= 16; res <<= 16;
return ((s32)res) >> 16; return ((s32)res) >> 16;
case BITS_32: case BITS_32:
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++]) << 8;
res |= ((u32)data[off++])<<16; res |= ((u32)data[off++]) << 16;
res |= ((u32)data[off++])<<24; res |= ((u32)data[off++]) << 24;
return (s32)res;
}
return (s32)res; return (s32)res;
}
return (s32)res;
} }
u32 cheatSearchRead(u8 *data, int off, int size) u32 cheatSearchRead(u8* data, int off, int size)
{ {
u32 res = data[off++]; u32 res = data[off++];
if(size == BITS_16) if (size == BITS_16)
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++]) << 8;
else if(size == BITS_32) { else if (size == BITS_32) {
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++]) << 8;
res |= ((u32)data[off++])<<16; res |= ((u32)data[off++]) << 16;
res |= ((u32)data[off++])<<24; res |= ((u32)data[off++]) << 24;
} }
return res; return res;
} }
void cheatSearch(const CheatSearchData *cs, int compare, int size, void cheatSearch(const CheatSearchData* cs, int compare, int size,
bool isSigned) bool isSigned)
{ {
if(compare < 0 || compare > SEARCH_GE) if (compare < 0 || compare > SEARCH_GE)
return; return;
int inc = 1; int inc = 1;
if(size == BITS_16) if (size == BITS_16)
inc = 2; inc = 2;
else if(size == BITS_32) else if (size == BITS_32)
inc = 4; inc = 4;
if(isSigned) { if (isSigned) {
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; bool (*func)(s32, s32) = cheatSearchSignedFunc[compare];
for(int i = 0; i < cs->count; i++) { for (int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i]; CheatSearchBlock* block = &cs->blocks[i];
int size2 = block->size; int size2 = block->size;
u8 *bits = block->bits; u8* bits = block->bits;
u8 *data = block->data; u8* data = block->data;
u8 *saved = block->saved; u8* saved = block->saved;
for(int j = 0; j < size2; j += inc) { for (int j = 0; j < size2; j += inc) {
if(IS_BIT_SET(bits, j)) { if (IS_BIT_SET(bits, j)) {
s32 a = cheatSearchSignedRead(data, j, size); s32 a = cheatSearchSignedRead(data, j, size);
s32 b = cheatSearchSignedRead(saved,j, size); s32 b = cheatSearchSignedRead(saved, j, size);
if(!func(a, b)) { if (!func(a, b)) {
CLEAR_BIT(bits, j); CLEAR_BIT(bits, j);
if(size == BITS_16) if (size == BITS_16)
CLEAR_BIT(bits, j+1); CLEAR_BIT(bits, j + 1);
if(size == BITS_32) { if (size == BITS_32) {
CLEAR_BIT(bits, j+2); CLEAR_BIT(bits, j + 2);
CLEAR_BIT(bits, j+3); CLEAR_BIT(bits, j + 3);
} }
} }
} }
} }
}
} else {
bool (*func)(u32, u32) = cheatSearchFunc[compare];
for (int i = 0; i < cs->count; i++) {
CheatSearchBlock* block = &cs->blocks[i];
int size2 = block->size;
u8* bits = block->bits;
u8* data = block->data;
u8* saved = block->saved;
for (int j = 0; j < size2; j += inc) {
if (IS_BIT_SET(bits, j)) {
u32 a = cheatSearchRead(data, j, size);
u32 b = cheatSearchRead(saved, j, size);
if (!func(a, b)) {
CLEAR_BIT(bits, j);
if (size == BITS_16)
CLEAR_BIT(bits, j + 1);
if (size == BITS_32) {
CLEAR_BIT(bits, j + 2);
CLEAR_BIT(bits, j + 3);
}
}
}
}
}
} }
} else {
bool (*func)(u32,u32) = cheatSearchFunc[compare];
for(int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i];
int size2 = block->size;
u8 *bits = block->bits;
u8 *data = block->data;
u8 *saved = block->saved;
for(int j = 0; j < size2; j += inc) {
if(IS_BIT_SET(bits, j)) {
u32 a = cheatSearchRead(data, j, size);
u32 b = cheatSearchRead(saved,j, size);
if(!func(a, b)) {
CLEAR_BIT(bits, j);
if(size == BITS_16)
CLEAR_BIT(bits, j+1);
if(size == BITS_32) {
CLEAR_BIT(bits, j+2);
CLEAR_BIT(bits, j+3);
}
}
}
}
}
}
} }
void cheatSearchValue(const CheatSearchData *cs, int compare, int size, void cheatSearchValue(const CheatSearchData* cs, int compare, int size,
bool isSigned, u32 value) bool isSigned, u32 value)
{ {
if(compare < 0 || compare > SEARCH_GE) if (compare < 0 || compare > SEARCH_GE)
return; return;
int inc = 1; int inc = 1;
if(size == BITS_16) if (size == BITS_16)
inc = 2; inc = 2;
else if(size == BITS_32) else if (size == BITS_32)
inc = 4; inc = 4;
if(isSigned) { if (isSigned) {
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; bool (*func)(s32, s32) = cheatSearchSignedFunc[compare];
for(int i = 0; i < cs->count; i++) { for (int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i]; CheatSearchBlock* block = &cs->blocks[i];
int size2 = block->size; int size2 = block->size;
u8 *bits = block->bits; u8* bits = block->bits;
u8 *data = block->data; u8* data = block->data;
for(int j = 0; j < size2; j += inc) { for (int j = 0; j < size2; j += inc) {
if(IS_BIT_SET(bits, j)) { if (IS_BIT_SET(bits, j)) {
s32 a = cheatSearchSignedRead(data, j, size); s32 a = cheatSearchSignedRead(data, j, size);
s32 b = (s32)value; s32 b = (s32)value;
if(!func(a, b)) { if (!func(a, b)) {
CLEAR_BIT(bits, j); CLEAR_BIT(bits, j);
if(size == BITS_16) if (size == BITS_16)
CLEAR_BIT(bits, j+1); CLEAR_BIT(bits, j + 1);
if(size == BITS_32) { if (size == BITS_32) {
CLEAR_BIT(bits, j+2); CLEAR_BIT(bits, j + 2);
CLEAR_BIT(bits, j+3); CLEAR_BIT(bits, j + 3);
} }
} }
} }
} }
}
} else {
bool (*func)(u32, u32) = cheatSearchFunc[compare];
for (int i = 0; i < cs->count; i++) {
CheatSearchBlock* block = &cs->blocks[i];
int size2 = block->size;
u8* bits = block->bits;
u8* data = block->data;
for (int j = 0; j < size2; j += inc) {
if (IS_BIT_SET(bits, j)) {
u32 a = cheatSearchRead(data, j, size);
if (!func(a, value)) {
CLEAR_BIT(bits, j);
if (size == BITS_16)
CLEAR_BIT(bits, j + 1);
if (size == BITS_32) {
CLEAR_BIT(bits, j + 2);
CLEAR_BIT(bits, j + 3);
}
}
}
}
}
} }
} else {
bool (*func)(u32,u32) = cheatSearchFunc[compare];
for(int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i];
int size2 = block->size;
u8 *bits = block->bits;
u8 *data = block->data;
for(int j = 0; j < size2; j += inc) {
if(IS_BIT_SET(bits, j)) {
u32 a = cheatSearchRead(data, j, size);
if(!func(a, value)) {
CLEAR_BIT(bits, j);
if(size == BITS_16)
CLEAR_BIT(bits, j+1);
if(size == BITS_32) {
CLEAR_BIT(bits, j+2);
CLEAR_BIT(bits, j+3);
}
}
}
}
}
}
} }
int cheatSearchGetCount(const CheatSearchData *cs, int size) int cheatSearchGetCount(const CheatSearchData* cs, int size)
{ {
int res = 0; int res = 0;
int inc = 1; int inc = 1;
if(size == BITS_16) if (size == BITS_16)
inc = 2; inc = 2;
else if(size == BITS_32) else if (size == BITS_32)
inc = 4; inc = 4;
for(int i = 0; i < cs->count; i++) { for (int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i]; CheatSearchBlock* block = &cs->blocks[i];
int size2 = block->size; int size2 = block->size;
u8 *bits = block->bits; u8* bits = block->bits;
for(int j = 0; j < size2; j += inc) { for (int j = 0; j < size2; j += inc) {
if(IS_BIT_SET(bits, j)) if (IS_BIT_SET(bits, j))
res++; res++;
}
} }
} return res;
return res;
} }
void cheatSearchUpdateValues(const CheatSearchData *cs) void cheatSearchUpdateValues(const CheatSearchData* cs)
{ {
for(int i = 0; i < cs->count; i++) { for (int i = 0; i < cs->count; i++) {
CheatSearchBlock *block = &cs->blocks[i]; CheatSearchBlock* block = &cs->blocks[i];
memcpy(block->saved, block->data, block->size); memcpy(block->saved, block->data, block->size);
} }
} }

View File

@ -4,21 +4,28 @@
#include "../System.h" #include "../System.h"
struct CheatSearchBlock { struct CheatSearchBlock {
int size; int size;
u32 offset; u32 offset;
u8 *bits; u8* bits;
u8 *data; u8* data;
u8 *saved; u8* saved;
}; };
struct CheatSearchData { struct CheatSearchData {
int count; int count;
CheatSearchBlock *blocks; CheatSearchBlock* blocks;
}; };
enum { SEARCH_EQ, SEARCH_NE, SEARCH_LT, SEARCH_LE, SEARCH_GT, SEARCH_GE }; enum { SEARCH_EQ,
SEARCH_NE,
SEARCH_LT,
SEARCH_LE,
SEARCH_GT,
SEARCH_GE };
enum { BITS_8, BITS_16, BITS_32 }; enum { BITS_8,
BITS_16,
BITS_32 };
#define SET_BIT(bits, off) (bits)[(off) >> 3] |= (1 << ((off)&7)) #define SET_BIT(bits, off) (bits)[(off) >> 3] |= (1 << ((off)&7))
@ -28,13 +35,13 @@ enum { BITS_8, BITS_16, BITS_32 };
extern CheatSearchData cheatSearchData; extern CheatSearchData cheatSearchData;
void cheatSearchCleanup(CheatSearchData *cs); void cheatSearchCleanup(CheatSearchData* cs);
void cheatSearchStart(const CheatSearchData *cs); void cheatSearchStart(const CheatSearchData* cs);
void cheatSearch(const CheatSearchData *cs, int compare, int size, bool isSigned); void cheatSearch(const CheatSearchData* cs, int compare, int size, bool isSigned);
void cheatSearchValue(const CheatSearchData *cs, int compare, int size, bool isSigned, u32 value); void cheatSearchValue(const CheatSearchData* cs, int compare, int size, bool isSigned, u32 value);
int cheatSearchGetCount(const CheatSearchData *cs, int size); int cheatSearchGetCount(const CheatSearchData* cs, int size);
void cheatSearchUpdateValues(const CheatSearchData *cs); void cheatSearchUpdateValues(const CheatSearchData* cs);
s32 cheatSearchSignedRead(u8 *data, int off, int size); s32 cheatSearchSignedRead(u8* data, int off, int size);
u32 cheatSearchRead(u8 *data, int off, int size); u32 cheatSearchRead(u8* data, int off, int size);
#endif // CHEATSEARCH_H #endif // CHEATSEARCH_H

File diff suppressed because it is too large Load Diff

View File

@ -4,24 +4,24 @@
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"
struct CheatsData { struct CheatsData {
int code; int code;
int size; int size;
int status; int status;
bool enabled; bool enabled;
u32 rawaddress; u32 rawaddress;
u32 address; u32 address;
u32 value; u32 value;
u32 oldValue; u32 oldValue;
char codestring[20]; char codestring[20];
char desc[32]; char desc[32];
}; };
void cheatsAdd(const char *codeStr, const char *desc, u32 rawaddress, u32 address, u32 value, void cheatsAdd(const char* codeStr, const char* desc, u32 rawaddress, u32 address, u32 value,
int code, int size); int code, int size);
void cheatsAddCheatCode(const char *code, const char *desc); void cheatsAddCheatCode(const char* code, const char* desc);
void cheatsAddGSACode(const char *code, const char *desc, bool v3); void cheatsAddGSACode(const char* code, const char* desc, bool v3);
void cheatsAddCBACode(const char *code, const char *desc); void cheatsAddCBACode(const char* code, const char* desc);
bool cheatsImportGSACodeFile(const char *name, int game, bool v3); bool cheatsImportGSACodeFile(const char* name, int game, bool v3);
void cheatsDelete(int number, bool restore); void cheatsDelete(int number, bool restore);
void cheatsDeleteAll(bool restore); void cheatsDeleteAll(bool restore);
void cheatsEnable(int number); void cheatsEnable(int number);
@ -30,8 +30,8 @@ void cheatsDisable(int number);
void cheatsSaveGame(gzFile file); void cheatsSaveGame(gzFile file);
void cheatsReadGame(gzFile file, int version); void cheatsReadGame(gzFile file, int version);
void cheatsReadGameSkip(gzFile file, int version); void cheatsReadGameSkip(gzFile file, int version);
void cheatsSaveCheatList(const char *file); void cheatsSaveCheatList(const char* file);
bool cheatsLoadCheatList(const char *file); bool cheatsLoadCheatList(const char* file);
#endif #endif
void cheatsWriteMemory(u32 address, u32 value); void cheatsWriteMemory(u32 address, u32 value);
void cheatsWriteHalfWord(u32 address, u16 value); void cheatsWriteHalfWord(u32 address, u16 value);

View File

@ -1,8 +1,8 @@
#include <memory.h>
#include <string.h>
#include "GBA.h"
#include "EEprom.h" #include "EEprom.h"
#include "../Util.h" #include "../Util.h"
#include "GBA.h"
#include <memory.h>
#include <string.h>
extern int cpuDmaCount; extern int cpuDmaCount;
@ -14,7 +14,7 @@ int eepromAddress = 0;
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
// Workaround for broken-by-design GBA save semantics // Workaround for broken-by-design GBA save semantics
extern u8 libretro_save_buf[0x20000 + 0x2000]; extern u8 libretro_save_buf[0x20000 + 0x2000];
u8 *eepromData = libretro_save_buf + 0x20000; u8* eepromData = libretro_save_buf + 0x20000;
#else #else
u8 eepromData[0x2000]; u8 eepromData[0x2000];
#endif #endif
@ -24,198 +24,195 @@ bool eepromInUse = false;
int eepromSize = 512; int eepromSize = 512;
variable_desc eepromSaveData[] = { variable_desc eepromSaveData[] = {
{ &eepromMode, sizeof(int) }, { &eepromMode, sizeof(int) },
{ &eepromByte, sizeof(int) }, { &eepromByte, sizeof(int) },
{ &eepromBits , sizeof(int) }, { &eepromBits, sizeof(int) },
{ &eepromAddress , sizeof(int) }, { &eepromAddress, sizeof(int) },
{ &eepromInUse, sizeof(bool) }, { &eepromInUse, sizeof(bool) },
{ &eepromData[0], 512 }, { &eepromData[0], 512 },
{ &eepromBuffer[0], 16 }, { &eepromBuffer[0], 16 },
{ NULL, 0 } { NULL, 0 }
}; };
void eepromInit() void eepromInit()
{ {
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
memset(eepromData, 255, 0x2000); memset(eepromData, 255, 0x2000);
#else #else
memset(eepromData, 255, sizeof(eepromData)); memset(eepromData, 255, sizeof(eepromData));
#endif #endif
} }
void eepromReset() void eepromReset()
{ {
eepromMode = EEPROM_IDLE; eepromMode = EEPROM_IDLE;
eepromByte = 0; eepromByte = 0;
eepromBits = 0; eepromBits = 0;
eepromAddress = 0; eepromAddress = 0;
eepromInUse = false; eepromInUse = false;
eepromSize = 512; eepromSize = 512;
} }
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
void eepromSaveGame(uint8_t *& data) void eepromSaveGame(uint8_t*& data)
{ {
utilWriteDataMem(data, eepromSaveData); utilWriteDataMem(data, eepromSaveData);
utilWriteIntMem(data, eepromSize); utilWriteIntMem(data, eepromSize);
utilWriteMem(data, eepromData, 0x2000); utilWriteMem(data, eepromData, 0x2000);
} }
void eepromReadGame(const uint8_t *& data, int version) void eepromReadGame(const uint8_t*& data, int version)
{ {
utilReadDataMem(data, eepromSaveData); utilReadDataMem(data, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) { if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadIntMem(data); eepromSize = utilReadIntMem(data);
utilReadMem(eepromData, data, 0x2000); utilReadMem(eepromData, data, 0x2000);
} else { } else {
// prior to 0.7.1, only 4K EEPROM was supported // prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512; eepromSize = 512;
} }
} }
#else #else
void eepromSaveGame(gzFile gzFile) void eepromSaveGame(gzFile gzFile)
{ {
utilWriteData(gzFile, eepromSaveData); utilWriteData(gzFile, eepromSaveData);
utilWriteInt(gzFile, eepromSize); utilWriteInt(gzFile, eepromSize);
utilGzWrite(gzFile, eepromData, 0x2000); utilGzWrite(gzFile, eepromData, 0x2000);
} }
void eepromReadGame(gzFile gzFile, int version) void eepromReadGame(gzFile gzFile, int version)
{ {
utilReadData(gzFile, eepromSaveData); utilReadData(gzFile, eepromSaveData);
if(version >= SAVE_GAME_VERSION_3) { if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadInt(gzFile); eepromSize = utilReadInt(gzFile);
utilGzRead(gzFile, eepromData, 0x2000); utilGzRead(gzFile, eepromData, 0x2000);
} else { } else {
// prior to 0.7.1, only 4K EEPROM was supported // prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512; eepromSize = 512;
} }
} }
void eepromReadGameSkip(gzFile gzFile, int version) void eepromReadGameSkip(gzFile gzFile, int version)
{ {
// skip the eeprom data in a save game // skip the eeprom data in a save game
utilReadDataSkip(gzFile, eepromSaveData); utilReadDataSkip(gzFile, eepromSaveData);
if(version >= SAVE_GAME_VERSION_3) { if (version >= SAVE_GAME_VERSION_3) {
utilGzSeek(gzFile, sizeof(int), SEEK_CUR); utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
utilGzSeek(gzFile, 0x2000, SEEK_CUR); utilGzSeek(gzFile, 0x2000, SEEK_CUR);
} }
} }
#endif #endif
int eepromRead(u32 /* address */) int eepromRead(u32 /* address */)
{ {
switch(eepromMode) { switch (eepromMode) {
case EEPROM_IDLE: case EEPROM_IDLE:
case EEPROM_READADDRESS: case EEPROM_READADDRESS:
case EEPROM_WRITEDATA: case EEPROM_WRITEDATA:
return 1;
case EEPROM_READDATA: {
eepromBits++;
if (eepromBits == 4) {
eepromMode = EEPROM_READDATA2;
eepromBits = 0;
eepromByte = 0;
}
return 0;
}
case EEPROM_READDATA2: {
int data = 0;
int address = eepromAddress << 3;
int mask = 1 << (7 - (eepromBits & 7));
data = (eepromData[address + eepromByte] & mask) ? 1 : 0;
eepromBits++;
if ((eepromBits & 7) == 0)
eepromByte++;
if (eepromBits == 0x40)
eepromMode = EEPROM_IDLE;
return data;
}
default:
return 0;
}
return 1; return 1;
case EEPROM_READDATA:
{
eepromBits++;
if(eepromBits == 4) {
eepromMode = EEPROM_READDATA2;
eepromBits = 0;
eepromByte = 0;
}
return 0;
}
case EEPROM_READDATA2:
{
int data = 0;
int address = eepromAddress << 3;
int mask = 1 << (7 - (eepromBits & 7));
data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
eepromBits++;
if((eepromBits & 7) == 0)
eepromByte++;
if(eepromBits == 0x40)
eepromMode = EEPROM_IDLE;
return data;
}
default:
return 0;
}
return 1;
} }
void eepromWrite(u32 /* address */, u8 value) void eepromWrite(u32 /* address */, u8 value)
{ {
if(cpuDmaCount == 0) if (cpuDmaCount == 0)
return; return;
int bit = value & 1; int bit = value & 1;
switch(eepromMode) { switch (eepromMode) {
case EEPROM_IDLE: case EEPROM_IDLE:
eepromByte = 0; eepromByte = 0;
eepromBits = 1; eepromBits = 1;
eepromBuffer[eepromByte] = bit; eepromBuffer[eepromByte] = bit;
eepromMode = EEPROM_READADDRESS; eepromMode = EEPROM_READADDRESS;
break; break;
case EEPROM_READADDRESS: case EEPROM_READADDRESS:
eepromBuffer[eepromByte] <<= 1; eepromBuffer[eepromByte] <<= 1;
eepromBuffer[eepromByte] |= bit; eepromBuffer[eepromByte] |= bit;
eepromBits++; eepromBits++;
if((eepromBits & 7) == 0) { if ((eepromBits & 7) == 0) {
eepromByte++; eepromByte++;
}
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
if(eepromBits == 0x11) {
eepromInUse = true;
eepromSize = 0x2000;
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
((eepromBuffer[1] & 0xFF));
if(!(eepromBuffer[0] & 0x40)) {
eepromBuffer[0] = bit;
eepromBits = 1;
eepromByte = 0;
eepromMode = EEPROM_WRITEDATA;
} else {
eepromMode = EEPROM_READDATA;
eepromByte = 0;
eepromBits = 0;
} }
} if (cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
} else { if (eepromBits == 0x11) {
if(eepromBits == 9) { eepromInUse = true;
eepromInUse = true; eepromSize = 0x2000;
eepromAddress = (eepromBuffer[0] & 0x3F); eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) | ((eepromBuffer[1] & 0xFF));
if(!(eepromBuffer[0] & 0x40)) { if (!(eepromBuffer[0] & 0x40)) {
eepromBuffer[0] = bit; eepromBuffer[0] = bit;
eepromBits = 1; eepromBits = 1;
eepromByte = 0; eepromByte = 0;
eepromMode = EEPROM_WRITEDATA; eepromMode = EEPROM_WRITEDATA;
} else {
eepromMode = EEPROM_READDATA;
eepromByte = 0;
eepromBits = 0;
}
}
} else { } else {
eepromMode = EEPROM_READDATA; if (eepromBits == 9) {
eepromByte = 0; eepromInUse = true;
eepromBits = 0; eepromAddress = (eepromBuffer[0] & 0x3F);
if (!(eepromBuffer[0] & 0x40)) {
eepromBuffer[0] = bit;
eepromBits = 1;
eepromByte = 0;
eepromMode = EEPROM_WRITEDATA;
} else {
eepromMode = EEPROM_READDATA;
eepromByte = 0;
eepromBits = 0;
}
}
} }
} break;
case EEPROM_READDATA:
case EEPROM_READDATA2:
// should we reset here?
eepromMode = EEPROM_IDLE;
break;
case EEPROM_WRITEDATA:
eepromBuffer[eepromByte] <<= 1;
eepromBuffer[eepromByte] |= bit;
eepromBits++;
if ((eepromBits & 7) == 0) {
eepromByte++;
}
if (eepromBits == 0x40) {
eepromInUse = true;
// write data;
for (int i = 0; i < 8; i++) {
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
}
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
} else if (eepromBits == 0x41) {
eepromMode = EEPROM_IDLE;
eepromByte = 0;
eepromBits = 0;
}
break;
} }
break;
case EEPROM_READDATA:
case EEPROM_READDATA2:
// should we reset here?
eepromMode = EEPROM_IDLE;
break;
case EEPROM_WRITEDATA:
eepromBuffer[eepromByte] <<= 1;
eepromBuffer[eepromByte] |= bit;
eepromBits++;
if((eepromBits & 7) == 0) {
eepromByte++;
}
if(eepromBits == 0x40) {
eepromInUse = true;
// write data;
for(int i = 0; i < 8; i++) {
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
}
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
} else if(eepromBits == 0x41) {
eepromMode = EEPROM_IDLE;
eepromByte = 0;
eepromBits = 0;
}
break;
}
} }

View File

@ -2,8 +2,8 @@
#define EEPROM_H #define EEPROM_H
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern void eepromSaveGame(u8 *&data); extern void eepromSaveGame(u8*& data);
extern void eepromReadGame(const u8 *&data, int version); extern void eepromReadGame(const u8*& data, int version);
#else #else
extern void eepromSaveGame(gzFile _gzFile); extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile _gzFile, int version); extern void eepromReadGame(gzFile _gzFile, int version);
@ -14,7 +14,7 @@ extern void eepromWrite(u32 address, u8 value);
extern void eepromInit(); extern void eepromInit();
extern void eepromReset(); extern void eepromReset();
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern u8 *eepromData; extern u8* eepromData;
#else #else
extern u8 eepromData[0x2000]; extern u8 eepromData[0x2000];
#endif #endif

View File

@ -1,26 +1,26 @@
#include <stdio.h> #include "Flash.h"
#include <string.h> #include "../Util.h"
#include <memory.h>
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Flash.h"
#include "Sram.h" #include "Sram.h"
#include "../Util.h" #include <memory.h>
#include <stdio.h>
#include <string.h>
#define FLASH_READ_ARRAY 0 #define FLASH_READ_ARRAY 0
#define FLASH_CMD_1 1 #define FLASH_CMD_1 1
#define FLASH_CMD_2 2 #define FLASH_CMD_2 2
#define FLASH_AUTOSELECT 3 #define FLASH_AUTOSELECT 3
#define FLASH_CMD_3 4 #define FLASH_CMD_3 4
#define FLASH_CMD_4 5 #define FLASH_CMD_4 5
#define FLASH_CMD_5 6 #define FLASH_CMD_5 6
#define FLASH_ERASE_COMPLETE 7 #define FLASH_ERASE_COMPLETE 7
#define FLASH_PROGRAM 8 #define FLASH_PROGRAM 8
#define FLASH_SETBANK 9 #define FLASH_SETBANK 9
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern uint8_t libretro_save_buf[0x20000 + 0x2000]; extern uint8_t libretro_save_buf[0x20000 + 0x2000];
uint8_t *flashSaveMemory = libretro_save_buf; uint8_t* flashSaveMemory = libretro_save_buf;
#else #else
uint8_t flashSaveMemory[FLASH_128K_SZ]; uint8_t flashSaveMemory[FLASH_128K_SZ];
#endif #endif
@ -33,252 +33,251 @@ int flashManufacturerID = 0x32;
int flashBank = 0; int flashBank = 0;
static variable_desc flashSaveData[] = { static variable_desc flashSaveData[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSaveMemory[0], 0x10000 }, { &flashSaveMemory[0], 0x10000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData2[] = { static variable_desc flashSaveData2[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData3[] = { static variable_desc flashSaveData3[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashBank, sizeof(int) }, { &flashBank, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
void flashInit() void flashInit()
{ {
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
memset(flashSaveMemory, 0xff, 0x20000); memset(flashSaveMemory, 0xff, 0x20000);
#else #else
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory)); memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
#endif #endif
} }
void flashReset() void flashReset()
{ {
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
flashBank = 0; flashBank = 0;
} }
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
void flashSaveGame(uint8_t *& data) void flashSaveGame(uint8_t*& data)
{ {
utilWriteDataMem(data, flashSaveData3); utilWriteDataMem(data, flashSaveData3);
} }
void flashReadGame(const uint8_t *& data, int) void flashReadGame(const uint8_t*& data, int)
{ {
utilReadDataMem(data, flashSaveData3); utilReadDataMem(data, flashSaveData3);
} }
#else #else
void flashSaveGame(gzFile gzFile) void flashSaveGame(gzFile gzFile)
{ {
utilWriteData(gzFile, flashSaveData3); utilWriteData(gzFile, flashSaveData3);
} }
void flashReadGame(gzFile gzFile, int version) void flashReadGame(gzFile gzFile, int version)
{ {
if(version < SAVE_GAME_VERSION_5) if (version < SAVE_GAME_VERSION_5)
utilReadData(gzFile, flashSaveData); utilReadData(gzFile, flashSaveData);
else if(version < SAVE_GAME_VERSION_7) { else if (version < SAVE_GAME_VERSION_7) {
utilReadData(gzFile, flashSaveData2); utilReadData(gzFile, flashSaveData2);
flashBank = 0; flashBank = 0;
flashSetSize(flashSize); flashSetSize(flashSize);
} else { } else {
utilReadData(gzFile, flashSaveData3); utilReadData(gzFile, flashSaveData3);
} }
} }
void flashReadGameSkip(gzFile gzFile, int version) void flashReadGameSkip(gzFile gzFile, int version)
{ {
// skip the flash data in a save game // skip the flash data in a save game
if(version < SAVE_GAME_VERSION_5) if (version < SAVE_GAME_VERSION_5)
utilReadDataSkip(gzFile, flashSaveData); utilReadDataSkip(gzFile, flashSaveData);
else if(version < SAVE_GAME_VERSION_7) { else if (version < SAVE_GAME_VERSION_7) {
utilReadDataSkip(gzFile, flashSaveData2); utilReadDataSkip(gzFile, flashSaveData2);
} else { } else {
utilReadDataSkip(gzFile, flashSaveData3); utilReadDataSkip(gzFile, flashSaveData3);
} }
} }
#endif #endif
void flashSetSize(int size) void flashSetSize(int size)
{ {
// log("Setting flash size to %d\n", size); // log("Setting flash size to %d\n", size);
if(size == 0x10000) { if (size == 0x10000) {
flashDeviceID = 0x1b; flashDeviceID = 0x1b;
flashManufacturerID = 0x32; flashManufacturerID = 0x32;
} else { } else {
flashDeviceID = 0x13; //0x09; flashDeviceID = 0x13; //0x09;
flashManufacturerID = 0x62; //0xc2; flashManufacturerID = 0x62; //0xc2;
} }
// Added to make 64k saves compatible with 128k ones // Added to make 64k saves compatible with 128k ones
// (allow wrongfuly set 64k saves to work for Pokemon games) // (allow wrongfuly set 64k saves to work for Pokemon games)
if ((size == 0x20000) && (flashSize == 0x10000)) if ((size == 0x20000) && (flashSize == 0x10000))
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000); memcpy((u8*)(flashSaveMemory + 0x10000), (u8*)(flashSaveMemory), 0x10000);
flashSize = size; flashSize = size;
} }
u8 flashRead(u32 address) u8 flashRead(u32 address)
{ {
// log("Reading %08x from %08x\n", address, reg[15].I); // log("Reading %08x from %08x\n", address, reg[15].I);
// log("Current read state is %d\n", flashReadState); // log("Current read state is %d\n", flashReadState);
address &= 0xFFFF; address &= 0xFFFF;
switch(flashReadState) { switch (flashReadState) {
case FLASH_READ_ARRAY: case FLASH_READ_ARRAY:
return flashSaveMemory[(flashBank << 16) + address]; return flashSaveMemory[(flashBank << 16) + address];
case FLASH_AUTOSELECT: case FLASH_AUTOSELECT:
switch(address & 0xFF) { switch (address & 0xFF) {
case 0: case 0:
// manufacturer ID // manufacturer ID
return flashManufacturerID; return flashManufacturerID;
case 1: case 1:
// device ID // device ID
return flashDeviceID; return flashDeviceID;
} }
break; break;
case FLASH_ERASE_COMPLETE: case FLASH_ERASE_COMPLETE:
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
return 0xFF; return 0xFF;
}; };
return 0; return 0;
} }
void flashSaveDecide(u32 address, u8 byte) void flashSaveDecide(u32 address, u8 byte)
{ {
if (saveType == 1) if (saveType == 1)
return; return;
// log("Deciding save type %08x\n", address); // log("Deciding save type %08x\n", address);
if(address == 0x0e005555) { if (address == 0x0e005555) {
saveType = 3; saveType = 3;
cpuSaveGameFunc = flashWrite; cpuSaveGameFunc = flashWrite;
} else { } else {
saveType = 2; saveType = 2;
cpuSaveGameFunc = sramWrite; cpuSaveGameFunc = sramWrite;
} }
(*cpuSaveGameFunc)(address, byte); (*cpuSaveGameFunc)(address, byte);
} }
void flashDelayedWrite(u32 address, u8 byte) void flashDelayedWrite(u32 address, u8 byte)
{ {
saveType = 3; saveType = 3;
cpuSaveGameFunc = flashWrite; cpuSaveGameFunc = flashWrite;
flashWrite(address, byte); flashWrite(address, byte);
} }
void flashWrite(u32 address, u8 byte) void flashWrite(u32 address, u8 byte)
{ {
// log("Writing %02x at %08x\n", byte, address); // log("Writing %02x at %08x\n", byte, address);
// log("Current state is %d\n", flashState); // log("Current state is %d\n", flashState);
address &= 0xFFFF; address &= 0xFFFF;
switch(flashState) { switch (flashState) {
case FLASH_READ_ARRAY: case FLASH_READ_ARRAY:
if(address == 0x5555 && byte == 0xAA) if (address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1; flashState = FLASH_CMD_1;
break; break;
case FLASH_CMD_1: case FLASH_CMD_1:
if(address == 0x2AAA && byte == 0x55) if (address == 0x2AAA && byte == 0x55)
flashState = FLASH_CMD_2; flashState = FLASH_CMD_2;
else else
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
break; break;
case FLASH_CMD_2: case FLASH_CMD_2:
if(address == 0x5555) { if (address == 0x5555) {
if(byte == 0x90) { if (byte == 0x90) {
flashState = FLASH_AUTOSELECT; flashState = FLASH_AUTOSELECT;
flashReadState = FLASH_AUTOSELECT; flashReadState = FLASH_AUTOSELECT;
} else if(byte == 0x80) { } else if (byte == 0x80) {
flashState = FLASH_CMD_3; flashState = FLASH_CMD_3;
} else if(byte == 0xF0) { } else if (byte == 0xF0) {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
} else if (byte == 0xA0) {
flashState = FLASH_PROGRAM;
} else if (byte == 0xB0 && flashSize == 0x20000) {
flashState = FLASH_SETBANK;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_CMD_3:
if (address == 0x5555 && byte == 0xAA) {
flashState = FLASH_CMD_4;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_CMD_4:
if (address == 0x2AAA && byte == 0x55) {
flashState = FLASH_CMD_5;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_CMD_5:
if (byte == 0x30) {
// SECTOR ERASE
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
0,
0x1000);
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashReadState = FLASH_ERASE_COMPLETE;
} else if (byte == 0x10) {
// CHIP ERASE
memset(flashSaveMemory, 0, flashSize);
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashReadState = FLASH_ERASE_COMPLETE;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_AUTOSELECT:
if (byte == 0xF0) {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
} else if (address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1;
else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_PROGRAM:
flashSaveMemory[(flashBank << 16) + address] = byte;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
} else if(byte == 0xA0) { break;
flashState = FLASH_PROGRAM; case FLASH_SETBANK:
} else if(byte == 0xB0 && flashSize == 0x20000) { if (address == 0) {
flashState = FLASH_SETBANK; flashBank = (byte & 1);
} else { }
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
} break;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
} }
break;
case FLASH_CMD_3:
if(address == 0x5555 && byte == 0xAA) {
flashState = FLASH_CMD_4;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_CMD_4:
if(address == 0x2AAA && byte == 0x55) {
flashState = FLASH_CMD_5;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_CMD_5:
if(byte == 0x30) {
// SECTOR ERASE
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
0,
0x1000);
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashReadState = FLASH_ERASE_COMPLETE;
} else if(byte == 0x10) {
// CHIP ERASE
memset(flashSaveMemory, 0, flashSize);
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashReadState = FLASH_ERASE_COMPLETE;
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_AUTOSELECT:
if(byte == 0xF0) {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
} else if(address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1;
else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
break;
case FLASH_PROGRAM:
flashSaveMemory[(flashBank<<16)+address] = byte;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
case FLASH_SETBANK:
if(address == 0) {
flashBank = (byte & 1);
}
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
}
} }

View File

@ -4,8 +4,8 @@
#define FLASH_128K_SZ 0x20000 #define FLASH_128K_SZ 0x20000
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern void flashSaveGame(u8 *&data); extern void flashSaveGame(u8*& data);
extern void flashReadGame(const u8 *&data, int); extern void flashReadGame(const u8*& data, int);
#else #else
extern void flashSaveGame(gzFile _gzFile); extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile _gzFile, int version); extern void flashReadGame(gzFile _gzFile, int version);
@ -15,7 +15,7 @@ extern u8 flashRead(u32 address);
extern void flashWrite(u32 address, u8 byte); extern void flashWrite(u32 address, u8 byte);
extern void flashDelayedWrite(u32 address, u8 byte); extern void flashDelayedWrite(u32 address, u8 byte);
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern uint8_t *flashSaveMemory; extern uint8_t* flashSaveMemory;
#else #else
extern u8 flashSaveMemory[FLASH_128K_SZ]; extern u8 flashSaveMemory[FLASH_128K_SZ];
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,43 +18,43 @@ const u64 TICKS_PER_SECOND = 16777216;
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10 #define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
typedef struct { typedef struct {
u8 *address; u8* address;
u32 mask; u32 mask;
#ifdef BKPT_SUPPORT #ifdef BKPT_SUPPORT
u8 *breakPoints; u8* breakPoints;
u8 *searchMatch; u8* searchMatch;
u8 *trace; u8* trace;
u32 size; u32 size;
#endif #endif
} memoryMap; } memoryMap;
typedef union { typedef union {
struct { struct {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
u8 B3; u8 B3;
u8 B2; u8 B2;
u8 B1; u8 B1;
u8 B0; u8 B0;
#else #else
u8 B0; u8 B0;
u8 B1; u8 B1;
u8 B2; u8 B2;
u8 B3; u8 B3;
#endif #endif
} B; } B;
struct { struct {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
u16 W1; u16 W1;
u16 W0; u16 W0;
#else #else
u16 W0; u16 W0;
u16 W1; u16 W1;
#endif #endif
} W; } W;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
volatile u32 I; volatile u32 I;
#else #else
u32 I; u32 I;
#endif #endif
} reg_pair; } reg_pair;
@ -78,49 +78,49 @@ extern char oldbuffer[10];
extern bool debugger; extern bool debugger;
#endif #endif
extern bool CPUReadGSASnapshot(const char *); extern bool CPUReadGSASnapshot(const char*);
extern bool CPUReadGSASPSnapshot(const char *); extern bool CPUReadGSASPSnapshot(const char*);
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *); extern bool CPUWriteGSASnapshot(const char*, const char*, const char*, const char*);
extern bool CPUWriteBatteryFile(const char *); extern bool CPUWriteBatteryFile(const char*);
extern bool CPUReadBatteryFile(const char *); extern bool CPUReadBatteryFile(const char*);
extern bool CPUExportEepromFile(const char *); extern bool CPUExportEepromFile(const char*);
extern bool CPUImportEepromFile(const char *); extern bool CPUImportEepromFile(const char*);
extern bool CPUWritePNGFile(const char *); extern bool CPUWritePNGFile(const char*);
extern bool CPUWriteBMPFile(const char *); extern bool CPUWriteBMPFile(const char*);
extern void CPUCleanUp(); extern void CPUCleanUp();
extern void CPUUpdateRender(); extern void CPUUpdateRender();
extern void CPUUpdateRenderBuffers(bool); extern void CPUUpdateRenderBuffers(bool);
extern bool CPUReadMemState(char *, int); extern bool CPUReadMemState(char*, int);
extern bool CPUWriteMemState(char *, int); extern bool CPUWriteMemState(char*, int);
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern bool CPUReadState(const u8 *, unsigned); extern bool CPUReadState(const u8*, unsigned);
extern unsigned int CPUWriteState(u8 *data, unsigned int size); extern unsigned int CPUWriteState(u8* data, unsigned int size);
#else #else
extern bool CPUReadState(const char *); extern bool CPUReadState(const char*);
extern bool CPUWriteState(const char *); extern bool CPUWriteState(const char*);
#endif #endif
extern int CPULoadRom(const char *); extern int CPULoadRom(const char*);
extern int CPULoadRomData(const char *data, int size); extern int CPULoadRomData(const char* data, int size);
extern void doMirroring(bool); extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16); extern void CPUUpdateRegister(u32, u16);
extern void applyTimer(); extern void applyTimer();
extern void CPUInit(const char *, bool); extern void CPUInit(const char*, bool);
void SetSaveType(int st); void SetSaveType(int st);
extern void CPUReset(); extern void CPUReset();
extern void CPULoop(int); extern void CPULoop(int);
extern void CPUCheckDMA(int, int); extern void CPUCheckDMA(int, int);
extern bool CPUIsGBAImage(const char *); extern bool CPUIsGBAImage(const char*);
extern bool CPUIsZipFile(const char *); extern bool CPUIsZipFile(const char*);
#ifdef PROFILING #ifdef PROFILING
#include "prof/prof.h" #include "prof/prof.h"
extern void cpuProfil(profile_segment *seg); extern void cpuProfil(profile_segment* seg);
extern void cpuEnableProfiling(int hz); extern void cpuEnableProfiling(int hz);
#endif #endif
const char *GetLoadDotCodeFile(); const char* GetLoadDotCodeFile();
const char *GetSaveDotCodeFile(); const char* GetSaveDotCodeFile();
void SetLoadDotCodeFile(const char *szFile); void SetLoadDotCodeFile(const char* szFile);
void SetSaveDotCodeFile(const char *szFile); void SetSaveDotCodeFile(const char* szFile);
extern struct EmulatedSystem GBASystem; extern struct EmulatedSystem GBASystem;

View File

@ -1,8 +1,9 @@
#include "../System.h" #include "../System.h"
int coeff[32] = { int coeff[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
};
u32 line0[240]; u32 line0[240];
u32 line1[240]; u32 line1[240];

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,20 +5,23 @@
* Link modes to be passed to InitLink * Link modes to be passed to InitLink
*/ */
enum LinkMode { enum LinkMode {
LINK_DISCONNECTED, LINK_DISCONNECTED,
LINK_CABLE_IPC, LINK_CABLE_IPC,
LINK_CABLE_SOCKET, LINK_CABLE_SOCKET,
LINK_RFU_IPC, LINK_RFU_IPC,
LINK_RFU_SOCKET, LINK_RFU_SOCKET,
LINK_GAMECUBE_DOLPHIN, LINK_GAMECUBE_DOLPHIN,
LINK_GAMEBOY_IPC, LINK_GAMEBOY_IPC,
LINK_GAMEBOY_SOCKET LINK_GAMEBOY_SOCKET
}; };
/** /**
* State of the connection attempt * State of the connection attempt
*/ */
enum ConnectionState { LINK_OK, LINK_ERROR, LINK_NEEDS_UPDATE, LINK_ABORT }; enum ConnectionState { LINK_OK,
LINK_ERROR,
LINK_NEEDS_UPDATE,
LINK_ABORT };
/** /**
* Initialize GBA linking * Initialize GBA linking
@ -34,7 +37,7 @@ extern ConnectionState InitLink(LinkMode mode);
* @param message Information message * @param message Information message
* @param size Maximum message size * @param size Maximum message size
*/ */
extern ConnectionState ConnectLinkUpdate(char *const message, size_t size); extern ConnectionState ConnectLinkUpdate(char* const message, size_t size);
/** /**
* Get the currently enabled link mode * Get the currently enabled link mode
@ -63,7 +66,7 @@ extern void EnableSpeedHacks(bool enable);
* *
* @return false if the address is invalid * @return false if the address is invalid
*/ */
extern bool SetLinkServerHost(const char *host); extern bool SetLinkServerHost(const char* host);
/** /**
* Get the host relevant to context * Get the host relevant to context
@ -73,7 +76,7 @@ extern bool SetLinkServerHost(const char *host);
* If in gamecube mode, returns the IP adress of the dolphin host * If in gamecube mode, returns the IP adress of the dolphin host
* *
*/ */
extern void GetLinkServerHost(char *const host, size_t size); extern void GetLinkServerHost(char* const host, size_t size);
/** /**
* Set the value in milliseconds of the timeout after which a connection is * Set the value in milliseconds of the timeout after which a connection is
@ -131,20 +134,20 @@ extern void CleanLocalLink();
* @return completed filename * @return completed filename
*/ */
extern const char *MakeInstanceFilename(const char *Input); extern const char* MakeInstanceFilename(const char* Input);
// register definitions // register definitions
#define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode #define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode
#define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode #define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode
#define COMM_SIOCNT 0x128 #define COMM_SIOCNT 0x128
#define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO) #define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO)
#define COMM_SIOMLT_SEND 0x12a // SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing) #define COMM_SIOMLT_SEND 0x12a // SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing)
#define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master) #define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1) #define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2) #define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3) #define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
#define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode #define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode
#define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)? #define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)?
#define COMM_JOYCNT 0x140 #define COMM_JOYCNT 0x140
#define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher #define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher
#define COMM_JOY_RECV_H 0x152 #define COMM_JOY_RECV_H 0x152
@ -176,16 +179,16 @@ extern const char *MakeInstanceFilename(const char *Input);
#define RFU_SEND 2 #define RFU_SEND 2
#define RFU_RECV 3 #define RFU_RECV 3
#define RF_RECVCMD \ #define RF_RECVCMD \
0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD 0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD
// sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?) // sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?)
#define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?) #define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?)
typedef struct { typedef struct {
u8 len; // data len in 32bit words u8 len; // data len in 32bit words
u8 gbaid; // source id u8 gbaid; // source id
u32 time; // linktime u32 time; // linktime
u32 data[255]; u32 data[255];
} rfu_datarec; } rfu_datarec;
extern u8 gbSIO_SC; extern u8 gbSIO_SC;
@ -199,6 +202,6 @@ extern void gbInitLinkIPC();
extern u8 gbStartLinkIPC(u8 b); extern u8 gbStartLinkIPC(u8 b);
extern u16 gbLinkUpdateIPC(u8 b, int gbSerialOn); extern u16 gbLinkUpdateIPC(u8 b, int gbSerialOn);
extern void BootLink(int m_type, const char *host, int timeout, bool m_hacks, int m_numplayers); extern void BootLink(int m_type, const char* host, int timeout, bool m_hacks, int m_numplayers);
#endif /* GBA_GBALINK_H */ #endif /* GBA_GBALINK_H */

View File

@ -6,94 +6,92 @@
GBASockClient::GBASockClient(sf::IpAddress _server_addr) GBASockClient::GBASockClient(sf::IpAddress _server_addr)
{ {
if (_server_addr == sf::IpAddress::None) if (_server_addr == sf::IpAddress::None)
server_addr = sf::IpAddress::LocalHost; server_addr = sf::IpAddress::LocalHost;
else else
server_addr = _server_addr; server_addr = _server_addr;
client.connect(server_addr, 0xd6ba); client.connect(server_addr, 0xd6ba);
client.setBlocking(false); client.setBlocking(false);
clock_client.connect(server_addr, 0xc10c); clock_client.connect(server_addr, 0xc10c);
clock_client.setBlocking(false); clock_client.setBlocking(false);
clock_sync = 0; clock_sync = 0;
is_disconnected = false; is_disconnected = false;
} }
GBASockClient::~GBASockClient() GBASockClient::~GBASockClient()
{ {
client.disconnect(); client.disconnect();
clock_client.disconnect(); clock_client.disconnect();
} }
u32 clock_sync_ticks = 0; u32 clock_sync_ticks = 0;
void GBASockClient::Send(std::vector<char> data) void GBASockClient::Send(std::vector<char> data)
{ {
char* plain_data = new char[data.size()]; char* plain_data = new char[data.size()];
std::copy(data.begin(), data.end(), plain_data); std::copy(data.begin(), data.end(), plain_data);
client.send(plain_data, data.size()); client.send(plain_data, data.size());
delete[] plain_data; delete[] plain_data;
} }
// Returns cmd for convenience // Returns cmd for convenience
char GBASockClient::ReceiveCmd(char* data_in, bool block) char GBASockClient::ReceiveCmd(char* data_in, bool block)
{ {
if (IsDisconnected()) if (IsDisconnected())
return data_in[0]; return data_in[0];
std::size_t num_received = 0; std::size_t num_received = 0;
if (block || clock_sync == 0) if (block || clock_sync == 0) {
{ sf::SocketSelector Selector;
sf::SocketSelector Selector; Selector.add(client);
Selector.add(client); Selector.wait(sf::seconds(6));
Selector.wait(sf::seconds(6)); }
} if (client.receive(data_in, 5, num_received) == sf::Socket::Disconnected)
if (client.receive(data_in, 5, num_received) == sf::Socket::Disconnected) Disconnect();
Disconnect();
return data_in[0]; return data_in[0];
} }
void GBASockClient::ReceiveClock(bool block) void GBASockClient::ReceiveClock(bool block)
{ {
if (IsDisconnected()) if (IsDisconnected())
return; return;
char sync_ticks[4] = { 0, 0, 0, 0 }; char sync_ticks[4] = { 0, 0, 0, 0 };
std::size_t num_received = 0; std::size_t num_received = 0;
if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Disconnected) if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Disconnected)
Disconnect(); Disconnect();
if (num_received == 4) if (num_received == 4) {
{ clock_sync_ticks = 0;
clock_sync_ticks = 0; for (int i = 0; i < 4; i++)
for (int i = 0; i < 4; i++) clock_sync_ticks |= (u8)(sync_ticks[i]) << ((3 - i) * 8);
clock_sync_ticks |= (u8)(sync_ticks[i]) << ((3 - i) * 8); clock_sync += clock_sync_ticks;
clock_sync += clock_sync_ticks; }
}
} }
void GBASockClient::ClockSync(u32 ticks) void GBASockClient::ClockSync(u32 ticks)
{ {
if (clock_sync > (s32)ticks) if (clock_sync > (s32)ticks)
clock_sync -= (s32)ticks; clock_sync -= (s32)ticks;
else else
clock_sync = 0; clock_sync = 0;
} }
void GBASockClient::Disconnect() void GBASockClient::Disconnect()
{ {
is_disconnected = true; is_disconnected = true;
client.disconnect(); client.disconnect();
clock_client.disconnect(); clock_client.disconnect();
} }
bool GBASockClient::IsDisconnected() bool GBASockClient::IsDisconnected()
{ {
return is_disconnected; return is_disconnected;
} }
#endif // NO_LINK #endif // NO_LINK

View File

@ -3,26 +3,25 @@
#include "../common/Types.h" #include "../common/Types.h"
#include <SFML/Network.hpp> #include <SFML/Network.hpp>
class GBASockClient class GBASockClient {
{ public:
public: GBASockClient(sf::IpAddress _server_addr);
GBASockClient(sf::IpAddress _server_addr); ~GBASockClient();
~GBASockClient();
bool Connect(sf::IpAddress server_addr); bool Connect(sf::IpAddress server_addr);
void Send(std::vector<char> data); void Send(std::vector<char> data);
char ReceiveCmd(char *data_in, bool block); char ReceiveCmd(char* data_in, bool block);
void ReceiveClock(bool block); void ReceiveClock(bool block);
void ClockSync(u32 ticks); void ClockSync(u32 ticks);
void Disconnect(); void Disconnect();
bool IsDisconnected(); bool IsDisconnected();
private: private:
sf::IpAddress server_addr; sf::IpAddress server_addr;
sf::TcpSocket client; sf::TcpSocket client;
sf::TcpSocket clock_client; sf::TcpSocket clock_client;
s32 clock_sync; s32 clock_sync;
bool is_disconnected; bool is_disconnected;
}; };

View File

@ -18,22 +18,22 @@ extern int thumbExecute();
#define UNLIKELY(x) (x) #define UNLIKELY(x) (x)
#endif #endif
#define UPDATE_REG(address, value) \ #define UPDATE_REG(address, value) \
{ \ { \
WRITE16LE(((u16 *)&ioMem[address]), value); \ WRITE16LE(((u16*)&ioMem[address]), value); \
} }
#define ARM_PREFETCH \ #define ARM_PREFETCH \
{ \ { \
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC); \ cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC); \
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); \ cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); \
} }
#define THUMB_PREFETCH \ #define THUMB_PREFETCH \
{ \ { \
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC); \ cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC); \
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); \ cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); \
} }
#define ARM_PREFETCH_NEXT cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); #define ARM_PREFETCH_NEXT cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4);
@ -66,179 +66,172 @@ extern void CPUSoftwareInterrupt(int comment);
// Waitstates when accessing data // Waitstates when accessing data
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
int value = memoryWait[addr]; int value = memoryWait[addr];
if ((addr >= 0x08) || (addr < 0x02)) { if ((addr >= 0x08) || (addr < 0x02)) {
busPrefetchCount = 0; busPrefetchCount = 0;
busPrefetch = false; busPrefetch = false;
} else if (busPrefetch) { } else if (busPrefetch) {
int waitState = value; int waitState = value;
if (!waitState) if (!waitState)
waitState = 1; waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
} }
return value; return value;
} }
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
int value = memoryWait32[addr]; int value = memoryWait32[addr];
if ((addr >= 0x08) || (addr < 0x02)) { if ((addr >= 0x08) || (addr < 0x02)) {
busPrefetchCount = 0; busPrefetchCount = 0;
busPrefetch = false; busPrefetch = false;
} else if (busPrefetch) { } else if (busPrefetch) {
int waitState = value; int waitState = value;
if (!waitState) if (!waitState)
waitState = 1; waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
} }
return value; return value;
} }
inline int dataTicksAccessSeq16(u32 address) // DATA 8/16bits SEQ inline int dataTicksAccessSeq16(u32 address) // DATA 8/16bits SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
int value = memoryWaitSeq[addr]; int value = memoryWaitSeq[addr];
if ((addr >= 0x08) || (addr < 0x02)) { if ((addr >= 0x08) || (addr < 0x02)) {
busPrefetchCount = 0; busPrefetchCount = 0;
busPrefetch = false; busPrefetch = false;
} else if (busPrefetch) { } else if (busPrefetch) {
int waitState = value; int waitState = value;
if (!waitState) if (!waitState)
waitState = 1; waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
} }
return value; return value;
} }
inline int dataTicksAccessSeq32(u32 address) // DATA 32bits SEQ inline int dataTicksAccessSeq32(u32 address) // DATA 32bits SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
int value = memoryWaitSeq32[addr]; int value = memoryWaitSeq32[addr];
if ((addr >= 0x08) || (addr < 0x02)) { if ((addr >= 0x08) || (addr < 0x02)) {
busPrefetchCount = 0; busPrefetchCount = 0;
busPrefetch = false; busPrefetch = false;
} else if (busPrefetch) { } else if (busPrefetch) {
int waitState = value; int waitState = value;
if (!waitState) if (!waitState)
waitState = 1; waitState = 1;
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
} }
return value; return value;
} }
// Waitstates when executing opcode // Waitstates when executing opcode
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
if ((addr >= 0x08) && (addr <= 0x0D)) { if ((addr >= 0x08) && (addr <= 0x0D)) {
if (busPrefetchCount & 0x1) { if (busPrefetchCount & 0x1) {
if (busPrefetchCount & 0x2) { if (busPrefetchCount & 0x2) {
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
(busPrefetchCount & 0xFFFFFF00); return 0;
return 0; }
} busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
busPrefetchCount = return memoryWaitSeq[addr] - 1;
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return memoryWaitSeq[addr] - 1;
} else {
busPrefetchCount = 0;
return memoryWait[addr];
}
} else { } else {
busPrefetchCount = 0; busPrefetchCount = 0;
return memoryWait[addr]; return memoryWait[addr];
} }
} else {
busPrefetchCount = 0;
return memoryWait[addr];
}
} }
inline int codeTicksAccess32(u32 address) // ARM NON SEQ inline int codeTicksAccess32(u32 address) // ARM NON SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
if ((addr >= 0x08) && (addr <= 0x0D)) { if ((addr >= 0x08) && (addr <= 0x0D)) {
if (busPrefetchCount & 0x1) { if (busPrefetchCount & 0x1) {
if (busPrefetchCount & 0x2) { if (busPrefetchCount & 0x2) {
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
(busPrefetchCount & 0xFFFFFF00); return 0;
return 0; }
} busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
busPrefetchCount = return memoryWaitSeq[addr] - 1;
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
return memoryWaitSeq[addr] - 1;
} else {
busPrefetchCount = 0;
return memoryWait32[addr];
}
} else { } else {
busPrefetchCount = 0; busPrefetchCount = 0;
return memoryWait32[addr]; return memoryWait32[addr];
} }
} else {
busPrefetchCount = 0;
return memoryWait32[addr];
}
} }
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
if ((addr >= 0x08) && (addr <= 0x0D)) { if ((addr >= 0x08) && (addr <= 0x0D)) {
if (busPrefetchCount & 0x1) { if (busPrefetchCount & 0x1) {
busPrefetchCount = busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); return 0;
return 0; } else if (busPrefetchCount > 0xFF) {
} else if (busPrefetchCount > 0xFF) { busPrefetchCount = 0;
busPrefetchCount = 0; return memoryWait[addr];
return memoryWait[addr]; } else
} else return memoryWaitSeq[addr];
return memoryWaitSeq[addr]; } else {
} else { busPrefetchCount = 0;
busPrefetchCount = 0; return memoryWaitSeq[addr];
return memoryWaitSeq[addr]; }
}
} }
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
{ {
int addr = (address >> 24) & 15; int addr = (address >> 24) & 15;
if ((addr >= 0x08) && (addr <= 0x0D)) { if ((addr >= 0x08) && (addr <= 0x0D)) {
if (busPrefetchCount & 0x1) { if (busPrefetchCount & 0x1) {
if (busPrefetchCount & 0x2) { if (busPrefetchCount & 0x2) {
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00);
(busPrefetchCount & 0xFFFFFF00); return 0;
return 0; }
} busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
busPrefetchCount = return memoryWaitSeq[addr];
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); } else if (busPrefetchCount > 0xFF) {
return memoryWaitSeq[addr]; busPrefetchCount = 0;
} else if (busPrefetchCount > 0xFF) { return memoryWait32[addr];
busPrefetchCount = 0; } else
return memoryWait32[addr]; return memoryWaitSeq32[addr];
} else } else {
return memoryWaitSeq32[addr]; return memoryWaitSeq32[addr];
} else { }
return memoryWaitSeq32[addr];
}
} }
// Emulates the Cheat System (m) code // Emulates the Cheat System (m) code
inline void cpuMasterCodeCheck() inline void cpuMasterCodeCheck()
{ {
if ((mastercode) && (mastercode == armNextPC)) { if ((mastercode) && (mastercode == armNextPC)) {
u32 joy = 0; u32 joy = 0;
if (systemReadJoypads()) if (systemReadJoypads())
joy = systemReadJoypad(-1); joy = systemReadJoypad(-1);
u32 ext = (joy >> 10); u32 ext = (joy >> 10);
cpuTotalTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext); cpuTotalTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext);
} }
} }
#endif // GBACPU_H #endif // GBACPU_H

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#include "GBA.h" #include "GBA.h"
#ifdef BKPT_SUPPORT #ifdef BKPT_SUPPORT
int oldreg[18]; int oldreg[18];
char oldbuffer[10]; char oldbuffer[10];
#endif #endif
@ -23,57 +23,57 @@ u32 stop = 0x08000568;
// 0x0000 to 0x7FFF: set custom 15 bit color // 0x0000 to 0x7FFF: set custom 15 bit color
int customBackdropColor = -1; int customBackdropColor = -1;
u8 *bios = 0; u8* bios = 0;
u8 *rom = 0; u8* rom = 0;
u8 *internalRAM = 0; u8* internalRAM = 0;
u8 *workRAM = 0; u8* workRAM = 0;
u8 *paletteRAM = 0; u8* paletteRAM = 0;
u8 *vram = 0; u8* vram = 0;
u8 *pix = 0; u8* pix = 0;
u8 *oam = 0; u8* oam = 0;
u8 *ioMem = 0; u8* ioMem = 0;
u16 DISPCNT = 0x0080; u16 DISPCNT = 0x0080;
u16 DISPSTAT = 0x0000; u16 DISPSTAT = 0x0000;
u16 VCOUNT = 0x0000; u16 VCOUNT = 0x0000;
u16 BG0CNT = 0x0000; u16 BG0CNT = 0x0000;
u16 BG1CNT = 0x0000; u16 BG1CNT = 0x0000;
u16 BG2CNT = 0x0000; u16 BG2CNT = 0x0000;
u16 BG3CNT = 0x0000; u16 BG3CNT = 0x0000;
u16 BG0HOFS = 0x0000; u16 BG0HOFS = 0x0000;
u16 BG0VOFS = 0x0000; u16 BG0VOFS = 0x0000;
u16 BG1HOFS = 0x0000; u16 BG1HOFS = 0x0000;
u16 BG1VOFS = 0x0000; u16 BG1VOFS = 0x0000;
u16 BG2HOFS = 0x0000; u16 BG2HOFS = 0x0000;
u16 BG2VOFS = 0x0000; u16 BG2VOFS = 0x0000;
u16 BG3HOFS = 0x0000; u16 BG3HOFS = 0x0000;
u16 BG3VOFS = 0x0000; u16 BG3VOFS = 0x0000;
u16 BG2PA = 0x0100; u16 BG2PA = 0x0100;
u16 BG2PB = 0x0000; u16 BG2PB = 0x0000;
u16 BG2PC = 0x0000; u16 BG2PC = 0x0000;
u16 BG2PD = 0x0100; u16 BG2PD = 0x0100;
u16 BG2X_L = 0x0000; u16 BG2X_L = 0x0000;
u16 BG2X_H = 0x0000; u16 BG2X_H = 0x0000;
u16 BG2Y_L = 0x0000; u16 BG2Y_L = 0x0000;
u16 BG2Y_H = 0x0000; u16 BG2Y_H = 0x0000;
u16 BG3PA = 0x0100; u16 BG3PA = 0x0100;
u16 BG3PB = 0x0000; u16 BG3PB = 0x0000;
u16 BG3PC = 0x0000; u16 BG3PC = 0x0000;
u16 BG3PD = 0x0100; u16 BG3PD = 0x0100;
u16 BG3X_L = 0x0000; u16 BG3X_L = 0x0000;
u16 BG3X_H = 0x0000; u16 BG3X_H = 0x0000;
u16 BG3Y_L = 0x0000; u16 BG3Y_L = 0x0000;
u16 BG3Y_H = 0x0000; u16 BG3Y_H = 0x0000;
u16 WIN0H = 0x0000; u16 WIN0H = 0x0000;
u16 WIN1H = 0x0000; u16 WIN1H = 0x0000;
u16 WIN0V = 0x0000; u16 WIN0V = 0x0000;
u16 WIN1V = 0x0000; u16 WIN1V = 0x0000;
u16 WININ = 0x0000; u16 WININ = 0x0000;
u16 WINOUT = 0x0000; u16 WINOUT = 0x0000;
u16 MOSAIC = 0x0000; u16 MOSAIC = 0x0000;
u16 BLDMOD = 0x0000; u16 BLDMOD = 0x0000;
u16 COLEV = 0x0000; u16 COLEV = 0x0000;
u16 COLY = 0x0000; u16 COLY = 0x0000;
u16 DM0SAD_L = 0x0000; u16 DM0SAD_L = 0x0000;
u16 DM0SAD_H = 0x0000; u16 DM0SAD_H = 0x0000;
u16 DM0DAD_L = 0x0000; u16 DM0DAD_L = 0x0000;
@ -98,15 +98,15 @@ u16 DM3DAD_L = 0x0000;
u16 DM3DAD_H = 0x0000; u16 DM3DAD_H = 0x0000;
u16 DM3CNT_L = 0x0000; u16 DM3CNT_L = 0x0000;
u16 DM3CNT_H = 0x0000; u16 DM3CNT_H = 0x0000;
u16 TM0D = 0x0000; u16 TM0D = 0x0000;
u16 TM0CNT = 0x0000; u16 TM0CNT = 0x0000;
u16 TM1D = 0x0000; u16 TM1D = 0x0000;
u16 TM1CNT = 0x0000; u16 TM1CNT = 0x0000;
u16 TM2D = 0x0000; u16 TM2D = 0x0000;
u16 TM2CNT = 0x0000; u16 TM2CNT = 0x0000;
u16 TM3D = 0x0000; u16 TM3D = 0x0000;
u16 TM3CNT = 0x0000; u16 TM3CNT = 0x0000;
u16 P1 = 0xFFFF; u16 P1 = 0xFFFF;
u16 IE = 0x0000; u16 IE = 0x0000;
u16 IF = 0x0000; u16 IF = 0x0000;
u16 IME = 0x0000; u16 IME = 0x0000;

View File

@ -36,15 +36,15 @@ extern int layerEnable;
extern int cpuSaveType; extern int cpuSaveType;
extern int customBackdropColor; extern int customBackdropColor;
extern u8 *bios; extern u8* bios;
extern u8 *rom; extern u8* rom;
extern u8 *internalRAM; extern u8* internalRAM;
extern u8 *workRAM; extern u8* workRAM;
extern u8 *paletteRAM; extern u8* paletteRAM;
extern u8 *vram; extern u8* vram;
extern u8 *pix; extern u8* pix;
extern u8 *oam; extern u8* oam;
extern u8 *ioMem; extern u8* ioMem;
extern u16 DISPCNT; extern u16 DISPCNT;
extern u16 DISPSTAT; extern u16 DISPSTAT;

View File

@ -1,506 +1,501 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h" #include "GBAGfx.h"
#include "Globals.h"
void mode0RenderLine() void mode0RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
return;
}
if(layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if(layerEnable & 0x0800) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) {
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} return;
} }
lineMix[x] = color; if (layerEnable & 0x0100) {
} gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if (layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if (layerEnable & 0x0400) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if (layerEnable & 0x0800) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line0[x] < color) {
color = line0[x];
top = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
} }
void mode0RenderLineNoWindow() void mode0RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
return; return;
}
if(layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if(layerEnable & 0x0800) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
int effect = (BLDMOD >> 6) & 3;
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) {
color = line0[x];
top = 0x01;
} }
if(line1[x] < (color & 0xFF000000)) { if (layerEnable & 0x0100) {
color = line1[x]; gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
top = 0x02;
} }
if(line2[x] < (color & 0xFF000000)) { if (layerEnable & 0x0200) {
color = line2[x]; gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
top = 0x04;
} }
if(line3[x] < (color & 0xFF000000)) { if (layerEnable & 0x0400) {
color = line3[x]; gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
top = 0x08;
} }
if(lineOBJ[x] < (color & 0xFF000000)) { if (layerEnable & 0x0800) {
color = lineOBJ[x]; gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
top = 0x10;
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch(effect) {
case 0: u32 backdrop;
break; if (customBackdropColor == -1) {
case 1: backdrop = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
int effect = (BLDMOD >> 6) & 3;
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line0[x] < color) {
color = line0[x];
top = 0x01;
}
if (line1[x] < (color & 0xFF000000)) {
color = line1[x];
top = 0x02;
}
if (line2[x] < (color & 0xFF000000)) {
color = line2[x];
top = 0x04;
}
if (line3[x] < (color & 0xFF000000)) {
color = line3[x];
top = 0x08;
}
if (lineOBJ[x] < (color & 0xFF000000)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch (effect) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if (line0[x] < back) {
if (top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if (line1[x] < (back & 0xFF000000)) {
if (top != 0x02) {
back = line1[x];
top2 = 0x02;
}
}
if (line2[x] < (back & 0xFF000000)) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if (line3[x] < (back & 0xFF000000)) {
if (top != 0x08) {
back = line3[x];
top2 = 0x08;
}
}
if (lineOBJ[x] < (back & 0xFF000000)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line0[x] < back) {
if(top != 0x01) { if (line0[x] < back) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if(line1[x] < (back & 0xFF000000)) { if (line1[x] < (back & 0xFF000000)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if(line2[x] < (back & 0xFF000000)) { if (line2[x] < (back & 0xFF000000)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if(line3[x] < (back & 0xFF000000)) { if (line3[x] < (back & 0xFF000000)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if(lineOBJ[x] < (back & 0xFF000000)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if(line0[x] < back) { lineMix[x] = color;
back = line0[x];
top2 = 0x01;
}
if(line1[x] < (back & 0xFF000000)) {
back = line1[x];
top2 = 0x02;
}
if(line2[x] < (back & 0xFF000000)) {
back = line2[x];
top2 = 0x04;
}
if(line3[x] < (back & 0xFF000000)) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
lineMix[x] = color;
}
} }
void mode0RenderLineAll() void mode0RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
return;
}
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if((layerEnable & 0x0100)) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if((layerEnable & 0x0200)) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if((layerEnable & 0x0400)) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if((layerEnable & 0x0800)) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if((mask & 1) && (line0[x] < color)) {
color = line0[x];
top = 0x01;
}
if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24))) {
color = line1[x];
top = 0x02;
}
if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24))) {
color = line2[x];
top = 0x04;
}
if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24))) {
color = line3[x];
top = 0x08;
}
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24))) {
back = line0[x];
top2 = 0x01;
}
if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24))) {
back = line1[x];
top2 = 0x02;
}
if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24))) {
back = line2[x];
top2 = 0x04;
}
if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24))) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} return;
} else if(mask & 32) { }
// special FX on in the window
switch((BLDMOD >> 6) & 3) { bool inWindow0 = false;
case 0: bool inWindow1 = false;
break;
case 1: if (layerEnable & 0x2000) {
{ u8 v0 = WIN0V >> 8;
if(top & BLDMOD) { u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if ((layerEnable & 0x0100)) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if ((layerEnable & 0x0200)) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if ((layerEnable & 0x0400)) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if ((layerEnable & 0x0800)) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if ((mask & 1) && (line0[x] < color)) {
color = line0[x];
top = 0x01;
}
if ((mask & 2) && ((u8)(line1[x] >> 24) < (u8)(color >> 24))) {
color = line1[x];
top = 0x02;
}
if ((mask & 4) && ((u8)(line2[x] >> 24) < (u8)(color >> 24))) {
color = line2[x];
top = 0x04;
}
if ((mask & 8) && ((u8)(line3[x] >> 24) < (u8)(color >> 24))) {
color = line3[x];
top = 0x08;
}
if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) { if ((mask & 1) && ((u8)(line0[x] >> 24) < (u8)(back >> 24))) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { if ((mask & 2) && ((u8)(line1[x] >> 24) < (u8)(back >> 24))) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { if ((mask & 4) && ((u8)(line2[x] >> 24) < (u8)(back >> 24))) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { if ((mask & 8) && ((u8)(line3[x] >> 24) < (u8)(back >> 24))) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
// special FX on in the window
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if(top2 & (BLDMOD>>8)) if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) {
color = gfxAlphaBlend(color, back, if (top != 0x02) {
coeff[COLEV & 0x1F], back = line1[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x02;
} }
}
if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x08) {
back = line3[x];
top2 = 0x08;
}
}
if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
} }

View File

@ -1,473 +1,468 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h" #include "GBAGfx.h"
#include "Globals.h"
void mode1RenderLine() void mode1RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) {
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
return;
} }
lineMix[x] = color; if (layerEnable & 0x0100) {
} gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
gfxBG2Changed = 0; }
gfxLastVCOUNT = VCOUNT;
if (layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if (layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line0[x] < color) {
color = line0[x];
top = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode1RenderLineNoWindow() void mode1RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
}
if(layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line0[x] < color) {
color = line0[x];
top = 0x01;
} }
if((u8)(line1[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x0100) {
color = line1[x]; gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
top = 0x02;
} }
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x0200) {
color = line2[x]; gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
top = 0x04;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x0400) {
color = lineOBJ[x]; int changed = gfxBG2Changed;
top = 0x10; if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch((BLDMOD >> 6) & 3) {
case 0: u32 backdrop;
break; if (customBackdropColor == -1) {
case 1: backdrop = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line0[x] < color) {
color = line0[x];
top = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x02) {
back = line1[x];
top2 = 0x02;
}
}
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) { if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((u8)(line1[x]>>24) < (u8)(back >> 24)) { if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) { lineMix[x] = color;
back = line0[x];
top2 = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
gfxBG2Changed = 0;
lineMix[x] = color; gfxLastVCOUNT = VCOUNT;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode1RenderLineAll() void mode1RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if(line0[x] < color && (mask & 1)) {
color = line0[x];
top = 0x01;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) {
color = line1[x];
top = 0x02;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) {
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x];
top2 = 0x01;
}
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
} else if(mask & 32) { return;
// special FX on the window }
switch((BLDMOD >> 6) & 3) {
case 0: bool inWindow0 = false;
break; bool inWindow1 = false;
case 1:
{ if (layerEnable & 0x2000) {
if(top & BLDMOD) { u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if (layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if (layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if (line0[x] < color && (mask & 1)) {
color = line0[x];
top = 0x01;
}
if ((u8)(line1[x] >> 24) < (u8)(color >> 24) && (mask & 2)) {
color = line1[x];
top = 0x02;
}
if ((u8)(line2[x] >> 24) < (u8)(color >> 24) && (mask & 4)) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24) && (mask & 16)) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x01) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
// special FX on the window
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if(top2 & (BLDMOD>>8)) if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) {
color = gfxAlphaBlend(color, back, if (top != 0x01) {
coeff[COLEV & 0x1F], back = line0[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x01;
} }
}
if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x02) {
back = line1[x];
top2 = 0x02;
}
}
if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -1,443 +1,437 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h" #include "GBAGfx.h"
#include "Globals.h"
void mode2RenderLine() void mode2RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
}
if(layerEnable & 0x0800) {
int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
return;
} }
lineMix[x] = color; if (layerEnable & 0x0400) {
} int changed = gfxBG2Changed;
gfxBG2Changed = 0; if (gfxLastVCOUNT > VCOUNT)
gfxBG3Changed = 0; changed = 3;
gfxLastVCOUNT = VCOUNT;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
}
if (layerEnable & 0x0800) {
int changed = gfxBG3Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode2RenderLineNoWindow() void mode2RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
}
if(layerEnable & 0x0800) {
int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
} }
if((u8)(line3[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x0400) {
color = line3[x]; int changed = gfxBG2Changed;
top = 0x08; if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x0800) {
color = lineOBJ[x]; int changed = gfxBG3Changed;
top = 0x10; if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch((BLDMOD >> 6) & 3) {
case 0: u32 backdrop;
break; if (customBackdropColor == -1) {
case 1: backdrop = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x08) {
back = line3[x];
top2 = 0x08;
}
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(line3[x]>>24) < (u8)(back >> 24)) { if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { lineMix[x] = color;
back = line2[x];
top2 = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
gfxBG2Changed = 0;
lineMix[x] = color; gfxBG3Changed = 0;
} gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode2RenderLineAll() void mode2RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
}
if(layerEnable & 0x0800) {
int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if(line2[x] < color && (mask & 4)) {
color = line2[x];
top = 0x04;
}
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
color = line3[x];
top = 0x08;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
} else if(mask & 32) { return;
// special FX on the window }
switch((BLDMOD >> 6) & 3) {
case 0: bool inWindow0 = false;
break; bool inWindow1 = false;
case 1:
{ if (layerEnable & 0x2000) {
if(top & BLDMOD) { u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
}
if (layerEnable & 0x0800) {
int changed = gfxBG3Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if (line2[x] < color && (mask & 4)) {
color = line2[x];
top = 0x04;
}
if ((u8)(line3[x] >> 24) < (u8)(color >> 24) && (mask & 8)) {
color = line3[x];
top = 0x08;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24) && (mask & 16)) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if ((mask & 4) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
// special FX on the window
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if(top2 & (BLDMOD>>8)) if ((mask & 4) && line2[x] < back) {
color = gfxAlphaBlend(color, back, if (top != 0x04) {
coeff[COLEV & 0x1F], back = line2[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x04;
} }
}
if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x08) {
back = line3[x];
top2 = 0x08;
}
}
if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxBG3Changed = 0; gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -1,374 +1,368 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h" #include "GBAGfx.h"
#include "Globals.h"
void mode3RenderLine() void mode3RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if(line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
return;
} }
lineMix[x] = color; if (layerEnable & 0x0400) {
} int changed = gfxBG2Changed;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if (customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if (line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode3RenderLineNoWindow() void mode3RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { if (layerEnable & 0x0400) {
color = lineOBJ[x]; int changed = gfxBG2Changed;
top = 0x10;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch((BLDMOD >> 6) & 3) {
case 0: u32 background;
break; if (customBackdropColor == -1) {
case 1: background = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = background;
u8 top2 = 0x20;
if (line2[x] < back) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if (line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if(line2[x] < back) { lineMix[x] = color;
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
gfxBG2Changed = 0;
lineMix[x] = color; gfxLastVCOUNT = VCOUNT;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode3RenderLineAll() void mode3RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) { if (DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
} else if(mask & 32) { return;
switch((BLDMOD >> 6) & 3) { }
case 0:
break; bool inWindow0 = false;
case 1: bool inWindow1 = false;
{
if(top & BLDMOD) { if (layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
u32 background;
if (customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if ((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if ((mask & 4) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = background;
u8 top2 = 0x20;
if(top2 & (BLDMOD>>8)) if ((mask & 4) && line2[x] < back) {
color = gfxAlphaBlend(color, back, if (top != 0x04) {
coeff[COLEV & 0x1F], back = line2[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x04;
}
}
} if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -4,368 +4,362 @@
void mode4RenderLine() void mode4RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if(layerEnable & 0x400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if(line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
return;
} }
lineMix[x] = color; if (layerEnable & 0x400) {
} int changed = gfxBG2Changed;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if (line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode4RenderLineNoWindow() void mode4RenderLineNoWindow()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
}
if(layerEnable & 0x400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if (layerEnable & 0x400) {
color = lineOBJ[x]; int changed = gfxBG2Changed;
top = 0x10;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch((BLDMOD >> 6) & 3) {
case 0: u32 backdrop;
break; if (customBackdropColor == -1) {
case 1: backdrop = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if (line2[x] < back) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if (line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if(line2[x] < back) { lineMix[x] = color;
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
gfxBG2Changed = 0;
lineMix[x] = color; gfxLastVCOUNT = VCOUNT;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode4RenderLineAll() void mode4RenderLineAll()
{ {
u16 *palette = (u16 *)paletteRAM; u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if(customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
} else if(mask & 32) { return;
switch((BLDMOD >> 6) & 3) { }
case 0:
break; bool inWindow0 = false;
case 1: bool inWindow1 = false;
{
if(top & BLDMOD) { if (layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
u32 backdrop;
if (customBackdropColor == -1) {
backdrop = (READ16LE(&palette[0]) | 0x30000000);
} else {
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
for (int x = 0; x < 240; x++) {
u32 color = backdrop;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if ((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if ((mask & 4) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = backdrop;
u8 top2 = 0x20;
if(top2 & (BLDMOD>>8)) if ((mask & 4) && line2[x] < back) {
color = gfxAlphaBlend(color, back, if (top != 0x04) {
coeff[COLEV & 0x1F], back = line2[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x04;
}
}
} if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -1,374 +1,368 @@
#include "GBA.h" #include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h" #include "GBAGfx.h"
#include "Globals.h"
void mode5RenderLine() void mode5RenderLine()
{ {
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
top = 0x10;
}
if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if(line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
return;
} }
lineMix[x] = color; u16* palette = (u16*)paletteRAM;
}
gfxBG2Changed = 0; if (layerEnable & 0x0400) {
gfxLastVCOUNT = VCOUNT; int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if (customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if ((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if (line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode5RenderLineNoWindow() void mode5RenderLineNoWindow()
{ {
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
}
u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if(line2[x] < color) {
color = line2[x];
top = 0x04;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { u16* palette = (u16*)paletteRAM;
color = lineOBJ[x];
top = 0x10; if (layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
} }
if(!(color & 0x00010000)) { gfxDrawSprites(lineOBJ);
switch((BLDMOD >> 6) & 3) {
case 0: u32 background;
break; if (customBackdropColor == -1) {
case 1: background = (READ16LE(&palette[0]) | 0x30000000);
{ } else {
if(top & BLDMOD) { background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
if (line2[x] < color) {
color = line2[x];
top = 0x04;
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
}
if (!(color & 0x00010000)) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = background;
u8 top2 = 0x20;
if (line2[x] < back) {
if (top != 0x04) {
back = line2[x];
top2 = 0x04;
}
}
if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if (line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} else {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if(line2[x] < back) { lineMix[x] = color;
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
} }
gfxBG2Changed = 0;
lineMix[x] = color; gfxLastVCOUNT = VCOUNT;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
} }
void mode5RenderLineAll() void mode5RenderLineAll()
{ {
if(DISPCNT & 0x0080) { if (DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) { for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
u16 *palette = (u16 *)paletteRAM;
if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
bool inWindow0 = false;
bool inWindow1 = false;
if(layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
u32 background;
if(customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for(int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
u8 mask = outMask;
if(!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if(inWindow1) {
if(gfxInWin1[x])
mask = inWin1Mask;
}
if(inWindow0) {
if(gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
top = 0x10;
}
if(color & 0x00010000) {
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else {
switch((BLDMOD >> 6) & 3) {
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
} }
} gfxLastVCOUNT = VCOUNT;
} else if(mask & 32) { return;
switch((BLDMOD >> 6) & 3) { }
case 0:
break; u16* palette = (u16*)paletteRAM;
case 1:
{ if (layerEnable & 0x0400) {
if(top & BLDMOD) { int changed = gfxBG2Changed;
if (gfxLastVCOUNT > VCOUNT)
changed = 3;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
line2);
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin);
bool inWindow0 = false;
bool inWindow1 = false;
if (layerEnable & 0x2000) {
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
if (layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if (v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF;
u32 background;
if (customBackdropColor == -1) {
background = (READ16LE(&palette[0]) | 0x30000000);
} else {
background = ((customBackdropColor & 0x7FFF) | 0x30000000);
}
for (int x = 0; x < 240; x++) {
u32 color = background;
u8 top = 0x20;
u8 mask = outMask;
if (!(lineOBJWin[x] & 0x80000000)) {
mask = WINOUT >> 8;
}
if (inWindow1) {
if (gfxInWin1[x])
mask = inWin1Mask;
}
if (inWindow0) {
if (gfxInWin0[x]) {
mask = inWin0Mask;
}
}
if ((mask & 4) && (line2[x] < color)) {
color = line2[x];
top = 0x04;
}
if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) {
color = lineOBJ[x];
top = 0x10;
}
if (color & 0x00010000) {
// semi-transparent OBJ
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if ((mask & 4) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if (top2 & (BLDMOD >> 8))
if(top != 0x10) { color = gfxAlphaBlend(color, back,
back = lineOBJ[x]; coeff[COLEV & 0x1F],
top2 = 0x10; coeff[(COLEV >> 8) & 0x1F]);
} else {
switch ((BLDMOD >> 6) & 3) {
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
} else if (mask & 32) {
switch ((BLDMOD >> 6) & 3) {
case 0:
break;
case 1: {
if (top & BLDMOD) {
u32 back = background;
u8 top2 = 0x20;
if(top2 & (BLDMOD>>8)) if ((mask & 4) && line2[x] < back) {
color = gfxAlphaBlend(color, back, if (top != 0x04) {
coeff[COLEV & 0x1F], back = line2[x];
coeff[(COLEV >> 8) & 0x1F]); top2 = 0x04;
}
}
} if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x10) {
back = lineOBJ[x];
top2 = 0x10;
}
}
if (top2 & (BLDMOD >> 8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
} break;
case 2:
if (BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if (BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
} }
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
lineMix[x] = color; lineMix[x] = color;
} }
gfxBG2Changed = 0; gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
} }

View File

@ -1,36 +1,35 @@
#include "../NLS.h"
#include "../System.h" #include "../System.h"
#include "../Util.h"
#include "../common/Port.h"
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "../common/Port.h"
#include "../Util.h"
#include "../NLS.h"
#include <time.h>
#include <memory.h> #include <memory.h>
#include <string.h> #include <string.h>
#include <time.h>
enum RTCSTATE enum RTCSTATE {
{ IDLE = 0,
IDLE = 0, COMMAND,
COMMAND, DATA,
DATA, READDATA
READDATA
}; };
typedef struct typedef struct
{ {
u8 byte0; u8 byte0;
u8 select; u8 select;
u8 enable; u8 enable;
u8 command; u8 command;
int dataLen; int dataLen;
int bits; int bits;
RTCSTATE state; RTCSTATE state;
u8 data[12]; u8 data[12];
// reserved variables for future // reserved variables for future
u8 reserved[12]; u8 reserved[12];
bool reserved2; bool reserved2;
u32 reserved3; u32 reserved3;
} RTCCLOCKDATA; } RTCCLOCKDATA;
struct tm gba_time; struct tm gba_time;
@ -42,330 +41,287 @@ u32 countTicks = 0;
void rtcEnable(bool e) void rtcEnable(bool e)
{ {
rtcClockEnabled = e; rtcClockEnabled = e;
} }
bool rtcIsEnabled() bool rtcIsEnabled()
{ {
return rtcClockEnabled; return rtcClockEnabled;
} }
void rtcEnableRumble(bool e) void rtcEnableRumble(bool e)
{ {
rtcRumbleEnabled = e; rtcRumbleEnabled = e;
} }
u16 rtcRead(u32 address) u16 rtcRead(u32 address)
{ {
int res = 0; int res = 0;
switch (address) switch (address) {
{ case 0x80000c8:
case 0x80000c8: return rtcClockData.enable;
return rtcClockData.enable; break;
break;
case 0x80000c6: case 0x80000c6:
return rtcClockData.select; return rtcClockData.select;
break; break;
case 0x80000c4: case 0x80000c4:
if (!(rtcClockData.enable & 1)) if (!(rtcClockData.enable & 1)) {
{ return 0;
return 0; }
}
// Boktai Solar Sensor // Boktai Solar Sensor
if (rtcClockData.select == 0x07) if (rtcClockData.select == 0x07) {
{ if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) {
if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) res |= 8;
{ }
res |= 8; }
}
}
// WarioWare Twisted Tilt Sensor // WarioWare Twisted Tilt Sensor
if (rtcClockData.select == 0x0b) if (rtcClockData.select == 0x0b) {
{ u16 v = systemGetSensorZ();
u16 v = systemGetSensorZ(); v = 0x6C0 + v;
v = 0x6C0 + v; res |= ((v >> rtcClockData.reserved[11]) & 1) << 2;
res |= ((v >> rtcClockData.reserved[11]) & 1) << 2; }
}
// Real Time Clock // Real Time Clock
if (rtcClockEnabled && (rtcClockData.select & 0x04)) if (rtcClockEnabled && (rtcClockData.select & 0x04)) {
{ res |= rtcClockData.byte0;
res |= rtcClockData.byte0; }
}
return res; return res;
break; break;
} }
return READ16LE((&rom[address & 0x1FFFFFE])); return READ16LE((&rom[address & 0x1FFFFFE]));
} }
static u8 toBCD(u8 value) static u8 toBCD(u8 value)
{ {
value = value % 100; value = value % 100;
int l = value % 10; int l = value % 10;
int h = value / 10; int h = value / 10;
return h * 16 + l; return h * 16 + l;
} }
void SetGBATime() void SetGBATime()
{ {
time_t long_time; time_t long_time;
time(&long_time); /* Get time as long integer. */ time(&long_time); /* Get time as long integer. */
gba_time = *localtime(&long_time); /* Convert to local time. */ gba_time = *localtime(&long_time); /* Convert to local time. */
} }
void rtcUpdateTime(int ticks) void rtcUpdateTime(int ticks)
{ {
countTicks += ticks; countTicks += ticks;
if (countTicks > TICKS_PER_SECOND) if (countTicks > TICKS_PER_SECOND) {
{ countTicks -= TICKS_PER_SECOND;
countTicks -= TICKS_PER_SECOND; gba_time.tm_sec++;
gba_time.tm_sec++; mktime(&gba_time);
mktime(&gba_time); }
}
} }
bool rtcWrite(u32 address, u16 value) bool rtcWrite(u32 address, u16 value)
{ {
if (address == 0x80000c8) if (address == 0x80000c8) {
{ rtcClockData.enable = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8
rtcClockData.enable = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8 } else if (address == 0x80000c6) {
} rtcClockData.select = (u8)value; // 0=read/1=write (for each of 4 low bits)
else if (address == 0x80000c6)
{
rtcClockData.select = (u8)value; // 0=read/1=write (for each of 4 low bits)
// rumble is off when not writing to that pin // rumble is off when not writing to that pin
if (rtcRumbleEnabled && !(value & 8)) systemCartridgeRumble(false); if (rtcRumbleEnabled && !(value & 8))
} systemCartridgeRumble(false);
else if (address == 0x80000c4) // 4 bits of I/O Port Data (upper bits not used) } else if (address == 0x80000c4) // 4 bits of I/O Port Data (upper bits not used)
{ {
// WarioWare Twisted rumble // WarioWare Twisted rumble
if (rtcRumbleEnabled && (rtcClockData.select & 0x08)) if (rtcRumbleEnabled && (rtcClockData.select & 0x08)) {
{ systemCartridgeRumble(value & 8);
systemCartridgeRumble(value & 8); }
}
// Boktai solar sensor // Boktai solar sensor
if (rtcClockData.select == 0x07) if (rtcClockData.select == 0x07) {
{ if (value & 2) {
if (value & 2) // reset counter to 0
{ rtcClockData.reserved[11] = 0;
// reset counter to 0 }
rtcClockData.reserved[11] = 0;
}
if ((value & 1) && !(rtcClockData.reserved[10] & 1)) if ((value & 1) && !(rtcClockData.reserved[10] & 1)) {
{ // increase counter, ready to do another read
// increase counter, ready to do another read if (rtcClockData.reserved[11] < 255) {
if (rtcClockData.reserved[11] < 255) rtcClockData.reserved[11]++;
{ } else {
rtcClockData.reserved[11]++; rtcClockData.reserved[11] = 0;
} }
else }
{
rtcClockData.reserved[11] = 0;
}
}
rtcClockData.reserved[10] = value & rtcClockData.select; rtcClockData.reserved[10] = value & rtcClockData.select;
} }
// WarioWare Twisted rotation sensor // WarioWare Twisted rotation sensor
if (rtcClockData.select == 0x0b) if (rtcClockData.select == 0x0b) {
{ if (value & 2) {
if (value & 2) // clock goes high in preperation for reading a bit
{ rtcClockData.reserved[11]--;
// clock goes high in preperation for reading a bit }
rtcClockData.reserved[11]--;
}
if (value & 1) if (value & 1) {
{ // start ADC conversion
// start ADC conversion rtcClockData.reserved[11] = 15;
rtcClockData.reserved[11] = 15; }
}
rtcClockData.byte0 = value & rtcClockData.select; rtcClockData.byte0 = value & rtcClockData.select;
} }
// Real Time Clock // Real Time Clock
if (rtcClockData.select & 4) if (rtcClockData.select & 4) {
{ if (rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
if (rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) rtcClockData.state = COMMAND;
{ rtcClockData.bits = 0;
rtcClockData.state = COMMAND; rtcClockData.command = 0;
rtcClockData.bits = 0; } else if (!(rtcClockData.byte0 & 1) && (value & 1)) // bit transfer
rtcClockData.command = 0; {
} rtcClockData.byte0 = (u8)value;
else if (!(rtcClockData.byte0 & 1) && (value & 1)) // bit transfer
{
rtcClockData.byte0 = (u8)value;
switch (rtcClockData.state) switch (rtcClockData.state) {
{ case COMMAND:
case COMMAND: rtcClockData.command |= ((value & 2) >> 1) << (7 - rtcClockData.bits);
rtcClockData.command |= ((value & 2) >> 1) << (7 - rtcClockData.bits); rtcClockData.bits++;
rtcClockData.bits++;
if (rtcClockData.bits == 8) if (rtcClockData.bits == 8) {
{ rtcClockData.bits = 0;
rtcClockData.bits = 0;
switch (rtcClockData.command) switch (rtcClockData.command) {
{ case 0x60:
case 0x60: // not sure what this command does but it doesn't take parameters
// not sure what this command does but it doesn't take parameters // maybe it is a reset or stop
// maybe it is a reset or stop rtcClockData.state = IDLE;
rtcClockData.state = IDLE; rtcClockData.bits = 0;
rtcClockData.bits = 0; break;
break;
case 0x62: case 0x62:
// this sets the control state but not sure what those values are // this sets the control state but not sure what those values are
rtcClockData.state = READDATA; rtcClockData.state = READDATA;
rtcClockData.dataLen = 1; rtcClockData.dataLen = 1;
break; break;
case 0x63: case 0x63:
rtcClockData.dataLen = 1; rtcClockData.dataLen = 1;
rtcClockData.data[0] = 0x40; rtcClockData.data[0] = 0x40;
rtcClockData.state = DATA; rtcClockData.state = DATA;
break; break;
case 0x64: case 0x64:
break; break;
case 0x65: case 0x65: {
{ if (rtcEnabled)
if (rtcEnabled) SetGBATime();
SetGBATime();
rtcClockData.dataLen = 7; rtcClockData.dataLen = 7;
rtcClockData.data[0] = toBCD(gba_time.tm_year); rtcClockData.data[0] = toBCD(gba_time.tm_year);
rtcClockData.data[1] = toBCD(gba_time.tm_mon + 1); rtcClockData.data[1] = toBCD(gba_time.tm_mon + 1);
rtcClockData.data[2] = toBCD(gba_time.tm_mday); rtcClockData.data[2] = toBCD(gba_time.tm_mday);
rtcClockData.data[3] = toBCD(gba_time.tm_wday); rtcClockData.data[3] = toBCD(gba_time.tm_wday);
rtcClockData.data[4] = toBCD(gba_time.tm_hour); rtcClockData.data[4] = toBCD(gba_time.tm_hour);
rtcClockData.data[5] = toBCD(gba_time.tm_min); rtcClockData.data[5] = toBCD(gba_time.tm_min);
rtcClockData.data[6] = toBCD(gba_time.tm_sec); rtcClockData.data[6] = toBCD(gba_time.tm_sec);
rtcClockData.state = DATA; rtcClockData.state = DATA;
} } break;
break;
case 0x67: case 0x67: {
{ if (rtcEnabled)
if (rtcEnabled) SetGBATime();
SetGBATime();
rtcClockData.dataLen = 3; rtcClockData.dataLen = 3;
rtcClockData.data[0] = toBCD(gba_time.tm_hour); rtcClockData.data[0] = toBCD(gba_time.tm_hour);
rtcClockData.data[1] = toBCD(gba_time.tm_min); rtcClockData.data[1] = toBCD(gba_time.tm_min);
rtcClockData.data[2] = toBCD(gba_time.tm_sec); rtcClockData.data[2] = toBCD(gba_time.tm_sec);
rtcClockData.state = DATA; rtcClockData.state = DATA;
} } break;
break;
default: default:
log(N_("Unknown RTC command %02x"), rtcClockData.command); log(N_("Unknown RTC command %02x"), rtcClockData.command);
rtcClockData.state = IDLE; rtcClockData.state = IDLE;
break; break;
} }
} }
break; break;
case DATA: case DATA:
if (rtcClockData.select & 2) if (rtcClockData.select & 2) {
{ } else if (rtcClockData.select & 4) {
} rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | ((rtcClockData.data[rtcClockData.bits >> 3] >> (rtcClockData.bits & 7)) & 1) * 2;
else if (rtcClockData.select & 4) rtcClockData.bits++;
{
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
((rtcClockData.data[rtcClockData.bits >> 3] >>
(rtcClockData.bits & 7)) & 1) * 2;
rtcClockData.bits++;
if (rtcClockData.bits == 8 * rtcClockData.dataLen) if (rtcClockData.bits == 8 * rtcClockData.dataLen) {
{ rtcClockData.bits = 0;
rtcClockData.bits = 0; rtcClockData.state = IDLE;
rtcClockData.state = IDLE; }
} }
}
break; break;
case READDATA: case READDATA:
if (!(rtcClockData.select & 2)) if (!(rtcClockData.select & 2)) {
{ } else {
} rtcClockData.data[rtcClockData.bits >> 3] = (rtcClockData.data[rtcClockData.bits >> 3] >> 1) | ((value << 6) & 128);
else rtcClockData.bits++;
{
rtcClockData.data[rtcClockData.bits >> 3] =
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
((value << 6) & 128);
rtcClockData.bits++;
if (rtcClockData.bits == 8 * rtcClockData.dataLen) if (rtcClockData.bits == 8 * rtcClockData.dataLen) {
{ rtcClockData.bits = 0;
rtcClockData.bits = 0; rtcClockData.state = IDLE;
rtcClockData.state = IDLE; }
} }
}
break; break;
default: default:
break; break;
} }
} } else
else rtcClockData.byte0 = (u8)value;
rtcClockData.byte0 = (u8)value; }
} }
}
return true; return true;
} }
void rtcReset() void rtcReset()
{ {
memset(&rtcClockData, 0, sizeof(rtcClockData)); memset(&rtcClockData, 0, sizeof(rtcClockData));
rtcClockData.byte0 = 0; rtcClockData.byte0 = 0;
rtcClockData.select = 0; rtcClockData.select = 0;
rtcClockData.enable = 0; rtcClockData.enable = 0;
rtcClockData.command = 0; rtcClockData.command = 0;
rtcClockData.dataLen = 0; rtcClockData.dataLen = 0;
rtcClockData.bits = 0; rtcClockData.bits = 0;
rtcClockData.state = IDLE; rtcClockData.state = IDLE;
rtcClockData.reserved[11] = 0; rtcClockData.reserved[11] = 0;
SetGBATime(); SetGBATime();
} }
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
void rtcSaveGame(u8* &data) void rtcSaveGame(u8*& data)
{ {
utilWriteMem(data, &rtcClockData, sizeof(rtcClockData)); utilWriteMem(data, &rtcClockData, sizeof(rtcClockData));
} }
void rtcReadGame(const u8* &data) void rtcReadGame(const u8*& data)
{ {
utilReadMem(&rtcClockData, data, sizeof(rtcClockData)); utilReadMem(&rtcClockData, data, sizeof(rtcClockData));
} }
#else #else
void rtcSaveGame(gzFile gzFile) void rtcSaveGame(gzFile gzFile)
{ {
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData)); utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
} }
void rtcReadGame(gzFile gzFile) void rtcReadGame(gzFile gzFile)
{ {
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData)); utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
} }
#endif #endif

View File

@ -10,8 +10,8 @@ bool rtcIsEnabled();
void rtcReset(); void rtcReset();
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
void rtcReadGame(const u8 *&data); void rtcReadGame(const u8*& data);
void rtcSaveGame(u8 *&data); void rtcSaveGame(u8*& data);
#else #else
void rtcReadGame(gzFile gzFile); void rtcReadGame(gzFile gzFile);
void rtcSaveGame(gzFile gzFile); void rtcSaveGame(gzFile gzFile);

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ void soundSetSampleRate(long sampleRate);
// Sound settings // Sound settings
extern bool soundInterpolation; // 1 if PCM should have low-pass filtering extern bool soundInterpolation; // 1 if PCM should have low-pass filtering
extern float soundFiltering; // 0.0 = none, 1.0 = max extern float soundFiltering; // 0.0 = none, 1.0 = max
//// GBA sound emulation //// GBA sound emulation
@ -70,12 +70,12 @@ void interp_rate();
// Notifies emulator that SOUND_CLOCK_TICKS clocks have passed // Notifies emulator that SOUND_CLOCK_TICKS clocks have passed
void psoundTickfn(); void psoundTickfn();
extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to soundTick() extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to soundTick()
extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called
// Saves/loads emulator state // Saves/loads emulator state
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
void soundSaveGame(u8 *&); void soundSaveGame(u8*&);
void soundReadGame(const u8 *&in, int version); void soundReadGame(const u8*& in, int version);
#else #else
void soundSaveGame(gzFile); void soundSaveGame(gzFile);
void soundReadGame(gzFile, int version); void soundReadGame(gzFile, int version);
@ -83,6 +83,6 @@ void soundReadGame(gzFile, int version);
class Multi_Buffer; class Multi_Buffer;
void flush_samples(Multi_Buffer *buffer); void flush_samples(Multi_Buffer* buffer);
#endif // SOUND_H #endif // SOUND_H

View File

@ -1,21 +1,21 @@
#include "Sram.h"
#include "Flash.h"
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Flash.h"
#include "Sram.h"
u8 sramRead(u32 address) u8 sramRead(u32 address)
{ {
return flashSaveMemory[address & 0xFFFF]; return flashSaveMemory[address & 0xFFFF];
} }
void sramDelayedWrite(u32 address, u8 byte) void sramDelayedWrite(u32 address, u8 byte)
{ {
saveType = 2; saveType = 2;
cpuSaveGameFunc = sramWrite; cpuSaveGameFunc = sramWrite;
sramWrite(address, byte); sramWrite(address, byte);
} }
void sramWrite(u32 address, u8 byte) void sramWrite(u32 address, u8 byte)
{ {
flashSaveMemory[address & 0xFFFF] = byte; flashSaveMemory[address & 0xFFFF] = byte;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
} }

View File

@ -1,80 +1,79 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../System.h"
#include "../common/Port.h"
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "../common/Port.h"
#include "../System.h"
#define debuggerWriteHalfWord(addr, value) \ #define debuggerWriteHalfWord(addr, value) \
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value)) WRITE16LE((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask], (value))
#define debuggerReadHalfWord(addr) \ #define debuggerReadHalfWord(addr) \
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) READ16LE(((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]))
static bool agbPrintEnabled = false; static bool agbPrintEnabled = false;
static bool agbPrintProtect = false; static bool agbPrintProtect = false;
bool agbPrintWrite(u32 address, u16 value) bool agbPrintWrite(u32 address, u16 value)
{ {
if(agbPrintEnabled) { if (agbPrintEnabled) {
if(address == 0x9fe2ffe) { // protect if (address == 0x9fe2ffe) { // protect
agbPrintProtect = (value != 0); agbPrintProtect = (value != 0);
debuggerWriteHalfWord(address, value); debuggerWriteHalfWord(address, value);
return true; return true;
} else { } else {
if(agbPrintProtect && if (agbPrintProtect && ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure || (address >= 0x8fd0000 && address <= 0x8fdffff)
|| (address >= 0x8fd0000 && address <= 0x8fdffff) || (address >= 0x9fd0000 && address <= 0x9fdffff))) {
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) { debuggerWriteHalfWord(address, value);
debuggerWriteHalfWord(address, value); return true;
return true; }
} }
} }
} return false;
return false;
} }
void agbPrintReset() void agbPrintReset()
{ {
agbPrintProtect = false; agbPrintProtect = false;
} }
void agbPrintEnable(bool enable) void agbPrintEnable(bool enable)
{ {
agbPrintEnabled = enable; agbPrintEnabled = enable;
} }
bool agbPrintIsEnabled() bool agbPrintIsEnabled()
{ {
return agbPrintEnabled; return agbPrintEnabled;
} }
void agbPrintFlush() void agbPrintFlush()
{ {
u16 get = debuggerReadHalfWord(0x9fe20fc); u16 get = debuggerReadHalfWord(0x9fe20fc);
u16 put = debuggerReadHalfWord(0x9fe20fe); u16 put = debuggerReadHalfWord(0x9fe20fe);
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16); u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
if(address != 0xfd0000 && address != 0x1fd0000) { if (address != 0xfd0000 && address != 0x1fd0000) {
dbgOutput("Did you forget to call AGBPrintInit?\n", 0); dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
// get rid of the text otherwise we will continue to be called // get rid of the text otherwise we will continue to be called
debuggerWriteHalfWord(0x9fe20fc, put); debuggerWriteHalfWord(0x9fe20fc, put);
return; return;
} }
u8 *data = &rom[address]; u8* data = &rom[address];
while(get != put) { while (get != put) {
char c = data[get++]; char c = data[get++];
char s[2]; char s[2];
s[0] = c; s[0] = c;
s[1] = 0; s[1] = 0;
if(systemVerbose & VERBOSE_AGBPRINT) if (systemVerbose & VERBOSE_AGBPRINT)
dbgOutput(s, 0); dbgOutput(s, 0);
if(c == '\n') if (c == '\n')
break; break;
} }
debuggerWriteHalfWord(0x9fe20fc, get); debuggerWriteHalfWord(0x9fe20fc, get);
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
#define DIS_VIEW_ADDRESS 1 #define DIS_VIEW_ADDRESS 1
#define DIS_VIEW_CODE 2 #define DIS_VIEW_CODE 2
int disThumb(u32 offset, char *dest, int flags); int disThumb(u32 offset, char* dest, int flags);
int disArm(u32 offset, char *dest, int flags); int disArm(u32 offset, char* dest, int flags);
#endif // __ARMDIS_H__ #endif // __ARMDIS_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
#ifndef ELF_H #ifndef ELF_H
#define ELF_H #define ELF_H
enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value }; enum LocationType { LOCATION_register,
LOCATION_memory,
LOCATION_value };
#define DW_ATE_boolean 0x02 #define DW_ATE_boolean 0x02
#define DW_ATE_signed 0x05 #define DW_ATE_signed 0x05
@ -9,253 +11,253 @@ enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value };
#define DW_ATE_unsigned_char 0x08 #define DW_ATE_unsigned_char 0x08
struct ELFHeader { struct ELFHeader {
u32 magic; u32 magic;
u8 clazz; u8 clazz;
u8 data; u8 data;
u8 version; u8 version;
u8 pad[9]; u8 pad[9];
u16 e_type; u16 e_type;
u16 e_machine; u16 e_machine;
u32 e_version; u32 e_version;
u32 e_entry; u32 e_entry;
u32 e_phoff; u32 e_phoff;
u32 e_shoff; u32 e_shoff;
u32 e_flags; u32 e_flags;
u16 e_ehsize; u16 e_ehsize;
u16 e_phentsize; u16 e_phentsize;
u16 e_phnum; u16 e_phnum;
u16 e_shentsize; u16 e_shentsize;
u16 e_shnum; u16 e_shnum;
u16 e_shstrndx; u16 e_shstrndx;
}; };
struct ELFProgramHeader { struct ELFProgramHeader {
u32 type; u32 type;
u32 offset; u32 offset;
u32 vaddr; u32 vaddr;
u32 paddr; u32 paddr;
u32 filesz; u32 filesz;
u32 memsz; u32 memsz;
u32 flags; u32 flags;
u32 align; u32 align;
}; };
struct ELFSectionHeader { struct ELFSectionHeader {
u32 name; u32 name;
u32 type; u32 type;
u32 flags; u32 flags;
u32 addr; u32 addr;
u32 offset; u32 offset;
u32 size; u32 size;
u32 link; u32 link;
u32 info; u32 info;
u32 addralign; u32 addralign;
u32 entsize; u32 entsize;
}; };
struct ELFSymbol { struct ELFSymbol {
u32 name; u32 name;
u32 value; u32 value;
u32 size; u32 size;
u8 info; u8 info;
u8 other; u8 other;
u16 shndx; u16 shndx;
}; };
struct ELFBlock { struct ELFBlock {
int length; int length;
u8 *data; u8* data;
}; };
struct ELFAttr { struct ELFAttr {
u32 name; u32 name;
u32 form; u32 form;
union { union {
u32 value; u32 value;
char *string; char* string;
u8 *data; u8* data;
bool flag; bool flag;
ELFBlock *block; ELFBlock* block;
}; };
}; };
struct ELFAbbrev { struct ELFAbbrev {
u32 number; u32 number;
u32 tag; u32 tag;
bool hasChildren; bool hasChildren;
int numAttrs; int numAttrs;
ELFAttr *attrs; ELFAttr* attrs;
ELFAbbrev *next; ELFAbbrev* next;
}; };
enum TypeEnum { enum TypeEnum {
TYPE_base, TYPE_base,
TYPE_pointer, TYPE_pointer,
TYPE_function, TYPE_function,
TYPE_void, TYPE_void,
TYPE_array, TYPE_array,
TYPE_struct, TYPE_struct,
TYPE_reference, TYPE_reference,
TYPE_enum, TYPE_enum,
TYPE_union TYPE_union
}; };
struct Type; struct Type;
struct Object; struct Object;
struct FunctionType { struct FunctionType {
Type *returnType; Type* returnType;
Object *args; Object* args;
}; };
struct Member { struct Member {
char *name; char* name;
Type *type; Type* type;
int bitSize; int bitSize;
int bitOffset; int bitOffset;
int byteSize; int byteSize;
ELFBlock *location; ELFBlock* location;
}; };
struct Struct { struct Struct {
int memberCount; int memberCount;
Member *members; Member* members;
}; };
struct Array { struct Array {
Type *type; Type* type;
int maxBounds; int maxBounds;
int *bounds; int* bounds;
}; };
struct EnumMember { struct EnumMember {
char *name; char* name;
u32 value; u32 value;
}; };
struct Enum { struct Enum {
int count; int count;
EnumMember *members; EnumMember* members;
}; };
struct Type { struct Type {
u32 offset; u32 offset;
TypeEnum type; TypeEnum type;
const char *name; const char* name;
int encoding; int encoding;
int size; int size;
int bitSize; int bitSize;
union { union {
Type *pointer; Type* pointer;
FunctionType *function; FunctionType* function;
Array *array; Array* array;
Struct *structure; Struct* structure;
Enum *enumeration; Enum* enumeration;
}; };
Type *next; Type* next;
}; };
struct Object { struct Object {
char *name; char* name;
int file; int file;
int line; int line;
bool external; bool external;
Type *type; Type* type;
ELFBlock *location; ELFBlock* location;
u32 startScope; u32 startScope;
u32 endScope; u32 endScope;
Object *next; Object* next;
}; };
struct Function { struct Function {
char *name; char* name;
u32 lowPC; u32 lowPC;
u32 highPC; u32 highPC;
int file; int file;
int line; int line;
bool external; bool external;
Type *returnType; Type* returnType;
Object *parameters; Object* parameters;
Object *variables; Object* variables;
ELFBlock *frameBase; ELFBlock* frameBase;
Function *next; Function* next;
}; };
struct LineInfoItem { struct LineInfoItem {
u32 address; u32 address;
char *file; char* file;
int line; int line;
}; };
struct LineInfo { struct LineInfo {
int fileCount; int fileCount;
char **files; char** files;
int number; int number;
LineInfoItem *lines; LineInfoItem* lines;
}; };
struct ARange { struct ARange {
u32 lowPC; u32 lowPC;
u32 highPC; u32 highPC;
}; };
struct ARanges { struct ARanges {
u32 offset; u32 offset;
int count; int count;
ARange *ranges; ARange* ranges;
}; };
struct CompileUnit { struct CompileUnit {
u32 length; u32 length;
u8 *top; u8* top;
u32 offset; u32 offset;
ELFAbbrev **abbrevs; ELFAbbrev** abbrevs;
ARanges *ranges; ARanges* ranges;
char *name; char* name;
char *compdir; char* compdir;
u32 lowPC; u32 lowPC;
u32 highPC; u32 highPC;
bool hasLineInfo; bool hasLineInfo;
u32 lineInfo; u32 lineInfo;
LineInfo *lineInfoTable; LineInfo* lineInfoTable;
Function *functions; Function* functions;
Function *lastFunction; Function* lastFunction;
Object *variables; Object* variables;
Type *types; Type* types;
CompileUnit *next; CompileUnit* next;
}; };
struct DebugInfo { struct DebugInfo {
u8 *debugfile; u8* debugfile;
u8 *abbrevdata; u8* abbrevdata;
u8 *debugdata; u8* debugdata;
u8 *infodata; u8* infodata;
int numRanges; int numRanges;
ARanges *ranges; ARanges* ranges;
}; };
struct Symbol { struct Symbol {
const char *name; const char* name;
int type; int type;
int binding; int binding;
u32 address; u32 address;
u32 value; u32 value;
u32 size; u32 size;
}; };
extern u32 elfReadLEB128(u8 *, int *); extern u32 elfReadLEB128(u8*, int*);
extern s32 elfReadSignedLEB128(u8 *, int *); extern s32 elfReadSignedLEB128(u8*, int*);
extern bool elfRead(const char *, int &, FILE *f); extern bool elfRead(const char*, int&, FILE* f);
extern bool elfGetSymbolAddress(const char *, u32 *, u32 *, int *); extern bool elfGetSymbolAddress(const char*, u32*, u32*, int*);
extern const char *elfGetAddressSymbol(u32); extern const char* elfGetAddressSymbol(u32);
extern const char *elfGetSymbol(int, u32 *, u32 *, int *); extern const char* elfGetSymbol(int, u32*, u32*, int*);
extern void elfCleanUp(); extern void elfCleanUp();
extern bool elfGetCurrentFunction(u32, Function **, CompileUnit **c); extern bool elfGetCurrentFunction(u32, Function**, CompileUnit** c);
extern bool elfGetObject(const char *, Function *, CompileUnit *, Object **); extern bool elfGetObject(const char*, Function*, CompileUnit*, Object**);
extern bool elfFindLineInUnit(u32 *, CompileUnit *, int); extern bool elfFindLineInUnit(u32*, CompileUnit*, int);
extern bool elfFindLineInModule(u32 *, const char *, int); extern bool elfFindLineInModule(u32*, const char*, int);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *); u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *, u32); u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*, u32);
int elfFindLine(CompileUnit *unit, Function *func, u32 addr, const char **); int elfFindLine(CompileUnit* unit, Function* func, u32 addr, const char**);
#endif // ELF_H #endif // ELF_H

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
extern unsigned char *DotCodeData; extern unsigned char* DotCodeData;
extern char filebuffer[]; extern char filebuffer[];
int OpenDotCodeFile(void); int OpenDotCodeFile(void);
int CheckEReaderRegion(void); int CheckEReaderRegion(void);
int LoadDotCodeData(int size, u32 *DCdata, unsigned long MEM1, unsigned long MEM2); int LoadDotCodeData(int size, u32* DCdata, unsigned long MEM1, unsigned long MEM2);
void EReaderWriteMemory(u32 address, u32 value); void EReaderWriteMemory(u32 address, u32 value);
void BIOS_EReader_ScanCard(int swi_num); void BIOS_EReader_ScanCard(int swi_num);

View File

@ -11,190 +11,204 @@ extern u16 systemColorMap16[0x10000];
extern u32 systemColorMap32[0x10000]; extern u32 systemColorMap32[0x10000];
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12, static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38, 0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0}; 0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0 };
// output R G B // output R G B
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
8, 16, 8, // green 8, 16, 8, // green
0, 8, 16};// blue 0, 8, 16 }; // blue
inline void swap(short & a, short & b) inline void swap(short& a, short& b)
{ {
short temp = a; short temp = a;
a = b; a = b;
b = temp; b = temp;
} }
void gbafilter_pal(u16 * buf, int count) void gbafilter_pal(u16* buf, int count)
{ {
short temp[3 * 3], s; short temp[3 * 3], s;
unsigned pix; unsigned pix;
u8 red, green, blue; u8 red, green, blue;
while (count--) while (count--) {
{ pix = *buf;
pix = *buf;
s = curve[(pix >> systemGreenShift) & 0x1f]; s = curve[(pix >> systemGreenShift) & 0x1f];
temp[3] = s * influence[3]; temp[3] = s * influence[3];
temp[4] = s * influence[4]; temp[4] = s * influence[4];
temp[5] = s * influence[5]; temp[5] = s * influence[5];
s = curve[(pix >> systemRedShift) & 0x1f]; s = curve[(pix >> systemRedShift) & 0x1f];
temp[0] = s * influence[0]; temp[0] = s * influence[0];
temp[1] = s * influence[1]; temp[1] = s * influence[1];
temp[2] = s * influence[2]; temp[2] = s * influence[2];
s = curve[(pix >> systemBlueShift) & 0x1f]; s = curve[(pix >> systemBlueShift) & 0x1f];
temp[6] = s * influence[6]; temp[6] = s * influence[6];
temp[7] = s * influence[7]; temp[7] = s * influence[7];
temp[8] = s * influence[8]; temp[8] = s * influence[8];
if (temp[0] < temp[3]) swap(temp[0], temp[3]); if (temp[0] < temp[3])
if (temp[0] < temp[6]) swap(temp[0], temp[6]); swap(temp[0], temp[3]);
if (temp[3] < temp[6]) swap(temp[3], temp[6]); if (temp[0] < temp[6])
temp[3] <<= 1; swap(temp[0], temp[6]);
temp[0] <<= 2; if (temp[3] < temp[6])
temp[0] += temp[3] + temp[6]; swap(temp[3], temp[6]);
temp[3] <<= 1;
temp[0] <<= 2;
temp[0] += temp[3] + temp[6];
red = ((int(temp[0]) * 160) >> 17) + 4; red = ((int(temp[0]) * 160) >> 17) + 4;
if (red > 31) red = 31; if (red > 31)
red = 31;
if (temp[2] < temp[5]) swap(temp[2], temp[5]); if (temp[2] < temp[5])
if (temp[2] < temp[8]) swap(temp[2], temp[8]); swap(temp[2], temp[5]);
if (temp[5] < temp[8]) swap(temp[5], temp[8]); if (temp[2] < temp[8])
temp[5] <<= 1; swap(temp[2], temp[8]);
temp[2] <<= 2; if (temp[5] < temp[8])
temp[2] += temp[5] + temp[8]; swap(temp[5], temp[8]);
temp[5] <<= 1;
temp[2] <<= 2;
temp[2] += temp[5] + temp[8];
blue = ((int(temp[2]) * 160) >> 17) + 4; blue = ((int(temp[2]) * 160) >> 17) + 4;
if (blue > 31) blue = 31; if (blue > 31)
blue = 31;
if (temp[1] < temp[4]) swap(temp[1], temp[4]); if (temp[1] < temp[4])
if (temp[1] < temp[7]) swap(temp[1], temp[7]); swap(temp[1], temp[4]);
if (temp[4] < temp[7]) swap(temp[4], temp[7]); if (temp[1] < temp[7])
temp[4] <<= 1; swap(temp[1], temp[7]);
temp[1] <<= 2; if (temp[4] < temp[7])
temp[1] += temp[4] + temp[7]; swap(temp[4], temp[7]);
temp[4] <<= 1;
temp[1] <<= 2;
temp[1] += temp[4] + temp[7];
green = ((int(temp[1]) * 160) >> 17) + 4; green = ((int(temp[1]) * 160) >> 17) + 4;
if (green > 31) green = 31; if (green > 31)
green = 31;
pix = red << systemRedShift; pix = red << systemRedShift;
pix += green << systemGreenShift; pix += green << systemGreenShift;
pix += blue << systemBlueShift; pix += blue << systemBlueShift;
*buf++ = pix; *buf++ = pix;
} }
} }
void gbafilter_pal32(u32 * buf, int count) void gbafilter_pal32(u32* buf, int count)
{ {
short temp[3 * 3], s; short temp[3 * 3], s;
unsigned pix; unsigned pix;
u8 red, green, blue; u8 red, green, blue;
while (count--) while (count--) {
{ pix = *buf;
pix = *buf;
s = curve[(pix >> systemGreenShift) & 0x1f]; s = curve[(pix >> systemGreenShift) & 0x1f];
temp[3] = s * influence[3]; temp[3] = s * influence[3];
temp[4] = s * influence[4]; temp[4] = s * influence[4];
temp[5] = s * influence[5]; temp[5] = s * influence[5];
s = curve[(pix >> systemRedShift) & 0x1f]; s = curve[(pix >> systemRedShift) & 0x1f];
temp[0] = s * influence[0]; temp[0] = s * influence[0];
temp[1] = s * influence[1]; temp[1] = s * influence[1];
temp[2] = s * influence[2]; temp[2] = s * influence[2];
s = curve[(pix >> systemBlueShift) & 0x1f]; s = curve[(pix >> systemBlueShift) & 0x1f];
temp[6] = s * influence[6]; temp[6] = s * influence[6];
temp[7] = s * influence[7]; temp[7] = s * influence[7];
temp[8] = s * influence[8]; temp[8] = s * influence[8];
if (temp[0] < temp[3]) swap(temp[0], temp[3]); if (temp[0] < temp[3])
if (temp[0] < temp[6]) swap(temp[0], temp[6]); swap(temp[0], temp[3]);
if (temp[3] < temp[6]) swap(temp[3], temp[6]); if (temp[0] < temp[6])
temp[3] <<= 1; swap(temp[0], temp[6]);
temp[0] <<= 2; if (temp[3] < temp[6])
temp[0] += temp[3] + temp[6]; swap(temp[3], temp[6]);
temp[3] <<= 1;
temp[0] <<= 2;
temp[0] += temp[3] + temp[6];
//red = ((int(temp[0]) * 160) >> 17) + 4; //red = ((int(temp[0]) * 160) >> 17) + 4;
red = ((int(temp[0]) * 160) >> 14) + 32; red = ((int(temp[0]) * 160) >> 14) + 32;
if (temp[2] < temp[5]) swap(temp[2], temp[5]); if (temp[2] < temp[5])
if (temp[2] < temp[8]) swap(temp[2], temp[8]); swap(temp[2], temp[5]);
if (temp[5] < temp[8]) swap(temp[5], temp[8]); if (temp[2] < temp[8])
temp[5] <<= 1; swap(temp[2], temp[8]);
temp[2] <<= 2; if (temp[5] < temp[8])
temp[2] += temp[5] + temp[8]; swap(temp[5], temp[8]);
temp[5] <<= 1;
temp[2] <<= 2;
temp[2] += temp[5] + temp[8];
//blue = ((int(temp[2]) * 160) >> 17) + 4; //blue = ((int(temp[2]) * 160) >> 17) + 4;
blue = ((int(temp[2]) * 160) >> 14) + 32; blue = ((int(temp[2]) * 160) >> 14) + 32;
if (temp[1] < temp[4]) swap(temp[1], temp[4]); if (temp[1] < temp[4])
if (temp[1] < temp[7]) swap(temp[1], temp[7]); swap(temp[1], temp[4]);
if (temp[4] < temp[7]) swap(temp[4], temp[7]); if (temp[1] < temp[7])
temp[4] <<= 1; swap(temp[1], temp[7]);
temp[1] <<= 2; if (temp[4] < temp[7])
temp[1] += temp[4] + temp[7]; swap(temp[4], temp[7]);
temp[4] <<= 1;
temp[1] <<= 2;
temp[1] += temp[4] + temp[7];
//green = ((int(temp[1]) * 160) >> 17) + 4; //green = ((int(temp[1]) * 160) >> 17) + 4;
green = ((int(temp[1]) * 160) >> 14) + 32; green = ((int(temp[1]) * 160) >> 14) + 32;
//pix = red << redshift; //pix = red << redshift;
//pix += green << greenshift; //pix += green << greenshift;
//pix += blue << blueshift; //pix += blue << blueshift;
pix = red << (systemRedShift - 3); pix = red << (systemRedShift - 3);
pix += green << (systemGreenShift - 3); pix += green << (systemGreenShift - 3);
pix += blue << (systemBlueShift - 3); pix += blue << (systemBlueShift - 3);
*buf++ = pix; *buf++ = pix;
} }
} }
// for palette mode to work with the three spoony filters in 32bpp depth // for palette mode to work with the three spoony filters in 32bpp depth
void gbafilter_pad(u8 * buf, int count) void gbafilter_pad(u8* buf, int count)
{ {
union union {
{ struct
struct {
{ u8 r;
u8 r; u8 g;
u8 g; u8 b;
u8 b; u8 a;
u8 a; } part;
} part; unsigned whole;
unsigned whole; } mask;
}
mask;
mask.whole = 0x1f << systemRedShift; mask.whole = 0x1f << systemRedShift;
mask.whole += 0x1f << systemGreenShift; mask.whole += 0x1f << systemGreenShift;
mask.whole += 0x1f << systemBlueShift; mask.whole += 0x1f << systemBlueShift;
switch (systemColorDepth) switch (systemColorDepth) {
{ case 24:
case 24: while (count--) {
while (count--) *buf++ &= mask.part.r;
{ *buf++ &= mask.part.g;
*buf++ &= mask.part.r; *buf++ &= mask.part.b;
*buf++ &= mask.part.g; }
*buf++ &= mask.part.b; break;
} case 32:
break; while (count--) {
case 32: *((u32*)buf) &= mask.whole;
while (count--) buf += 4;
{ }
*((u32*)buf) &= mask.whole; }
buf += 4;
}
}
} }
/* /*

View File

@ -1,5 +1,5 @@
#include "../System.h" #include "../System.h"
void gbafilter_pal(u16 *buf, int count); void gbafilter_pal(u16* buf, int count);
void gbafilter_pal32(u32 *buf, int count); void gbafilter_pal32(u32* buf, int count);
void gbafilter_pad(u8 *buf, int count); void gbafilter_pad(u8* buf, int count);

File diff suppressed because it is too large Load Diff

View File

@ -4,39 +4,39 @@
#include "../common/Types.h" #include "../common/Types.h"
#include "GBA.h" #include "GBA.h"
#define BitSet(array, bit) ((u8 *)(array))[(bit) >> 3] |= (1 << ((bit)&7)) #define BitSet(array, bit) ((u8*)(array))[(bit) >> 3] |= (1 << ((bit)&7))
#define BitClear(array, bit) ((u8 *)(array))[(bit) >> 3] &= ~(1 << ((bit)&7)) #define BitClear(array, bit) ((u8*)(array))[(bit) >> 3] &= ~(1 << ((bit)&7))
#define BitGet(array, bit) ((u8)((array)[(bit) >> 3]) & (u8)(1 << ((bit)&7))) #define BitGet(array, bit) ((u8)((array)[(bit) >> 3]) & (u8)(1 << ((bit)&7)))
#define BreakSet(array, addr, flag) \ #define BreakSet(array, addr, flag) \
((u8 *)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf)) ((u8*)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf))
#define BreakClear(array, addr, flag) \ #define BreakClear(array, addr, flag) \
((u8 *)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf)) ((u8*)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf))
// check // check
#define BreakThumbCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x80 : 0x8) #define BreakThumbCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x80 : 0x8)
#define BreakARMCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x40 : 0x4) #define BreakARMCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x40 : 0x4)
#define BreakReadCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x20 : 0x2) #define BreakReadCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x20 : 0x2)
#define BreakWriteCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x10 : 0x1) #define BreakWriteCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x10 : 0x1)
#define BreakCheck(array, addr, flag) \ #define BreakCheck(array, addr, flag) \
((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf)) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf))
extern bool debugger; extern bool debugger;
extern bool dexp_eval(char *, u32 *); extern bool dexp_eval(char*, u32*);
extern void dexp_setVar(char *, u32); extern void dexp_setVar(char*, u32);
extern void dexp_listVars(); extern void dexp_listVars();
extern void dexp_saveVars(char *); extern void dexp_saveVars(char*);
extern void dexp_loadVars(char *); extern void dexp_loadVars(char*);
void debuggerOutput(const char *s, u32 addr); void debuggerOutput(const char* s, u32 addr);
bool debuggerBreakOnExecution(u32 address, u8 state); bool debuggerBreakOnExecution(u32 address, u8 state);
bool debuggerBreakOnWrite(u32 address, u32 value, int size); bool debuggerBreakOnWrite(u32 address, u32 value, int size);
@ -44,25 +44,25 @@ void debuggerBreakOnWrite(u32 address, u32 oldvalue, u32 value, int size, int t)
bool debuggerBreakOnRead(u32 address, int size); bool debuggerBreakOnRead(u32 address, int size);
struct regBreak { struct regBreak {
// u8 regNum; /No longer needed // u8 regNum; /No longer needed
// bit 0 = equal // bit 0 = equal
// bit 1 = greater // bit 1 = greater
// bit 2 = smaller // bit 2 = smaller
// bit 3 = signed // bit 3 = signed
u8 flags; u8 flags;
u32 intVal; u32 intVal;
struct regBreak *next; struct regBreak* next;
}; };
extern u8 lowRegBreakCounter[4]; //(r0-r3) extern u8 lowRegBreakCounter[4]; //(r0-r3)
extern u8 medRegBreakCounter[4]; //(r4-r7) extern u8 medRegBreakCounter[4]; //(r4-r7)
extern u8 highRegBreakCounter[4]; //(r8-r11) extern u8 highRegBreakCounter[4]; //(r8-r11)
extern u8 statusRegBreakCounter[4]; //(r12-r15) extern u8 statusRegBreakCounter[4]; //(r12-r15)
extern bool enableRegBreak; extern bool enableRegBreak;
extern regBreak *breakRegList[16]; extern regBreak* breakRegList[16];
extern void breakReg_check(int i); extern void breakReg_check(int i);
struct regBreak *getFromBreakRegList(u8 regnum, int location); struct regBreak* getFromBreakRegList(u8 regnum, int location);
void clearBreakRegList(); void clearBreakRegList();
void clearParticularRegListBreaks(int reg); void clearParticularRegListBreaks(int reg);
@ -73,7 +73,7 @@ void printBreakRegList(bool verbose);
void remoteStubMain(); void remoteStubMain();
void remoteStubSignal(int sig, int number); void remoteStubSignal(int sig, int number);
void remoteOutput(const char *s, u32 addr); void remoteOutput(const char* s, u32 addr);
void remoteSetProtocol(int p); void remoteSetProtocol(int p);
void remoteSetPort(int port); void remoteSetPort(int port);