more and more formating issues, I keep doing it in parts for my own reasons
This commit is contained in:
parent
48086ba62f
commit
1f37311a4a
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
4866
src/gba/Cheats.cpp
4866
src/gba/Cheats.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
2744
src/gba/GBA-arm.cpp
2744
src/gba/GBA-arm.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7700
src/gba/GBA.cpp
7700
src/gba/GBA.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
2907
src/gba/GBAGfx.h
2907
src/gba/GBAGfx.h
File diff suppressed because it is too large
Load Diff
6572
src/gba/GBALink.cpp
6572
src/gba/GBALink.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
267
src/gba/GBAcpu.h
267
src/gba/GBAcpu.h
|
@ -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
|
||||
|
|
1271
src/gba/GBAinline.h
1271
src/gba/GBAinline.h
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
482
src/gba/RTC.cpp
482
src/gba/RTC.cpp
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
1066
src/gba/Sound.cpp
1066
src/gba/Sound.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
1321
src/gba/armdis.cpp
1321
src/gba/armdis.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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__
|
||||
|
|
2376
src/gba/bios.cpp
2376
src/gba/bios.cpp
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
5332
src/gba/elf.cpp
5332
src/gba/elf.cpp
File diff suppressed because it is too large
Load Diff
350
src/gba/elf.h
350
src/gba/elf.h
|
@ -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
|
||||
|
|
1047
src/gba/ereader.cpp
1047
src/gba/ereader.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
6588
src/gba/remote.cpp
6588
src/gba/remote.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue