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 "../Util.h"
#include "../common/Types.h"
#include "gbGlobals.h"
#include "gbSGB.h"
u8 gbInvertTab[256] = {
uint8_t gbInvertTab[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
@ -40,16 +39,16 @@ u8 gbInvertTab[256] = {
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
u16 gbLineMix[160];
u16 gbWindowColor[160];
uint16_t gbLineMix[160];
uint16_t gbWindowColor[160];
extern int inUseRegister_WY;
extern int layerSettings;
void gbRenderLine()
{
memset(gbLineMix, 0, sizeof(gbLineMix));
u8* bank0;
u8* bank1;
uint8_t* bank0;
uint8_t* bank1;
if (gbCgbMode) {
bank0 = &gbVram[0x0000];
bank1 = &gbVram[0x2000];
@ -91,11 +90,11 @@ void gbRenderLine()
int tile_map_address = tile_map_line_y + tx;
u8 attrs = 0;
uint8_t attrs = 0;
if (bank1 != NULL)
attrs = bank1[tile_map_address];
u8 tile = bank0[tile_map_address];
uint8_t tile = bank0[tile_map_address];
tile_map_address++;
@ -108,8 +107,8 @@ void gbRenderLine()
if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while (x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
uint8_t tile_a = 0;
uint8_t tile_b = 0;
if (attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
@ -129,7 +128,7 @@ void gbRenderLine()
}
while (bx > 0) {
u8 c = (tile_a & bx) ? 1 : 0;
uint8_t c = (tile_a & bx) ? 1 : 0;
c += ((tile_b & bx) ? 2 : 0);
gbLineBuffer[x] = c; // mark the gbLineBuffer color
@ -204,7 +203,7 @@ void gbRenderLine()
// (this fixes white flashes on Last Bible II)
// Also added the gbColorOption (fixes Dracula Densetsu II color problems)
for (int i = 0; i < 160; i++) {
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
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;
gbLineMix[i] = color;
@ -279,7 +278,7 @@ void gbRenderLine()
x = wx;
tile = bank0[tile_map_address];
u8 attrs = 0;
uint8_t attrs = 0;
if (bank1)
attrs = bank1[tile_map_address];
tile_map_address++;
@ -298,8 +297,8 @@ void gbRenderLine()
gbLineMix[i] = gbWindowColor[i];
while (x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
uint8_t tile_a = 0;
uint8_t tile_b = 0;
if (attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
@ -319,7 +318,7 @@ void gbRenderLine()
}
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);
if (x >= 0) {
@ -386,7 +385,7 @@ void gbRenderLine()
gbWindowLine = 0;
}
} else {
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF;
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,
int size, int spriteNumber)
{
u8* bank0;
u8* bank1;
uint8_t* bank0;
uint8_t* bank1;
if (gbCgbMode) {
bank0 = &gbVram[0x0000];
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;
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 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++) {
u8 mask = 1 << (7 - xx);
u8 c = 0;
uint8_t mask = 1 << (7 - xx);
uint8_t c = 0;
if ((a & mask))
c++;
if ((b & mask))
@ -459,7 +458,7 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
if (xxx < 0 || xxx > 159)
continue;
u16 color = gbLineBuffer[xxx];
uint16_t color = gbLineBuffer[xxx];
// Fixes OAM-BG priority
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"
#define readWord(addr) \
((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))
#define readWord(addr) \
((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))
#define readHalfWord(addr) \
((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \
((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8))
#define readHalfWord(addr) \
((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + ((&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]
struct ConditionalBreakNode {
char *address;
char *value;
u8 cond_flags;
u8 exp_type_flags;
struct ConditionalBreakNode *next;
char* address;
char* value;
u8 cond_flags;
u8 exp_type_flags;
struct ConditionalBreakNode* next;
};
struct ConditionalBreak {
u32 break_address;
u8 type_flags;
struct ConditionalBreakNode *firstCond;
struct ConditionalBreak *next;
u32 break_address;
u8 type_flags;
struct ConditionalBreakNode* firstCond;
struct ConditionalBreak* next;
};
extern struct ConditionalBreak *conditionals[16];
extern struct ConditionalBreak* conditionals[16];
// conditional break manipulators
// case '*': flag = 0xf; break;
@ -40,7 +36,7 @@ extern struct ConditionalBreak *conditionals[16];
// case 'r': flag = 0x2; break; // mem read
// case 'w': flag = 0x1; break; // mem write
// 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 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);
// 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(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 doBreak(struct ConditionalBreak *toTest);
bool doBreak(struct ConditionalBreak* toTest);
// printing the structure(AKA list Breaks)
// void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress);

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -4,24 +4,24 @@
#include "../common/ConfigManager.h"
struct CheatsData {
int code;
int size;
int status;
bool enabled;
u32 rawaddress;
u32 address;
u32 value;
u32 oldValue;
char codestring[20];
char desc[32];
int code;
int size;
int status;
bool enabled;
u32 rawaddress;
u32 address;
u32 value;
u32 oldValue;
char codestring[20];
char desc[32];
};
void cheatsAdd(const char *codeStr, const char *desc, u32 rawaddress, u32 address, u32 value,
int code, int size);
void cheatsAddCheatCode(const char *code, const char *desc);
void cheatsAddGSACode(const char *code, const char *desc, bool v3);
void cheatsAddCBACode(const char *code, const char *desc);
bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
void cheatsAdd(const char* codeStr, const char* desc, u32 rawaddress, u32 address, u32 value,
int code, int size);
void cheatsAddCheatCode(const char* code, const char* desc);
void cheatsAddGSACode(const char* code, const char* desc, bool v3);
void cheatsAddCBACode(const char* code, const char* desc);
bool cheatsImportGSACodeFile(const char* name, int game, bool v3);
void cheatsDelete(int number, bool restore);
void cheatsDeleteAll(bool restore);
void cheatsEnable(int number);
@ -30,8 +30,8 @@ void cheatsDisable(int number);
void cheatsSaveGame(gzFile file);
void cheatsReadGame(gzFile file, int version);
void cheatsReadGameSkip(gzFile file, int version);
void cheatsSaveCheatList(const char *file);
bool cheatsLoadCheatList(const char *file);
void cheatsSaveCheatList(const char* file);
bool cheatsLoadCheatList(const char* file);
#endif
void cheatsWriteMemory(u32 address, u32 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 "../Util.h"
#include "GBA.h"
#include <memory.h>
#include <string.h>
extern int cpuDmaCount;
@ -14,7 +14,7 @@ int eepromAddress = 0;
#ifdef __LIBRETRO__
// Workaround for broken-by-design GBA save semantics
extern u8 libretro_save_buf[0x20000 + 0x2000];
u8 *eepromData = libretro_save_buf + 0x20000;
u8* eepromData = libretro_save_buf + 0x20000;
#else
u8 eepromData[0x2000];
#endif
@ -24,198 +24,195 @@ bool eepromInUse = false;
int eepromSize = 512;
variable_desc eepromSaveData[] = {
{ &eepromMode, sizeof(int) },
{ &eepromByte, sizeof(int) },
{ &eepromBits , sizeof(int) },
{ &eepromAddress , sizeof(int) },
{ &eepromInUse, sizeof(bool) },
{ &eepromData[0], 512 },
{ &eepromBuffer[0], 16 },
{ NULL, 0 }
{ &eepromMode, sizeof(int) },
{ &eepromByte, sizeof(int) },
{ &eepromBits, sizeof(int) },
{ &eepromAddress, sizeof(int) },
{ &eepromInUse, sizeof(bool) },
{ &eepromData[0], 512 },
{ &eepromBuffer[0], 16 },
{ NULL, 0 }
};
void eepromInit()
{
#ifdef __LIBRETRO__
memset(eepromData, 255, 0x2000);
memset(eepromData, 255, 0x2000);
#else
memset(eepromData, 255, sizeof(eepromData));
memset(eepromData, 255, sizeof(eepromData));
#endif
}
void eepromReset()
{
eepromMode = EEPROM_IDLE;
eepromByte = 0;
eepromBits = 0;
eepromAddress = 0;
eepromInUse = false;
eepromSize = 512;
eepromMode = EEPROM_IDLE;
eepromByte = 0;
eepromBits = 0;
eepromAddress = 0;
eepromInUse = false;
eepromSize = 512;
}
#ifdef __LIBRETRO__
void eepromSaveGame(uint8_t *& data)
void eepromSaveGame(uint8_t*& data)
{
utilWriteDataMem(data, eepromSaveData);
utilWriteIntMem(data, eepromSize);
utilWriteMem(data, eepromData, 0x2000);
utilWriteDataMem(data, eepromSaveData);
utilWriteIntMem(data, eepromSize);
utilWriteMem(data, eepromData, 0x2000);
}
void eepromReadGame(const uint8_t *& data, int version)
void eepromReadGame(const uint8_t*& data, int version)
{
utilReadDataMem(data, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadIntMem(data);
utilReadMem(eepromData, data, 0x2000);
} else {
// prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
utilReadDataMem(data, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadIntMem(data);
utilReadMem(eepromData, data, 0x2000);
} else {
// prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
}
#else
void eepromSaveGame(gzFile gzFile)
{
utilWriteData(gzFile, eepromSaveData);
utilWriteInt(gzFile, eepromSize);
utilGzWrite(gzFile, eepromData, 0x2000);
utilWriteData(gzFile, eepromSaveData);
utilWriteInt(gzFile, eepromSize);
utilGzWrite(gzFile, eepromData, 0x2000);
}
void eepromReadGame(gzFile gzFile, int version)
{
utilReadData(gzFile, eepromSaveData);
if(version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadInt(gzFile);
utilGzRead(gzFile, eepromData, 0x2000);
} else {
// prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
utilReadData(gzFile, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) {
eepromSize = utilReadInt(gzFile);
utilGzRead(gzFile, eepromData, 0x2000);
} else {
// prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
}
void eepromReadGameSkip(gzFile gzFile, int version)
{
// skip the eeprom data in a save game
utilReadDataSkip(gzFile, eepromSaveData);
if(version >= SAVE_GAME_VERSION_3) {
utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
utilGzSeek(gzFile, 0x2000, SEEK_CUR);
}
// skip the eeprom data in a save game
utilReadDataSkip(gzFile, eepromSaveData);
if (version >= SAVE_GAME_VERSION_3) {
utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
utilGzSeek(gzFile, 0x2000, SEEK_CUR);
}
}
#endif
int eepromRead(u32 /* address */)
{
switch(eepromMode) {
case EEPROM_IDLE:
case EEPROM_READADDRESS:
case EEPROM_WRITEDATA:
switch (eepromMode) {
case EEPROM_IDLE:
case EEPROM_READADDRESS:
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;
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)
{
if(cpuDmaCount == 0)
return;
int bit = value & 1;
switch(eepromMode) {
case EEPROM_IDLE:
eepromByte = 0;
eepromBits = 1;
eepromBuffer[eepromByte] = bit;
eepromMode = EEPROM_READADDRESS;
break;
case EEPROM_READADDRESS:
eepromBuffer[eepromByte] <<= 1;
eepromBuffer[eepromByte] |= bit;
eepromBits++;
if((eepromBits & 7) == 0) {
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 == 0)
return;
int bit = value & 1;
switch (eepromMode) {
case EEPROM_IDLE:
eepromByte = 0;
eepromBits = 1;
eepromBuffer[eepromByte] = bit;
eepromMode = EEPROM_READADDRESS;
break;
case EEPROM_READADDRESS:
eepromBuffer[eepromByte] <<= 1;
eepromBuffer[eepromByte] |= bit;
eepromBits++;
if ((eepromBits & 7) == 0) {
eepromByte++;
}
}
} else {
if(eepromBits == 9) {
eepromInUse = true;
eepromAddress = (eepromBuffer[0] & 0x3F);
if(!(eepromBuffer[0] & 0x40)) {
eepromBuffer[0] = bit;
eepromBits = 1;
eepromByte = 0;
eepromMode = EEPROM_WRITEDATA;
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;
}
}
} else {
eepromMode = EEPROM_READDATA;
eepromByte = 0;
eepromBits = 0;
if (eepromBits == 9) {
eepromInUse = true;
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
#ifdef __LIBRETRO__
extern void eepromSaveGame(u8 *&data);
extern void eepromReadGame(const u8 *&data, int version);
extern void eepromSaveGame(u8*& data);
extern void eepromReadGame(const u8*& data, int version);
#else
extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile _gzFile, int version);
@ -14,7 +14,7 @@ extern void eepromWrite(u32 address, u8 value);
extern void eepromInit();
extern void eepromReset();
#ifdef __LIBRETRO__
extern u8 *eepromData;
extern u8* eepromData;
#else
extern u8 eepromData[0x2000];
#endif

View File

@ -1,26 +1,26 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "Flash.h"
#include "../Util.h"
#include "GBA.h"
#include "Globals.h"
#include "Flash.h"
#include "Sram.h"
#include "../Util.h"
#include <memory.h>
#include <stdio.h>
#include <string.h>
#define FLASH_READ_ARRAY 0
#define FLASH_CMD_1 1
#define FLASH_CMD_2 2
#define FLASH_AUTOSELECT 3
#define FLASH_CMD_3 4
#define FLASH_CMD_4 5
#define FLASH_CMD_5 6
#define FLASH_ERASE_COMPLETE 7
#define FLASH_PROGRAM 8
#define FLASH_SETBANK 9
#define FLASH_READ_ARRAY 0
#define FLASH_CMD_1 1
#define FLASH_CMD_2 2
#define FLASH_AUTOSELECT 3
#define FLASH_CMD_3 4
#define FLASH_CMD_4 5
#define FLASH_CMD_5 6
#define FLASH_ERASE_COMPLETE 7
#define FLASH_PROGRAM 8
#define FLASH_SETBANK 9
#ifdef __LIBRETRO__
extern uint8_t libretro_save_buf[0x20000 + 0x2000];
uint8_t *flashSaveMemory = libretro_save_buf;
uint8_t* flashSaveMemory = libretro_save_buf;
#else
uint8_t flashSaveMemory[FLASH_128K_SZ];
#endif
@ -33,252 +33,251 @@ int flashManufacturerID = 0x32;
int flashBank = 0;
static variable_desc flashSaveData[] = {
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSaveMemory[0], 0x10000 },
{ NULL, 0 }
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSaveMemory[0], 0x10000 },
{ NULL, 0 }
};
static variable_desc flashSaveData2[] = {
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 },
{ NULL, 0 }
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 },
{ NULL, 0 }
};
static variable_desc flashSaveData3[] = {
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) },
{ &flashBank, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 },
{ NULL, 0 }
{ &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) },
{ &flashBank, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 },
{ NULL, 0 }
};
void flashInit()
{
#ifdef __LIBRETRO__
memset(flashSaveMemory, 0xff, 0x20000);
memset(flashSaveMemory, 0xff, 0x20000);
#else
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
#endif
}
void flashReset()
{
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
flashBank = 0;
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
flashBank = 0;
}
#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
void flashSaveGame(gzFile gzFile)
{
utilWriteData(gzFile, flashSaveData3);
utilWriteData(gzFile, flashSaveData3);
}
void flashReadGame(gzFile gzFile, int version)
{
if(version < SAVE_GAME_VERSION_5)
utilReadData(gzFile, flashSaveData);
else if(version < SAVE_GAME_VERSION_7) {
utilReadData(gzFile, flashSaveData2);
flashBank = 0;
flashSetSize(flashSize);
} else {
utilReadData(gzFile, flashSaveData3);
}
if (version < SAVE_GAME_VERSION_5)
utilReadData(gzFile, flashSaveData);
else if (version < SAVE_GAME_VERSION_7) {
utilReadData(gzFile, flashSaveData2);
flashBank = 0;
flashSetSize(flashSize);
} else {
utilReadData(gzFile, flashSaveData3);
}
}
void flashReadGameSkip(gzFile gzFile, int version)
{
// skip the flash data in a save game
if(version < SAVE_GAME_VERSION_5)
utilReadDataSkip(gzFile, flashSaveData);
else if(version < SAVE_GAME_VERSION_7) {
utilReadDataSkip(gzFile, flashSaveData2);
} else {
utilReadDataSkip(gzFile, flashSaveData3);
}
// skip the flash data in a save game
if (version < SAVE_GAME_VERSION_5)
utilReadDataSkip(gzFile, flashSaveData);
else if (version < SAVE_GAME_VERSION_7) {
utilReadDataSkip(gzFile, flashSaveData2);
} else {
utilReadDataSkip(gzFile, flashSaveData3);
}
}
#endif
void flashSetSize(int size)
{
// log("Setting flash size to %d\n", size);
if(size == 0x10000) {
flashDeviceID = 0x1b;
flashManufacturerID = 0x32;
} else {
flashDeviceID = 0x13; //0x09;
flashManufacturerID = 0x62; //0xc2;
}
// Added to make 64k saves compatible with 128k ones
// (allow wrongfuly set 64k saves to work for Pokemon games)
if ((size == 0x20000) && (flashSize == 0x10000))
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
flashSize = size;
// log("Setting flash size to %d\n", size);
if (size == 0x10000) {
flashDeviceID = 0x1b;
flashManufacturerID = 0x32;
} else {
flashDeviceID = 0x13; //0x09;
flashManufacturerID = 0x62; //0xc2;
}
// Added to make 64k saves compatible with 128k ones
// (allow wrongfuly set 64k saves to work for Pokemon games)
if ((size == 0x20000) && (flashSize == 0x10000))
memcpy((u8*)(flashSaveMemory + 0x10000), (u8*)(flashSaveMemory), 0x10000);
flashSize = size;
}
u8 flashRead(u32 address)
{
// log("Reading %08x from %08x\n", address, reg[15].I);
// log("Current read state is %d\n", flashReadState);
address &= 0xFFFF;
// log("Reading %08x from %08x\n", address, reg[15].I);
// log("Current read state is %d\n", flashReadState);
address &= 0xFFFF;
switch(flashReadState) {
case FLASH_READ_ARRAY:
return flashSaveMemory[(flashBank << 16) + address];
case FLASH_AUTOSELECT:
switch(address & 0xFF) {
case 0:
// manufacturer ID
return flashManufacturerID;
case 1:
// device ID
return flashDeviceID;
}
break;
case FLASH_ERASE_COMPLETE:
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
return 0xFF;
};
return 0;
switch (flashReadState) {
case FLASH_READ_ARRAY:
return flashSaveMemory[(flashBank << 16) + address];
case FLASH_AUTOSELECT:
switch (address & 0xFF) {
case 0:
// manufacturer ID
return flashManufacturerID;
case 1:
// device ID
return flashDeviceID;
}
break;
case FLASH_ERASE_COMPLETE:
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
return 0xFF;
};
return 0;
}
void flashSaveDecide(u32 address, u8 byte)
{
if (saveType == 1)
return;
if (saveType == 1)
return;
// log("Deciding save type %08x\n", address);
if(address == 0x0e005555) {
saveType = 3;
cpuSaveGameFunc = flashWrite;
} else {
saveType = 2;
cpuSaveGameFunc = sramWrite;
}
// log("Deciding save type %08x\n", address);
if (address == 0x0e005555) {
saveType = 3;
cpuSaveGameFunc = flashWrite;
} else {
saveType = 2;
cpuSaveGameFunc = sramWrite;
}
(*cpuSaveGameFunc)(address, byte);
(*cpuSaveGameFunc)(address, byte);
}
void flashDelayedWrite(u32 address, u8 byte)
{
saveType = 3;
cpuSaveGameFunc = flashWrite;
flashWrite(address, byte);
saveType = 3;
cpuSaveGameFunc = flashWrite;
flashWrite(address, byte);
}
void flashWrite(u32 address, u8 byte)
{
// log("Writing %02x at %08x\n", byte, address);
// log("Current state is %d\n", flashState);
address &= 0xFFFF;
switch(flashState) {
case FLASH_READ_ARRAY:
if(address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1;
break;
case FLASH_CMD_1:
if(address == 0x2AAA && byte == 0x55)
flashState = FLASH_CMD_2;
else
flashState = FLASH_READ_ARRAY;
break;
case FLASH_CMD_2:
if(address == 0x5555) {
if(byte == 0x90) {
flashState = FLASH_AUTOSELECT;
flashReadState = FLASH_AUTOSELECT;
} else if(byte == 0x80) {
flashState = FLASH_CMD_3;
} else if(byte == 0xF0) {
// log("Writing %02x at %08x\n", byte, address);
// log("Current state is %d\n", flashState);
address &= 0xFFFF;
switch (flashState) {
case FLASH_READ_ARRAY:
if (address == 0x5555 && byte == 0xAA)
flashState = FLASH_CMD_1;
break;
case FLASH_CMD_1:
if (address == 0x2AAA && byte == 0x55)
flashState = FLASH_CMD_2;
else
flashState = FLASH_READ_ARRAY;
break;
case FLASH_CMD_2:
if (address == 0x5555) {
if (byte == 0x90) {
flashState = FLASH_AUTOSELECT;
flashReadState = FLASH_AUTOSELECT;
} else if (byte == 0x80) {
flashState = FLASH_CMD_3;
} 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;
flashReadState = FLASH_READ_ARRAY;
} else if(byte == 0xA0) {
flashState = FLASH_PROGRAM;
} else if(byte == 0xB0 && flashSize == 0x20000) {
flashState = FLASH_SETBANK;
} else {
break;
case FLASH_SETBANK:
if (address == 0) {
flashBank = (byte & 1);
}
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
}
} else {
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
}
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
#ifdef __LIBRETRO__
extern void flashSaveGame(u8 *&data);
extern void flashReadGame(const u8 *&data, int);
extern void flashSaveGame(u8*& data);
extern void flashReadGame(const u8*& data, int);
#else
extern void flashSaveGame(gzFile _gzFile);
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 flashDelayedWrite(u32 address, u8 byte);
#ifdef __LIBRETRO__
extern uint8_t *flashSaveMemory;
extern uint8_t* flashSaveMemory;
#else
extern u8 flashSaveMemory[FLASH_128K_SZ];
#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
typedef struct {
u8 *address;
u32 mask;
u8* address;
u32 mask;
#ifdef BKPT_SUPPORT
u8 *breakPoints;
u8 *searchMatch;
u8 *trace;
u32 size;
u8* breakPoints;
u8* searchMatch;
u8* trace;
u32 size;
#endif
} memoryMap;
typedef union {
struct {
struct {
#ifdef WORDS_BIGENDIAN
u8 B3;
u8 B2;
u8 B1;
u8 B0;
u8 B3;
u8 B2;
u8 B1;
u8 B0;
#else
u8 B0;
u8 B1;
u8 B2;
u8 B3;
u8 B0;
u8 B1;
u8 B2;
u8 B3;
#endif
} B;
struct {
} B;
struct {
#ifdef WORDS_BIGENDIAN
u16 W1;
u16 W0;
u16 W1;
u16 W0;
#else
u16 W0;
u16 W1;
u16 W0;
u16 W1;
#endif
} W;
} W;
#ifdef WORDS_BIGENDIAN
volatile u32 I;
volatile u32 I;
#else
u32 I;
u32 I;
#endif
} reg_pair;
@ -78,49 +78,49 @@ extern char oldbuffer[10];
extern bool debugger;
#endif
extern bool CPUReadGSASnapshot(const char *);
extern bool CPUReadGSASPSnapshot(const char *);
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
extern bool CPUWriteBatteryFile(const char *);
extern bool CPUReadBatteryFile(const char *);
extern bool CPUExportEepromFile(const char *);
extern bool CPUImportEepromFile(const char *);
extern bool CPUWritePNGFile(const char *);
extern bool CPUWriteBMPFile(const char *);
extern bool CPUReadGSASnapshot(const char*);
extern bool CPUReadGSASPSnapshot(const char*);
extern bool CPUWriteGSASnapshot(const char*, const char*, const char*, const char*);
extern bool CPUWriteBatteryFile(const char*);
extern bool CPUReadBatteryFile(const char*);
extern bool CPUExportEepromFile(const char*);
extern bool CPUImportEepromFile(const char*);
extern bool CPUWritePNGFile(const char*);
extern bool CPUWriteBMPFile(const char*);
extern void CPUCleanUp();
extern void CPUUpdateRender();
extern void CPUUpdateRenderBuffers(bool);
extern bool CPUReadMemState(char *, int);
extern bool CPUWriteMemState(char *, int);
extern bool CPUReadMemState(char*, int);
extern bool CPUWriteMemState(char*, int);
#ifdef __LIBRETRO__
extern bool CPUReadState(const u8 *, unsigned);
extern unsigned int CPUWriteState(u8 *data, unsigned int size);
extern bool CPUReadState(const u8*, unsigned);
extern unsigned int CPUWriteState(u8* data, unsigned int size);
#else
extern bool CPUReadState(const char *);
extern bool CPUWriteState(const char *);
extern bool CPUReadState(const char*);
extern bool CPUWriteState(const char*);
#endif
extern int CPULoadRom(const char *);
extern int CPULoadRomData(const char *data, int size);
extern int CPULoadRom(const char*);
extern int CPULoadRomData(const char* data, int size);
extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16);
extern void applyTimer();
extern void CPUInit(const char *, bool);
extern void CPUInit(const char*, bool);
void SetSaveType(int st);
extern void CPUReset();
extern void CPULoop(int);
extern void CPUCheckDMA(int, int);
extern bool CPUIsGBAImage(const char *);
extern bool CPUIsZipFile(const char *);
extern bool CPUIsGBAImage(const char*);
extern bool CPUIsZipFile(const char*);
#ifdef PROFILING
#include "prof/prof.h"
extern void cpuProfil(profile_segment *seg);
extern void cpuProfil(profile_segment* seg);
extern void cpuEnableProfiling(int hz);
#endif
const char *GetLoadDotCodeFile();
const char *GetSaveDotCodeFile();
void SetLoadDotCodeFile(const char *szFile);
void SetSaveDotCodeFile(const char *szFile);
const char* GetLoadDotCodeFile();
const char* GetSaveDotCodeFile();
void SetLoadDotCodeFile(const char* szFile);
void SetSaveDotCodeFile(const char* szFile);
extern struct EmulatedSystem GBASystem;

View File

@ -1,8 +1,9 @@
#include "../System.h"
int coeff[32] = {
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};
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
};
u32 line0[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
*/
enum LinkMode {
LINK_DISCONNECTED,
LINK_CABLE_IPC,
LINK_CABLE_SOCKET,
LINK_RFU_IPC,
LINK_RFU_SOCKET,
LINK_GAMECUBE_DOLPHIN,
LINK_GAMEBOY_IPC,
LINK_GAMEBOY_SOCKET
LINK_DISCONNECTED,
LINK_CABLE_IPC,
LINK_CABLE_SOCKET,
LINK_RFU_IPC,
LINK_RFU_SOCKET,
LINK_GAMECUBE_DOLPHIN,
LINK_GAMEBOY_IPC,
LINK_GAMEBOY_SOCKET
};
/**
* 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
@ -34,7 +37,7 @@ extern ConnectionState InitLink(LinkMode mode);
* @param message Information message
* @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
@ -63,7 +66,7 @@ extern void EnableSpeedHacks(bool enable);
*
* @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
@ -73,7 +76,7 @@ extern bool SetLinkServerHost(const char *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
@ -131,20 +134,20 @@ extern void CleanLocalLink();
* @return completed filename
*/
extern const char *MakeInstanceFilename(const char *Input);
extern const char* MakeInstanceFilename(const char* Input);
// register definitions
#define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode
#define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode
#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_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
#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_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
#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_JOYCNT 0x140
#define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher
#define COMM_JOY_RECV_H 0x152
@ -176,16 +179,16 @@ extern const char *MakeInstanceFilename(const char *Input);
#define RFU_SEND 2
#define RFU_RECV 3
#define RF_RECVCMD \
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?)
#define RF_RECVCMD \
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?)
#define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?)
typedef struct {
u8 len; // data len in 32bit words
u8 gbaid; // source id
u32 time; // linktime
u32 data[255];
u8 len; // data len in 32bit words
u8 gbaid; // source id
u32 time; // linktime
u32 data[255];
} rfu_datarec;
extern u8 gbSIO_SC;
@ -199,6 +202,6 @@ extern void gbInitLinkIPC();
extern u8 gbStartLinkIPC(u8 b);
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 */

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,506 +1,501 @@
#include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h"
#include "Globals.h"
void mode0RenderLine()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
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()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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);
}
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 (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
return;
}
if(line1[x] < (color & 0xFF000000)) {
color = line1[x];
top = 0x02;
if (layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if(line2[x] < (color & 0xFF000000)) {
color = line2[x];
top = 0x04;
if (layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if(line3[x] < (color & 0xFF000000)) {
color = line3[x];
top = 0x08;
if (layerEnable & 0x0400) {
gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
}
if(lineOBJ[x] < (color & 0xFF000000)) {
color = lineOBJ[x];
top = 0x10;
if (layerEnable & 0x0800) {
gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
}
if(!(color & 0x00010000)) {
switch(effect) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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)) {
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;
u8 top2 = 0x20;
if(line0[x] < back) {
if(top != 0x01) {
if (line0[x] < back) {
back = line0[x];
top2 = 0x01;
}
}
if(line1[x] < (back & 0xFF000000)) {
if(top != 0x02) {
if (line1[x] < (back & 0xFF000000)) {
back = line1[x];
top2 = 0x02;
}
}
if(line2[x] < (back & 0xFF000000)) {
if(top != 0x04) {
if (line2[x] < (back & 0xFF000000)) {
back = line2[x];
top2 = 0x04;
}
}
if(line3[x] < (back & 0xFF000000)) {
if(top != 0x08) {
if (line3[x] < (back & 0xFF000000)) {
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]);
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) {
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;
}
lineMix[x] = color;
}
}
void mode0RenderLineAll()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
// special FX on in the window
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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)) {
if(top != 0x01) {
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)) {
if(top != 0x02) {
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)) {
if(top != 0x04) {
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)) {
if(top != 0x08) {
if ((mask & 8) && ((u8)(line3[x] >> 24) < (u8)(back >> 24))) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
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 & 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 "Globals.h"
#include "GBAGfx.h"
#include "Globals.h"
void mode1RenderLine()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
gfxLastVCOUNT = VCOUNT;
return;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
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;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode1RenderLineNoWindow()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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 (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x];
top = 0x02;
if (layerEnable & 0x0100) {
gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x];
top = 0x04;
if (layerEnable & 0x0200) {
gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
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(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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 (!(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;
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];
top2 = 0x01;
}
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) {
if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) {
back = line1[x];
top2 = 0x02;
}
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) {
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
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]);
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)) {
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;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode1RenderLineAll()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
// special FX on the window
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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)) {
if(top != 0x01) {
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)) {
if(top != 0x02) {
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)) {
if(top != 0x04) {
if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) {
if (top != 0x01) {
back = line0[x];
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;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,443 +1,437 @@
#include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h"
#include "Globals.h"
void mode2RenderLine()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
gfxLastVCOUNT = VCOUNT;
return;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
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;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode2RenderLineNoWindow()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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 (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
color = line3[x];
top = 0x08;
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((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
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);
}
if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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 (!(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;
u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) {
if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) {
back = line2[x];
top2 = 0x04;
}
}
if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(top != 0x08) {
if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) {
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]);
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)) {
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;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode2RenderLineAll()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
// special FX on the window
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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) {
if(top != 0x04) {
if ((mask & 4) && line2[x] < back) {
back = line2[x];
top2 = 0x04;
}
}
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(top != 0x08) {
if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
if ((mask & 4) && line2[x] < back) {
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;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,374 +1,368 @@
#include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h"
#include "Globals.h"
void mode3RenderLine()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
gfxLastVCOUNT = VCOUNT;
return;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
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;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode3RenderLineNoWindow()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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 (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
top = 0x10;
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);
}
if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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 (!(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;
u8 top2 = 0x20;
if(line2[x] < back) {
if(top != 0x04) {
if (line2[x] < back) {
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]);
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) {
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;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode3RenderLineAll()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x80) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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) {
if(top != 0x04) {
if ((mask & 4) && line2[x] < back) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if ((mask & 4) && line2[x] < back) {
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;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -4,368 +4,362 @@
void mode4RenderLine()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
gfxLastVCOUNT = VCOUNT;
return;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
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;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode4RenderLineNoWindow()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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 (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
top = 0x10;
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);
}
if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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 (!(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;
u8 top2 = 0x20;
if(line2[x] < back) {
if(top != 0x04) {
if (line2[x] < back) {
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]);
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) {
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;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode4RenderLineAll()
{
u16 *palette = (u16 *)paletteRAM;
u16* palette = (u16*)paletteRAM;
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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) {
if(top != 0x04) {
if ((mask & 4) && line2[x] < back) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if ((mask & 4) && line2[x] < back) {
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;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,374 +1,368 @@
#include "GBA.h"
#include "Globals.h"
#include "GBAGfx.h"
#include "Globals.h"
void mode5RenderLine()
{
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
gfxLastVCOUNT = VCOUNT;
return;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
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;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode5RenderLineNoWindow()
{
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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 (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
gfxLastVCOUNT = VCOUNT;
return;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
top = 0x10;
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);
}
if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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 (!(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;
u8 top2 = 0x20;
if(line2[x] < back) {
if(top != 0x04) {
if (line2[x] < back) {
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]);
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) {
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;
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}
void mode5RenderLineAll()
{
if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
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;
if (DISPCNT & 0x0080) {
for (int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff;
}
}
} else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
case 0:
break;
case 1:
{
if(top & BLDMOD) {
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) {
if(top != 0x04) {
if ((mask & 4) && line2[x] < back) {
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]);
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))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if ((mask & 4) && line2[x] < back) {
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;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

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

View File

@ -10,8 +10,8 @@ bool rtcIsEnabled();
void rtcReset();
#ifdef __LIBRETRO__
void rtcReadGame(const u8 *&data);
void rtcSaveGame(u8 *&data);
void rtcReadGame(const u8*& data);
void rtcSaveGame(u8*& data);
#else
void rtcReadGame(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
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
@ -70,12 +70,12 @@ void interp_rate();
// Notifies emulator that SOUND_CLOCK_TICKS clocks have passed
void psoundTickfn();
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
#ifdef __LIBRETRO__
void soundSaveGame(u8 *&);
void soundReadGame(const u8 *&in, int version);
void soundSaveGame(u8*&);
void soundReadGame(const u8*& in, int version);
#else
void soundSaveGame(gzFile);
void soundReadGame(gzFile, int version);
@ -83,6 +83,6 @@ void soundReadGame(gzFile, int version);
class Multi_Buffer;
void flush_samples(Multi_Buffer *buffer);
void flush_samples(Multi_Buffer* buffer);
#endif // SOUND_H

View File

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

View File

@ -1,80 +1,79 @@
#include <stdio.h>
#include <string.h>
#include "../System.h"
#include "../common/Port.h"
#include "GBA.h"
#include "Globals.h"
#include "../common/Port.h"
#include "../System.h"
#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) \
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 agbPrintProtect = false;
bool agbPrintWrite(u32 address, u16 value)
{
if(agbPrintEnabled) {
if(address == 0x9fe2ffe) { // protect
agbPrintProtect = (value != 0);
debuggerWriteHalfWord(address, value);
return true;
} else {
if(agbPrintProtect &&
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
debuggerWriteHalfWord(address, value);
return true;
}
if (agbPrintEnabled) {
if (address == 0x9fe2ffe) { // protect
agbPrintProtect = (value != 0);
debuggerWriteHalfWord(address, value);
return true;
} else {
if (agbPrintProtect && ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
|| (address >= 0x8fd0000 && address <= 0x8fdffff)
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) {
debuggerWriteHalfWord(address, value);
return true;
}
}
}
}
return false;
return false;
}
void agbPrintReset()
{
agbPrintProtect = false;
agbPrintProtect = false;
}
void agbPrintEnable(bool enable)
{
agbPrintEnabled = enable;
agbPrintEnabled = enable;
}
bool agbPrintIsEnabled()
{
return agbPrintEnabled;
return agbPrintEnabled;
}
void agbPrintFlush()
{
u16 get = debuggerReadHalfWord(0x9fe20fc);
u16 put = debuggerReadHalfWord(0x9fe20fe);
u16 get = debuggerReadHalfWord(0x9fe20fc);
u16 put = debuggerReadHalfWord(0x9fe20fe);
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
if(address != 0xfd0000 && address != 0x1fd0000) {
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
// get rid of the text otherwise we will continue to be called
debuggerWriteHalfWord(0x9fe20fc, put);
return;
}
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
if (address != 0xfd0000 && address != 0x1fd0000) {
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
// get rid of the text otherwise we will continue to be called
debuggerWriteHalfWord(0x9fe20fc, put);
return;
}
u8 *data = &rom[address];
u8* data = &rom[address];
while(get != put) {
char c = data[get++];
char s[2];
s[0] = c;
s[1] = 0;
while (get != put) {
char c = data[get++];
char s[2];
s[0] = c;
s[1] = 0;
if(systemVerbose & VERBOSE_AGBPRINT)
dbgOutput(s, 0);
if(c == '\n')
break;
}
debuggerWriteHalfWord(0x9fe20fc, get);
if (systemVerbose & VERBOSE_AGBPRINT)
dbgOutput(s, 0);
if (c == '\n')
break;
}
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_CODE 2
int disThumb(u32 offset, char *dest, int flags);
int disArm(u32 offset, char *dest, int flags);
int disThumb(u32 offset, char* dest, int flags);
int disArm(u32 offset, char* dest, int flags);
#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
#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_signed 0x05
@ -9,253 +11,253 @@ enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value };
#define DW_ATE_unsigned_char 0x08
struct ELFHeader {
u32 magic;
u8 clazz;
u8 data;
u8 version;
u8 pad[9];
u16 e_type;
u16 e_machine;
u32 e_version;
u32 e_entry;
u32 e_phoff;
u32 e_shoff;
u32 e_flags;
u16 e_ehsize;
u16 e_phentsize;
u16 e_phnum;
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
u32 magic;
u8 clazz;
u8 data;
u8 version;
u8 pad[9];
u16 e_type;
u16 e_machine;
u32 e_version;
u32 e_entry;
u32 e_phoff;
u32 e_shoff;
u32 e_flags;
u16 e_ehsize;
u16 e_phentsize;
u16 e_phnum;
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
};
struct ELFProgramHeader {
u32 type;
u32 offset;
u32 vaddr;
u32 paddr;
u32 filesz;
u32 memsz;
u32 flags;
u32 align;
u32 type;
u32 offset;
u32 vaddr;
u32 paddr;
u32 filesz;
u32 memsz;
u32 flags;
u32 align;
};
struct ELFSectionHeader {
u32 name;
u32 type;
u32 flags;
u32 addr;
u32 offset;
u32 size;
u32 link;
u32 info;
u32 addralign;
u32 entsize;
u32 name;
u32 type;
u32 flags;
u32 addr;
u32 offset;
u32 size;
u32 link;
u32 info;
u32 addralign;
u32 entsize;
};
struct ELFSymbol {
u32 name;
u32 value;
u32 size;
u8 info;
u8 other;
u16 shndx;
u32 name;
u32 value;
u32 size;
u8 info;
u8 other;
u16 shndx;
};
struct ELFBlock {
int length;
u8 *data;
int length;
u8* data;
};
struct ELFAttr {
u32 name;
u32 form;
union {
u32 value;
char *string;
u8 *data;
bool flag;
ELFBlock *block;
};
u32 name;
u32 form;
union {
u32 value;
char* string;
u8* data;
bool flag;
ELFBlock* block;
};
};
struct ELFAbbrev {
u32 number;
u32 tag;
bool hasChildren;
int numAttrs;
ELFAttr *attrs;
ELFAbbrev *next;
u32 number;
u32 tag;
bool hasChildren;
int numAttrs;
ELFAttr* attrs;
ELFAbbrev* next;
};
enum TypeEnum {
TYPE_base,
TYPE_pointer,
TYPE_function,
TYPE_void,
TYPE_array,
TYPE_struct,
TYPE_reference,
TYPE_enum,
TYPE_union
TYPE_base,
TYPE_pointer,
TYPE_function,
TYPE_void,
TYPE_array,
TYPE_struct,
TYPE_reference,
TYPE_enum,
TYPE_union
};
struct Type;
struct Object;
struct FunctionType {
Type *returnType;
Object *args;
Type* returnType;
Object* args;
};
struct Member {
char *name;
Type *type;
int bitSize;
int bitOffset;
int byteSize;
ELFBlock *location;
char* name;
Type* type;
int bitSize;
int bitOffset;
int byteSize;
ELFBlock* location;
};
struct Struct {
int memberCount;
Member *members;
int memberCount;
Member* members;
};
struct Array {
Type *type;
int maxBounds;
int *bounds;
Type* type;
int maxBounds;
int* bounds;
};
struct EnumMember {
char *name;
u32 value;
char* name;
u32 value;
};
struct Enum {
int count;
EnumMember *members;
int count;
EnumMember* members;
};
struct Type {
u32 offset;
TypeEnum type;
const char *name;
int encoding;
int size;
int bitSize;
union {
Type *pointer;
FunctionType *function;
Array *array;
Struct *structure;
Enum *enumeration;
};
Type *next;
u32 offset;
TypeEnum type;
const char* name;
int encoding;
int size;
int bitSize;
union {
Type* pointer;
FunctionType* function;
Array* array;
Struct* structure;
Enum* enumeration;
};
Type* next;
};
struct Object {
char *name;
int file;
int line;
bool external;
Type *type;
ELFBlock *location;
u32 startScope;
u32 endScope;
Object *next;
char* name;
int file;
int line;
bool external;
Type* type;
ELFBlock* location;
u32 startScope;
u32 endScope;
Object* next;
};
struct Function {
char *name;
u32 lowPC;
u32 highPC;
int file;
int line;
bool external;
Type *returnType;
Object *parameters;
Object *variables;
ELFBlock *frameBase;
Function *next;
char* name;
u32 lowPC;
u32 highPC;
int file;
int line;
bool external;
Type* returnType;
Object* parameters;
Object* variables;
ELFBlock* frameBase;
Function* next;
};
struct LineInfoItem {
u32 address;
char *file;
int line;
u32 address;
char* file;
int line;
};
struct LineInfo {
int fileCount;
char **files;
int number;
LineInfoItem *lines;
int fileCount;
char** files;
int number;
LineInfoItem* lines;
};
struct ARange {
u32 lowPC;
u32 highPC;
u32 lowPC;
u32 highPC;
};
struct ARanges {
u32 offset;
int count;
ARange *ranges;
u32 offset;
int count;
ARange* ranges;
};
struct CompileUnit {
u32 length;
u8 *top;
u32 offset;
ELFAbbrev **abbrevs;
ARanges *ranges;
char *name;
char *compdir;
u32 lowPC;
u32 highPC;
bool hasLineInfo;
u32 lineInfo;
LineInfo *lineInfoTable;
Function *functions;
Function *lastFunction;
Object *variables;
Type *types;
CompileUnit *next;
u32 length;
u8* top;
u32 offset;
ELFAbbrev** abbrevs;
ARanges* ranges;
char* name;
char* compdir;
u32 lowPC;
u32 highPC;
bool hasLineInfo;
u32 lineInfo;
LineInfo* lineInfoTable;
Function* functions;
Function* lastFunction;
Object* variables;
Type* types;
CompileUnit* next;
};
struct DebugInfo {
u8 *debugfile;
u8 *abbrevdata;
u8 *debugdata;
u8 *infodata;
int numRanges;
ARanges *ranges;
u8* debugfile;
u8* abbrevdata;
u8* debugdata;
u8* infodata;
int numRanges;
ARanges* ranges;
};
struct Symbol {
const char *name;
int type;
int binding;
u32 address;
u32 value;
u32 size;
const char* name;
int type;
int binding;
u32 address;
u32 value;
u32 size;
};
extern u32 elfReadLEB128(u8 *, int *);
extern s32 elfReadSignedLEB128(u8 *, int *);
extern bool elfRead(const char *, int &, FILE *f);
extern bool elfGetSymbolAddress(const char *, u32 *, u32 *, int *);
extern const char *elfGetAddressSymbol(u32);
extern const char *elfGetSymbol(int, u32 *, u32 *, int *);
extern u32 elfReadLEB128(u8*, int*);
extern s32 elfReadSignedLEB128(u8*, int*);
extern bool elfRead(const char*, int&, FILE* f);
extern bool elfGetSymbolAddress(const char*, u32*, u32*, int*);
extern const char* elfGetAddressSymbol(u32);
extern const char* elfGetSymbol(int, u32*, u32*, int*);
extern void elfCleanUp();
extern bool elfGetCurrentFunction(u32, Function **, CompileUnit **c);
extern bool elfGetObject(const char *, Function *, CompileUnit *, Object **);
extern bool elfFindLineInUnit(u32 *, CompileUnit *, int);
extern bool elfFindLineInModule(u32 *, const char *, int);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *, u32);
int elfFindLine(CompileUnit *unit, Function *func, u32 addr, const char **);
extern bool elfGetCurrentFunction(u32, Function**, CompileUnit** c);
extern bool elfGetObject(const char*, Function*, CompileUnit*, Object**);
extern bool elfFindLineInUnit(u32*, CompileUnit*, int);
extern bool elfFindLineInModule(u32*, const char*, int);
u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*);
u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*, u32);
int elfFindLine(CompileUnit* unit, Function* func, u32 addr, const char**);
#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[];
int OpenDotCodeFile(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 BIOS_EReader_ScanCard(int swi_num);

View File

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

View File

@ -1,5 +1,5 @@
#include "../System.h"
void gbafilter_pal(u16 *buf, int count);
void gbafilter_pal32(u32 *buf, int count);
void gbafilter_pad(u8 *buf, int count);
void gbafilter_pal(u16* buf, int count);
void gbafilter_pal32(u32* 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 "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 BreakSet(array, addr, flag) \
((u8 *)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf))
#define BreakSet(array, addr, flag) \
((u8*)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf))
#define BreakClear(array, addr, flag) \
((u8 *)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf))
#define BreakClear(array, addr, flag) \
((u8*)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf))
// 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) \
((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf))
#define BreakCheck(array, addr, flag) \
((u8*)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf))
extern bool debugger;
extern bool dexp_eval(char *, u32 *);
extern void dexp_setVar(char *, u32);
extern bool dexp_eval(char*, u32*);
extern void dexp_setVar(char*, u32);
extern void dexp_listVars();
extern void dexp_saveVars(char *);
extern void dexp_loadVars(char *);
extern void dexp_saveVars(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 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);
struct regBreak {
// u8 regNum; /No longer needed
// bit 0 = equal
// bit 1 = greater
// bit 2 = smaller
// bit 3 = signed
u8 flags;
u32 intVal;
struct regBreak *next;
// u8 regNum; /No longer needed
// bit 0 = equal
// bit 1 = greater
// bit 2 = smaller
// bit 3 = signed
u8 flags;
u32 intVal;
struct regBreak* next;
};
extern u8 lowRegBreakCounter[4]; //(r0-r3)
extern u8 medRegBreakCounter[4]; //(r4-r7)
extern u8 highRegBreakCounter[4]; //(r8-r11)
extern u8 lowRegBreakCounter[4]; //(r0-r3)
extern u8 medRegBreakCounter[4]; //(r4-r7)
extern u8 highRegBreakCounter[4]; //(r8-r11)
extern u8 statusRegBreakCounter[4]; //(r12-r15)
extern bool enableRegBreak;
extern regBreak *breakRegList[16];
extern regBreak* breakRegList[16];
extern void breakReg_check(int i);
struct regBreak *getFromBreakRegList(u8 regnum, int location);
struct regBreak* getFromBreakRegList(u8 regnum, int location);
void clearBreakRegList();
void clearParticularRegListBreaks(int reg);
@ -73,7 +73,7 @@ void printBreakRegList(bool verbose);
void remoteStubMain();
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 remoteSetPort(int port);