optimizations (DCN)

This commit is contained in:
dborth 2010-01-13 07:09:54 +00:00
parent e5c58eab80
commit 686a33a760
6 changed files with 610 additions and 483 deletions

View File

@ -54,7 +54,7 @@ void ClearFontData()
} }
/** /**
* Convert a short char sctring to a wide char string. * Convert a short char string to a wide char string.
* *
* This routine converts a supplied shot character string into a wide character string. * This routine converts a supplied shot character string into a wide character string.
* Note that it is the user's responsibility to clear the returned buffer once it is no longer needed. * Note that it is the user's responsibility to clear the returned buffer once it is no longer needed.
@ -190,7 +190,7 @@ void FreeTypeGX::unloadFont()
{ {
if(this->fontData.size() == 0) if(this->fontData.size() == 0)
return; return;
for(std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(); i != this->fontData.end(); i++) for(std::map<wchar_t, ftgxCharData>::iterator i = this->fontData.begin(), iEnd = this->fontData.end(); i != iEnd; ++i)
free(i->second.glyphDataTexture); free(i->second.glyphDataTexture);
this->fontData.clear(); this->fontData.clear();
} }
@ -310,16 +310,16 @@ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode)
*/ */
uint16_t FreeTypeGX::cacheGlyphDataComplete() uint16_t FreeTypeGX::cacheGlyphDataComplete()
{ {
uint16_t i = 0; uint32_t i = 0;
FT_UInt gIndex; FT_UInt gIndex;
FT_ULong charCode = FT_Get_First_Char( ftFace, &gIndex ); FT_ULong charCode = FT_Get_First_Char( ftFace, &gIndex );
while ( gIndex != 0 ) while ( gIndex != 0 )
{ {
if(this->cacheGlyphData(charCode) != NULL) if(this->cacheGlyphData(charCode) != NULL)
i++; ++i;
charCode = FT_Get_Next_Char( ftFace, charCode, &gIndex ); charCode = FT_Get_Next_Char( ftFace, charCode, &gIndex );
} }
return i; return (uint16_t)(i);
} }
/** /**
@ -336,11 +336,13 @@ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData)
uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4); uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4);
memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4); memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4);
for (uint16_t imagePosY = 0; imagePosY < bmp->rows; imagePosY++) uint32_t bmprows = bmp->rows;
uint32_t bmpwid = bmp->width;
for (uint32_t imagePosY = 0; imagePosY < bmprows; imagePosY++)
{ {
for (uint16_t imagePosX = 0; imagePosX < bmp->width; imagePosX++) for (uint32_t imagePosX = 0; imagePosX < bmpwid; imagePosX++)
{ {
uint32_t pixel = (uint32_t) bmp->buffer[imagePosY * bmp->width + imagePosX]; uint32_t pixel = (uint32_t) bmp->buffer[imagePosY * bmpwid + imagePosX];
glyphData[imagePosY * charData->textureWidth + imagePosX] = 0x00000000 | (pixel << 24) | (pixel << 16) | (pixel << 8) | pixel; glyphData[imagePosY * charData->textureWidth + imagePosX] = 0x00000000 | (pixel << 24) | (pixel << 16) | (pixel << 8) | pixel;
} }
} }
@ -444,7 +446,7 @@ int16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format
*/ */
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle) uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle)
{ {
uint16_t strLength = wcslen(text); uint32_t strLength = wcslen(text);
uint16_t x_pos = x, printed = 0; uint16_t x_pos = x, printed = 0;
uint16_t x_offset = 0, y_offset = 0; uint16_t x_offset = 0, y_offset = 0;
GXTexObj glyphTexture; GXTexObj glyphTexture;
@ -461,10 +463,12 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
y_offset = this->getStyleOffsetHeight(&offset, textStyle); y_offset = this->getStyleOffsetHeight(&offset, textStyle);
} }
for (uint16_t i = 0; i < strLength; i++) std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end();
for (uint32_t i = 0; i < strLength; ++i)
{ {
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != this->fontData.end() ) if( this->fontData.find(text[i]) != thisEnd)
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }
@ -485,7 +489,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color); this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color);
x_pos += glyphData->glyphAdvanceX; x_pos += glyphData->glyphAdvanceX;
printed++; ++printed;
} }
} }
@ -528,15 +532,16 @@ void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataO
*/ */
uint16_t FreeTypeGX::getWidth(wchar_t *text) uint16_t FreeTypeGX::getWidth(wchar_t *text)
{ {
uint16_t strLength = wcslen(text);
uint16_t strWidth = 0;
FT_Vector pairDelta; FT_Vector pairDelta;
uint32_t strLength = wcslen(text);
uint16_t strWidth = 0;
for (uint16_t i = 0; i < strLength; i++) std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end();
{
for (uint32_t i = 0; i < strLength; ++i){
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != this->fontData.end() ) if( this->fontData.find(text[i]) != thisEnd)
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }
@ -604,14 +609,15 @@ uint16_t FreeTypeGX::getHeight(wchar_t const *text)
*/ */
void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset) void FreeTypeGX::getOffset(wchar_t *text, ftgxDataOffset* offset)
{ {
uint16_t strLength = wcslen(text); uint32_t strLength = wcslen(text);
int16_t strMax = 0, strMin = 9999; int16_t strMax = 0, strMin = 9999;
std::map<wchar_t, ftgxCharData>::iterator thisEnd =this->fontData.end();
for (uint16_t i = 0; i < strLength; i++) for (uint32_t i = 0; i < strLength; ++i)
{ {
ftgxCharData* glyphData = NULL; ftgxCharData* glyphData = NULL;
if( this->fontData.find(text[i]) != this->fontData.end() ) if( this->fontData.find(text[i]) != thisEnd)
{ {
glyphData = &this->fontData[text[i]]; glyphData = &this->fontData[text[i]];
} }

73
source/ngc/fastmath.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef __VBA_FASTMATH_H__
#define __VBA_FASTMATH_H__
//
// ftou: float to unsigned
//
inline u32 ftou(f32 f){
return u32(s32(f));
}
//
// dtou: double to unsigned
//
inline u32 dtou(double f){
return u32(s32(f));
}
//
// utof: unsigned to float
//
inline f32 utof(u32 u){
// Warning! 'u' must be within the signed int range!
return f32(s32(u));
}
//
// utod: unsigned to double
//
inline double utod(u32 u){
// Warning! 'u' must be within the signed int range!
return double(s32(u));
}
// ===== POWERPC SPECIFIC =====
//
// absf: absolute value of a float
//
// ===== POWERPC SPECIFIC =====
inline float absf(float f){
// THREE instructions!
volatile float tmp = f;
// This MUST be "volatile"! Without it the compiler will try to
// optimize it and ends up using 13 instructions!
asm("fabs %0, %0 \n\t"
: "=f" (tmp) //output
: "f" (tmp) //input
);
return tmp;
}
// ===== POWERPC SPECIFIC =====
//
// absd: absolute value of a double
//
// ===== POWERPC SPECIFIC =====
inline double absd(double d){
// THREE instructions!
volatile double tmp = d;
// This MUST be "volatile"! Without it the compiler will try to
// optimize it and ends up using 13 instructions!
asm("fabs %0, %0 \n\t"
: "=f" (tmp) //output
: "f" (tmp) //input
);
return tmp;
}
#endif

View File

@ -14,12 +14,10 @@ Modified by Tantric, 2009
#include "pngu.h" #include "pngu.h"
#include "png.h" #include "png.h"
// Constants // Constants
#define PNGU_SOURCE_BUFFER 1 #define PNGU_SOURCE_BUFFER 1
#define PNGU_SOURCE_DEVICE 2 #define PNGU_SOURCE_DEVICE 2
// Prototypes of helper functions // Prototypes of helper functions
int pngu_info (IMGCTX ctx); int pngu_info (IMGCTX ctx);
int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha); int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha);
@ -29,7 +27,6 @@ void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t
void pngu_flush_data_to_buffer (png_structp png_ptr); void pngu_flush_data_to_buffer (png_structp png_ptr);
int pngu_clamp (int value, int min, int max); int pngu_clamp (int value, int min, int max);
// PNGU Image context struct // PNGU Image context struct
struct _IMGCTX struct _IMGCTX
{ {
@ -50,7 +47,6 @@ struct _IMGCTX
png_bytep img_data; png_bytep img_data;
}; };
// PNGU Implementation // // PNGU Implementation //
IMGCTX PNGU_SelectImageFromBuffer (const void *buffer) IMGCTX PNGU_SelectImageFromBuffer (const void *buffer)
@ -74,7 +70,6 @@ IMGCTX PNGU_SelectImageFromBuffer (const void *buffer)
return ctx; return ctx;
} }
IMGCTX PNGU_SelectImageFromDevice (const char *filename) IMGCTX PNGU_SelectImageFromDevice (const char *filename)
{ {
IMGCTX ctx = NULL; IMGCTX ctx = NULL;
@ -104,7 +99,6 @@ IMGCTX PNGU_SelectImageFromDevice (const char *filename)
return ctx; return ctx;
} }
void PNGU_ReleaseImageContext (IMGCTX ctx) void PNGU_ReleaseImageContext (IMGCTX ctx)
{ {
if (!ctx) if (!ctx)
@ -117,11 +111,9 @@ void PNGU_ReleaseImageContext (IMGCTX ctx)
free (ctx->prop.trans); free (ctx->prop.trans);
pngu_free_info (ctx); pngu_free_info (ctx);
free (ctx); free (ctx);
} }
int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop) int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop)
{ {
int res; int res;
@ -134,11 +126,9 @@ int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop)
} }
*imgprop = ctx->prop; *imgprop = ctx->prop;
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
{ {
int result; int result;
@ -157,12 +147,18 @@ int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buff
return result; return result;
// Copy image to the output buffer // Copy image to the output buffer
buffWidth = (width + stride) / 2; buffWidth = (width + stride) >> 1;
PNGU_u32 wid2 = width >>1;
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
for (x = 0; x < (width / 2); x++) {
((PNGU_u32 *)buffer)[y*buffWidth+x] = PNGU_RGB8_TO_YCbYCr (*(ctx->row_pointers[y]+x*6), *(ctx->row_pointers[y]+x*6+1), *(ctx->row_pointers[y]+x*6+2), for (x = 0; x < wid2; x++)
*(ctx->row_pointers[y]+x*6+3), *(ctx->row_pointers[y]+x*6+4), *(ctx->row_pointers[y]+x*6+5)); {
PNGU_u32 x6 = x*6;
((PNGU_u32 *)buffer)[y*buffWidth+x] = PNGU_RGB8_TO_YCbYCr (*(ctx->row_pointers[y]+x6), *(ctx->row_pointers[y]+x6+1), *(ctx->row_pointers[y]+x6+2),
*(ctx->row_pointers[y]+x6+3), *(ctx->row_pointers[y]+x6+4), *(ctx->row_pointers[y]+x6+5));
}
}
// Free resources // Free resources
free (ctx->img_data); free (ctx->img_data);
free (ctx->row_pointers); free (ctx->row_pointers);
@ -171,7 +167,6 @@ int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buff
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
{ {
int result; int result;
@ -199,7 +194,6 @@ int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buff
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha) int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha)
{ {
int result; int result;
@ -216,7 +210,7 @@ int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
{ {
// Alpha channel present, copy image to the output buffer // Alpha channel present, copy image to the output buffer
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
memcpy (buffer + (y * buffWidth * 4), ctx->row_pointers[y], width * 4); memcpy (buffer + (y * buffWidth << 2), ctx->row_pointers[y], width<<2);
} }
else else
{ {
@ -238,55 +232,55 @@ int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer) int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer)
{ {
int result; PNGU_u32 x, y;
PNGU_u32 x, y, qwidth, qheight;
// width and height need to be divisible by four // width and height need to be divisible by four
if ((width % 4) || (height % 4)) if ((width % 4) || (height % 4))
return PNGU_INVALID_WIDTH_OR_HEIGHT; return PNGU_INVALID_WIDTH_OR_HEIGHT;
result = pngu_decode (ctx, width, height, 1); int result = pngu_decode (ctx, width, height, 1);
if (result != PNGU_OK) if (result != PNGU_OK)
return result; return result;
// Copy image to the output buffer // Copy image to the output buffer
qwidth = width / 4; PNGU_u32 qwidth = width >> 2;
qheight = height / 4; PNGU_u32 qheight = height >> 2;
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 4; PNGU_u32 y4 = y << 2;
PNGU_u32 x12 = x * 12;
int blockbase = (y * qwidth + x) << 2;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
((PNGU_u64 *) buffer)[blockbase] = ((PNGU_u64 *) buffer)[blockbase] =
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
((PNGU_u64 *) buffer)[blockbase+1] = ((PNGU_u64 *) buffer)[blockbase+1] =
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
((PNGU_u64 *) buffer)[blockbase+2] = ((PNGU_u64 *) buffer)[blockbase+2] =
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) | (((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3))); (((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
((PNGU_u64 *) buffer)[blockbase+3] = ((PNGU_u64 *) buffer)[blockbase+3] =
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) | (((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) | (((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
@ -302,7 +296,6 @@ int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha) int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha)
{ {
int result; int result;
@ -318,8 +311,8 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
return result; return result;
// Init some vars // Init some vars
qwidth = width / 4; qwidth = width >> 2;
qheight = height / 4; qheight = height >> 2;
// Check is source image has an alpha channel // Check is source image has an alpha channel
if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) ) if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) )
@ -328,11 +321,16 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 4; int blockbase = (y * qwidth + x) << 2;
PNGU_u32 y4 = y << 2;
PNGU_u32 x16 = x << 4;
PNGU_u64 tmp; PNGU_u64 tmp;
PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16)); PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16));
PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16+8)); PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16+8));
// If first pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 // If first pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
@ -341,15 +339,15 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
// If second pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 // If second pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
if ((fieldA & 0xE0ULL) == 0xE0ULL) if ((fieldA & 0xE0ULL) == 0xE0ULL)
tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
else else
tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
// If third pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 // If third pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
else else
tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
// If fourth pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444 // If fourth pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
if ((fieldB & 0xE0ULL) == 0xE0ULL) if ((fieldB & 0xE0ULL) == 0xE0ULL)
@ -358,8 +356,8 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
((PNGU_u64 *) buffer)[blockbase] = tmp; ((PNGU_u64 *) buffer)[blockbase] = tmp;
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16+8));
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
@ -369,28 +367,28 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
if ((fieldA & 0xE0ULL) == 0xE0ULL) if ((fieldA & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
if ((fieldB & 0xE0ULL) == 0xE0ULL) if ((fieldB & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
((PNGU_u64 *) buffer)[blockbase+1] = tmp; ((PNGU_u64 *) buffer)[blockbase+1] = tmp;
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16+8));
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
@ -400,28 +398,28 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
if ((fieldA & 0xE0ULL) == 0xE0ULL) if ((fieldA & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
if ((fieldB & 0xE0ULL) == 0xE0ULL) if ((fieldB & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
((PNGU_u64 *) buffer)[blockbase+2] = tmp; ((PNGU_u64 *) buffer)[blockbase+2] = tmp;
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16+8));
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5); tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
@ -431,24 +429,25 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
if ((fieldA & 0xE0ULL) == 0xE0ULL) if ((fieldA & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21); tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20); tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL) if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27); tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28); tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
if ((fieldB & 0xE0ULL) == 0xE0ULL) if ((fieldB & 0xE0ULL) == 0xE0ULL)
// Opaque pixel, so set MSB to 1 and encode colors in RGB555 // Opaque pixel, so set MSB to 1 and encode colors in RGB555
tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11); tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
else else
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444 // Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12); tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
((PNGU_u64 *) buffer)[blockbase+3] = tmp; ((PNGU_u64 *) buffer)[blockbase+3] = tmp;
} }
} }
@ -464,34 +463,37 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 4; int blockbase = (y * qwidth + x) << 2;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); PNGU_u32 y4 = y << 2;
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); PNGU_u32 x12 = x * 12;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
((PNGU_u64 *) buffer)[blockbase] = ((PNGU_u64 *) buffer)[blockbase] =
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
((PNGU_u64 *) buffer)[blockbase+1] = ((PNGU_u64 *) buffer)[blockbase+1] =
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
((PNGU_u64 *) buffer)[blockbase+2] = ((PNGU_u64 *) buffer)[blockbase+2] =
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) | ((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3); ((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
((PNGU_u64 *) buffer)[blockbase+3] = ((PNGU_u64 *) buffer)[blockbase+3] =
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) | alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) | ((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
@ -509,34 +511,37 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 4; int blockbase = (y * qwidth + x) << 2;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); PNGU_u32 y4 = y << 2;
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); PNGU_u32 x12 = x * 12;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
((PNGU_u64 *) buffer)[blockbase] = ((PNGU_u64 *) buffer)[blockbase] =
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
((PNGU_u64 *) buffer)[blockbase+1] = ((PNGU_u64 *) buffer)[blockbase+1] =
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
((PNGU_u64 *) buffer)[blockbase+2] = ((PNGU_u64 *) buffer)[blockbase+2] =
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) | ((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4); ((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
((PNGU_u64 *) buffer)[blockbase+3] = ((PNGU_u64 *) buffer)[blockbase+3] =
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) | alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) | ((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
@ -554,7 +559,6 @@ int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *b
return PNGU_OK; return PNGU_OK;
} }
int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha) int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha)
{ {
int result; int result;
@ -570,8 +574,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
return result; return result;
// Init some variables // Init some variables
qwidth = width / 4; qwidth = width >> 2;
qheight = height / 4; qheight = height >> 2;
// Check is source image has an alpha channel // Check is source image has an alpha channel
if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) ) if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) )
@ -580,10 +584,13 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 8; int blockbase = (y * qwidth + x) << 3;
PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16)); PNGU_u32 y4 = y << 2;
PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*16+8)); PNGU_u32 x16 = x << 4;
PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16));
PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16+8));
((PNGU_u64 *) buffer)[blockbase] = ((PNGU_u64 *) buffer)[blockbase] =
((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) |
((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) |
@ -593,8 +600,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) |
((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8);
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16+8));
((PNGU_u64 *) buffer)[blockbase+1] = ((PNGU_u64 *) buffer)[blockbase+1] =
((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) |
((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) |
@ -604,8 +611,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) |
((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8);
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16+8));
((PNGU_u64 *) buffer)[blockbase+2] = ((PNGU_u64 *) buffer)[blockbase+2] =
((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) |
((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) |
@ -615,8 +622,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) | ((fieldA & 0xFFFF0000000000ULL) << 8) | ((fieldA & 0xFFFF00ULL) << 24) |
((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8); ((fieldB & 0xFFFF0000000000ULL) >> 24) | ((fieldB & 0xFFFF00ULL) >> 8);
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16)); fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16));
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*16+8)); fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16+8));
((PNGU_u64 *) buffer)[blockbase+3] = ((PNGU_u64 *) buffer)[blockbase+3] =
((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) | ((fieldA & 0xFF00000000ULL) << 24) | ((fieldA & 0xFF00000000000000ULL) >> 8) |
((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) | ((fieldA & 0xFFULL) << 40) | ((fieldA & 0xFF000000ULL) << 8) |
@ -636,10 +643,13 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
for (y = 0; y < qheight; y++) for (y = 0; y < qheight; y++)
for (x = 0; x < qwidth; x++) for (x = 0; x < qwidth; x++)
{ {
int blockbase = (y * qwidth + x) * 8; int blockbase = (y * qwidth + x) << 3;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4]+x*12)); PNGU_u32 y4 = y << 2;
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4]+x*12+8)); PNGU_u32 x12 = x * 12;
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
((PNGU_u64 *) buffer)[blockbase] = ((PNGU_u64 *) buffer)[blockbase] =
(((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) |
((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask);
@ -647,8 +657,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
(((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) |
((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+1]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+1]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
((PNGU_u64 *) buffer)[blockbase+1] = ((PNGU_u64 *) buffer)[blockbase+1] =
(((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) |
((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask);
@ -656,8 +666,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
(((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) |
((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+2]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+2]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
((PNGU_u64 *) buffer)[blockbase+2] = ((PNGU_u64 *) buffer)[blockbase+2] =
(((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) |
((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask);
@ -665,8 +675,8 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
(((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) | (((field64 & 0xFFFF0000000000ULL) << 8) | ((field64 & 0xFFFF0000ULL) << 16) |
((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL)); ((field64 & 0xFFULL) << 24) | ((field32 & 0xFF000000ULL) >> 8) | (field32 & 0xFFFFULL));
field64 = *((PNGU_u64 *)(ctx->row_pointers[y*4+3]+x*12)); field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y*4+3]+x*12+8)); field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
((PNGU_u64 *) buffer)[blockbase+3] = ((PNGU_u64 *) buffer)[blockbase+3] =
(((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) | (((field64 & 0xFF00000000000000ULL) >> 8) | (field64 & 0xFF00000000ULL) |
((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask); ((field64 & 0xFF00ULL) << 8) | ((field32 & 0xFF0000ULL) >> 16) | alphaMask);
@ -684,7 +694,6 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
return PNGU_OK; return PNGU_OK;
} }
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
{ {
png_uint_32 rowbytes; png_uint_32 rowbytes;
@ -744,7 +753,7 @@ int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
// Allocate memory to store the image in RGB format // Allocate memory to store the image in RGB format
rowbytes = width * 3; rowbytes = width * 3;
if (rowbytes % 4) if (rowbytes % 4)
rowbytes = ((rowbytes / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary rowbytes = ((rowbytes >> 2) + 1) << 2;
ctx->img_data = malloc (rowbytes * height); ctx->img_data = malloc (rowbytes * height);
if (!ctx->img_data) if (!ctx->img_data)
@ -765,16 +774,20 @@ int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
} }
// Encode YCbYCr image into RGB8 format // Encode YCbYCr image into RGB8 format
buffWidth = (width + stride) / 2; buffWidth = (width + stride) >> 1;
PNGU_u32 wid2 = width >> 1;
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
{ {
ctx->row_pointers[y] = ctx->img_data + (y * rowbytes); ctx->row_pointers[y] = ctx->img_data + (y * rowbytes);
for (x = 0; x < (width / 2); x++) for (x = 0; x < wid2; ++x)
{
PNGU_u32 x6 = x*6;
PNGU_YCbYCr_TO_RGB8 ( ((PNGU_u32 *)buffer)[y*buffWidth+x], PNGU_YCbYCr_TO_RGB8 ( ((PNGU_u32 *)buffer)[y*buffWidth+x],
((PNGU_u8 *) ctx->row_pointers[y]+x*6), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+1), ((PNGU_u8 *) ctx->row_pointers[y]+x6), ((PNGU_u8 *) ctx->row_pointers[y]+x6+1),
((PNGU_u8 *) ctx->row_pointers[y]+x*6+2), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+3), ((PNGU_u8 *) ctx->row_pointers[y]+x6+2), ((PNGU_u8 *) ctx->row_pointers[y]+x6+3),
((PNGU_u8 *) ctx->row_pointers[y]+x*6+4), ((PNGU_u8 *) ctx->row_pointers[y]+x*6+5) ); ((PNGU_u8 *) ctx->row_pointers[y]+x6+4), ((PNGU_u8 *) ctx->row_pointers[y]+x6+5) );
}
} }
// Tell libpng where is our image data // Tell libpng where is our image data
@ -856,7 +869,7 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
// Allocate memory to store the image in RGB format // Allocate memory to store the image in RGB format
rowbytes = width * 3; rowbytes = width * 3;
if (rowbytes % 4) if (rowbytes % 4)
rowbytes = ((rowbytes / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary rowbytes = ((rowbytes >>2) + 1) <<2; // Add extra padding so each row starts in a 4 byte boundary
ctx->img_data = malloc(rowbytes * height); ctx->img_data = malloc(rowbytes * height);
memset(ctx->img_data, 0, rowbytes * height); memset(ctx->img_data, 0, rowbytes * height);
@ -880,7 +893,7 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
return PNGU_LIB_ERROR; return PNGU_LIB_ERROR;
} }
for (y = 0; y < height; y++) for (y = 0; y < height; ++y)
{ {
ctx->row_pointers[y] = buffer + (y * rowbytes); ctx->row_pointers[y] = buffer + (y * rowbytes);
} }
@ -907,7 +920,9 @@ int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffe
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride) int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
{ {
int x,y,res; int res;
PNGU_u32 x,y, tmpy1, tmpy2, tmpyWid, tmpxy;
unsigned char * ptr = (unsigned char*)buffer; unsigned char * ptr = (unsigned char*)buffer;
unsigned char * tmpbuffer = (unsigned char *)malloc(width*height*3); unsigned char * tmpbuffer = (unsigned char *)malloc(width*height*3);
memset(tmpbuffer, 0, width*height*3); memset(tmpbuffer, 0, width*height*3);
@ -915,13 +930,18 @@ int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void
for(y=0; y < height; y++) for(y=0; y < height; y++)
{ {
tmpy1 = y * 640*3;
tmpy2 = y%4 << 2;
tmpyWid = (((y >> 2)<<4)*width);
for(x=0; x < width; x++) for(x=0; x < width; x++)
{ {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1); offset = tmpyWid + ((x >> 2)<<6) + ((tmpy2+ x%4 ) << 1);
tmpxy = x * 3 + tmpy1;
tmpbuffer[y*640*3+x*3] = ptr[offset+1]; // R tmpbuffer[tmpxy ] = ptr[offset+1]; // R
tmpbuffer[y*640*3+x*3+1] = ptr[offset+32]; // G tmpbuffer[tmpxy+1] = ptr[offset+32]; // G
tmpbuffer[y*640*3+x*3+2] = ptr[offset+33]; // B tmpbuffer[tmpxy+2] = ptr[offset+33]; // B
} }
} }
@ -933,31 +953,32 @@ int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void
// This function is taken from a libogc example // This function is taken from a libogc example
PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2) PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2)
{ {
int y1, cb1, cr1, y2, cb2, cr2, cb, cr; PNGU_u32 y1, cb1, cr1, y2, cb2, cr2, cb, cr;
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000; y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000; cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000; cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000; y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000; cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000; cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
cb = (cb1 + cb2) >> 1; cb = (cb1 + cb2) >> 1;
cr = (cr1 + cr2) >> 1; cr = (cr1 + cr2) >> 1;
return (PNGU_u32) ((y1 << 24) | (cb << 16) | (y2 << 8) | cr); return (PNGU_u32) ((y1 << 24) | (cb << 16) | (y2 << 8) | cr);
} }
void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2) void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2)
{ {
PNGU_u8 *val = (PNGU_u8 *) &ycbycr; PNGU_u8 *val = (PNGU_u8 *) &ycbycr;
int r, g, b;
r = 1.371f * (val[3] - 128); float val1 = (float)((int)(val[1]) - 128);
g = - 0.698f * (val[3] - 128) - 0.336f * (val[1] - 128); float val3 = (float)((int)(val[3]) - 128);
b = 1.732f * (val[1] - 128);
int r = (int)(1.371f * val3);
int g = (int)(- 0.698f * val3 - 0.336f * val1);
int b = (int)(1.732f * val1);
*r1 = pngu_clamp (val[0] + r, 0, 255); *r1 = pngu_clamp (val[0] + r, 0, 255);
*g1 = pngu_clamp (val[0] + g, 0, 255); *g1 = pngu_clamp (val[0] + g, 0, 255);
@ -1044,6 +1065,8 @@ int pngu_info (IMGCTX ctx)
// Query image properties if they have not been queried before // Query image properties if they have not been queried before
if (!ctx->propRead) if (!ctx->propRead)
{ {
int ctxNumTrans;
png_get_IHDR(ctx->png_ptr, ctx->info_ptr, &width, &height, png_get_IHDR(ctx->png_ptr, ctx->info_ptr, &width, &height,
(int *) &(ctx->prop.imgBitDepth), (int *) &(ctx->prop.imgBitDepth),
(int *) &(ctx->prop.imgColorType), (int *) &(ctx->prop.imgColorType),
@ -1074,60 +1097,88 @@ int pngu_info (IMGCTX ctx)
} }
// Constant used to scale 16 bit values to 8 bit values // Constant used to scale 16 bit values to 8 bit values
scale = 1; scale = 0;
if (ctx->prop.imgBitDepth == 16) if (ctx->prop.imgBitDepth == 16)
scale = 256; scale = 8;
// Query background color, if any. // Query background color, if any.
ctx->prop.validBckgrnd = 0; ctx->prop.validBckgrnd = 0;
if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA)) &&
(png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background)))
{
ctx->prop.validBckgrnd = 1;
ctx->prop.bckgrnd.r = background->red / scale;
ctx->prop.bckgrnd.g = background->green / scale;
ctx->prop.bckgrnd.b = background->blue / scale;
}
else if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA)) &&
(png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background)))
{
ctx->prop.validBckgrnd = 1;
ctx->prop.bckgrnd.r = ctx->prop.bckgrnd.g = ctx->prop.bckgrnd.b = background->gray / scale;
}
// Query list of transparent colors, if any. switch(ctx->prop.imgColorType)
ctx->prop.numTrans = 0;
ctx->prop.trans = NULL;
if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA)) &&
(png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values)))
{ {
if (ctx->prop.numTrans) case PNGU_COLOR_TYPE_RGB:
case PNGU_COLOR_TYPE_RGB_ALPHA:
{ {
ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctx->prop.numTrans); if(png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background)){
if (ctx->prop.trans) ctx->prop.validBckgrnd = 1;
for (i = 0; i < ctx->prop.numTrans; i++) ctx->prop.bckgrnd.r = background->red >> scale;
{ ctx->prop.bckgrnd.g = background->green >> scale;
ctx->prop.trans[i].r = trans_values[i].red / scale; ctx->prop.bckgrnd.b = background->blue >> scale;
ctx->prop.trans[i].g = trans_values[i].green / scale; }
ctx->prop.trans[i].b = trans_values[i].blue / scale;
// Query list of transparent colors, if any.
ctx->prop.numTrans = 0;
ctx->prop.trans = NULL;
if(png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values)){
ctxNumTrans = ctx->prop.numTrans;
if(ctxNumTrans){
ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctxNumTrans);
if (ctx->prop.trans)
for (i = 0; i < ctxNumTrans; i++)
{
ctx->prop.trans[i].r = trans_values[i].red >> scale;
ctx->prop.trans[i].g = trans_values[i].green >> scale;
ctx->prop.trans[i].b = trans_values[i].blue >> scale;
}
else
ctx->prop.numTrans = 0;
} }
else }
ctx->prop.numTrans = 0;
} }
} break;
else if (((ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA)) &&
(png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values))) case PNGU_COLOR_TYPE_GRAY:
{ case PNGU_COLOR_TYPE_GRAY_ALPHA:
if (ctx->prop.numTrans)
{ {
ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctx->prop.numTrans); if(png_get_bKGD (ctx->png_ptr, ctx->info_ptr, &background)){
if (ctx->prop.trans) ctx->prop.validBckgrnd = 1;
for (i = 0; i < ctx->prop.numTrans; i++) ctx->prop.bckgrnd.r =
ctx->prop.trans[i].r = ctx->prop.trans[i].g = ctx->prop.trans[i].b = ctx->prop.bckgrnd.g =
trans_values[i].gray / scale; ctx->prop.bckgrnd.b = background->gray >> scale;
else }
ctx->prop.numTrans = 0;
// Query list of transparent colors, if any.
ctx->prop.numTrans = 0;
ctx->prop.trans = NULL;
if(png_get_tRNS (ctx->png_ptr, ctx->info_ptr, &trans, (int *) &(ctx->prop.numTrans), &trans_values)){
ctxNumTrans = ctx->prop.numTrans;
if(ctxNumTrans){
ctx->prop.trans = malloc (sizeof (PNGUCOLOR) * ctxNumTrans);
if (ctx->prop.trans)
for (i = 0; i < ctxNumTrans; i++)
ctx->prop.trans[i].r =
ctx->prop.trans[i].g =
ctx->prop.trans[i].b = trans_values[i].gray >> scale;
else
ctx->prop.numTrans = 0;
}
}
} }
break;
default:
// It was none of those things,
{
// Query list of transparent colors, if any.
ctx->prop.numTrans = 0;
ctx->prop.trans = NULL;
}
break;
} }
ctx->propRead = 1; ctx->propRead = 1;
@ -1139,18 +1190,17 @@ int pngu_info (IMGCTX ctx)
return PNGU_OK; return PNGU_OK;
} }
int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha) int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlpha)
{ {
png_uint_32 rowbytes; png_uint_32 rowbytes;
int i; png_uint_32 i, propImgHeight;
// Read info if it hasn't been read before // Read info if it hasn't been read before
if (!ctx->infoRead) if (!ctx->infoRead)
{ {
i = pngu_info (ctx); int c = pngu_info (ctx);
if (i != PNGU_OK) if (c != PNGU_OK)
return i; return c;
} }
// Check if the user has specified the real width and height of the image // Check if the user has specified the real width and height of the image
@ -1182,8 +1232,9 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph
// Allocate memory to store the image // Allocate memory to store the image
rowbytes = png_get_rowbytes (ctx->png_ptr, ctx->info_ptr); rowbytes = png_get_rowbytes (ctx->png_ptr, ctx->info_ptr);
if (rowbytes % 4)
rowbytes = ((rowbytes / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary if (rowbytes & 3)
rowbytes = ((rowbytes >> 2) + 1) << 2; // Add extra padding so each row starts in a 4 byte boundary
ctx->img_data = malloc (rowbytes * ctx->prop.imgHeight); ctx->img_data = malloc (rowbytes * ctx->prop.imgHeight);
if (!ctx->img_data) if (!ctx->img_data)
@ -1200,7 +1251,8 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph
return PNGU_LIB_ERROR; return PNGU_LIB_ERROR;
} }
for (i = 0; i < ctx->prop.imgHeight; i++) propImgHeight = ctx->prop.imgHeight;
for (i = 0; i < propImgHeight; ++i)
ctx->row_pointers[i] = ctx->img_data + (i * rowbytes); ctx->row_pointers[i] = ctx->img_data + (i * rowbytes);
// Transform the image and copy it to our allocated memory // Transform the image and copy it to our allocated memory
@ -1263,4 +1315,3 @@ int pngu_clamp (int value, int min, int max)
return value; return value;
} }

View File

@ -45,6 +45,7 @@
#include "gcunzip.h" #include "gcunzip.h"
#include "gamesettings.h" #include "gamesettings.h"
#include "preferences.h" #include "preferences.h"
#include "fastmath.h"
//#define CARLLOG //#define CARLLOG
@ -124,7 +125,7 @@ bool systemPauseOnFrame()
} }
static u32 lastTime = 0; static u32 lastTime = 0;
#define RATE60HZ 166666.67 // 1/6 second or 166666.67 usec #define RATE60HZ 166666.67f // 1/6 second or 166666.67 usec
void system10Frames(int rate) void system10Frames(int rate)
{ {
@ -132,26 +133,26 @@ void system10Frames(int rate)
u32 diff = diff_usec(lastTime, time); u32 diff = diff_usec(lastTime, time);
// expected diff - actual diff // expected diff - actual diff
u32 timeOff = RATE60HZ - diff; u32 timeOff = ftou(RATE60HZ - utof(diff));
if(timeOff > 0 && timeOff < 100000) // we're running ahead! if(timeOff < 100000u)
usleep(timeOff); // let's take a nap usleep(timeOff); // let's take a nap
else else
timeOff = 0; // timeoff was not valid timeOff = 0; // timeoff was not valid
int speed = (RATE60HZ/diff)*100; int speed = int((RATE60HZ/utof(diff))*100.0f);
if (cartridgeType == 2) // GBA games require frameskipping if (cartridgeType == 2) // GBA games require frameskipping
{ {
// consider increasing skip // consider increasing skip
if(speed < 98) if(speed < 60)
systemFrameSkip += 1; systemFrameSkip += 4;
else if(speed < 80)
systemFrameSkip += 2;
else if(speed < 70) else if(speed < 70)
systemFrameSkip += 3; systemFrameSkip += 3;
else if(speed < 60) else if(speed < 80)
systemFrameSkip += 4; systemFrameSkip += 2;
else if(speed < 98)
++systemFrameSkip;
// consider decreasing skip // consider decreasing skip
else if(speed > 185) else if(speed > 185)
@ -159,7 +160,7 @@ void system10Frames(int rate)
else if(speed > 145) else if(speed > 145)
systemFrameSkip -= 2; systemFrameSkip -= 2;
else if(speed > 125) else if(speed > 125)
systemFrameSkip -= 1; --systemFrameSkip;
// correct invalid frame skip values // correct invalid frame skip values
if(systemFrameSkip > 20) if(systemFrameSkip > 20)
@ -505,47 +506,43 @@ u8 systemGetSensorDarkness()
void systemUpdateSolarSensor() void systemUpdateSolarSensor()
{ {
u8 d, sun; u8 sun = 0x0; //sun = 0xE8 - 0xE8 (case 0 and default)
switch (SunBars) switch (SunBars)
{ {
case 0:
d = 0xE8;
break;
case 1: case 1:
d = 0xE0; sun = 0xE8 - 0xE0;
break; break;
case 2: case 2:
d = 0xDA; sun = 0xE8 - 0xDA;
break; break;
case 3: case 3:
d = 0xD0; sun = 0xE8 - 0xD0;
break; break;
case 4: case 4:
d = 0xC8; sun = 0xE8 - 0xC8;
break; break;
case 5: case 5:
d = 0xC0; sun = 0xE8 - 0xC0;
break; break;
case 6: case 6:
d = 0xB0; sun = 0xE8 - 0xB0;
break; break;
case 7: case 7:
d = 0xA0; sun = 0xE8 - 0xA0;
break; break;
case 8: case 8:
d = 0x88; sun = 0xE8 - 0x88;
break; break;
case 9: case 9:
d = 0x70; sun = 0xE8 - 0x70;
break; break;
case 10: case 10:
d = 0x50; sun = 0xE8 - 0x50;
break; break;
default: default:
d = 0xE8;
break; break;
} }
sun = 0xE8 - d;
struct tm *newtime; struct tm *newtime;
time_t long_time; time_t long_time;
@ -559,27 +556,26 @@ void systemUpdateSolarSensor()
} }
else if (newtime->tm_hour > 20 || newtime->tm_hour < 6) else if (newtime->tm_hour > 20 || newtime->tm_hour < 6)
{ {
sun = sun / 9; // almost total darkness 8pm-9pm, 5am-6am sun /= 9; // almost total darkness 8pm-9pm, 5am-6am
} }
else if (newtime->tm_hour > 18 || newtime->tm_hour < 7) else if (newtime->tm_hour > 18 || newtime->tm_hour < 7)
{ {
sun = sun / 2; // half darkness 6pm-8pm, 6am-7am sun >>= 1;
} }
#ifdef HW_RVL #ifdef HW_RVL
// pointing the Gun Del Sol at the ground blocks the sun light, // pointing the Gun Del Sol at the ground blocks the sun light,
// because sometimes you need the shade. // because sometimes you need the shade.
int chan = 0; // first wiimote WPADData *Data = WPAD_Data(0);// first wiimote
WPADData *Data = WPAD_Data(chan);
WPADData data = *Data; WPADData data = *Data;
float f; float f = 1.0f;
if (data.orient.pitch > 0) if (data.orient.pitch > 0)
{
f = 1.0f - (data.orient.pitch/85.0f); f = 1.0f - (data.orient.pitch/85.0f);
else if (f < 0)
f = 1.0f; f = 0;
if (f < 0) }
f=0; sun = int(float(int(sun)) * f);
sun *= f;
#endif #endif
sensorDarkness = 0xE8 - sun; sensorDarkness = 0xE8 - sun;
} }
@ -587,9 +583,7 @@ void systemUpdateSolarSensor()
void systemUpdateMotionSensor() void systemUpdateMotionSensor()
{ {
#ifdef HW_RVL #ifdef HW_RVL
int chan = 0; // first wiimote WPADData *Data = WPAD_Data(0); // first wiimote
WPADData *Data = WPAD_Data(chan);
WPADData data = *Data; WPADData data = *Data;
static float OldTiltAngle, OldAvg; static float OldTiltAngle, OldAvg;
static bool WasFlat = false; static bool WasFlat = false;
@ -599,31 +593,31 @@ void systemUpdateMotionSensor()
{ {
sensorY = 2047+(data.gforce.x*50); sensorY = 2047+(data.gforce.x*50);
sensorX = 2047+(data.gforce.y*50); sensorX = 2047+(data.gforce.y*50);
TiltAngle = ((-data.orient.pitch) + OldTiltAngle)/2.0f; TiltAngle = ((-data.orient.pitch) + OldTiltAngle)*0.5f;
OldTiltAngle = -data.orient.pitch; OldTiltAngle = -data.orient.pitch;
} }
else else
{ {
sensorX = 2047-(data.gforce.x*50); sensorX = 2047-(data.gforce.x*50);
sensorY = 2047+(data.gforce.y*50); sensorY = 2047+(data.gforce.y*50);
TiltAngle = ((data.orient.roll) + OldTiltAngle)/2.0f; TiltAngle = ((data.orient.roll) + OldTiltAngle)*0.5f;
OldTiltAngle = data.orient.roll; OldTiltAngle = data.orient.roll;
} }
DeltaAngle = TiltAngle - OldAvg; DeltaAngle = TiltAngle - OldAvg;
if (DeltaAngle> 180) if (DeltaAngle > 180.0f)
DeltaAngle -= 360; DeltaAngle -= 360.0f;
else if (DeltaAngle < -180) else if (DeltaAngle < -180.0f)
DeltaAngle += 360; DeltaAngle += 360.0f;
OldAvg = TiltAngle; OldAvg = TiltAngle;
if (TiltAngle < 3.0f && TiltAngle> -3.0f) if(absf(TiltAngle) < 3.0f)
{ {
WasFlat = true; WasFlat = true;
TiltAngle = 0; TiltAngle = 0;
} }
else else
{ {
if (WasFlat) TiltAngle = TiltAngle / 2.0f; if (WasFlat) TiltAngle *= 0.5f;
WasFlat = false; WasFlat = false;
} }
@ -650,10 +644,10 @@ static bool ValidGameId(u32 id)
{ {
if (id == 0) if (id == 0)
return false; return false;
for (int i = 1; i <= 4; i++) for (unsigned i = 1u; i <= 4u; ++i)
{ {
u8 b = id & 0xFF; u8 b = id & 0xFF;
id = id >> 8; id >>= 8;
if (!(b >= 'A' && b <= 'Z') && !(b >= '0' && b <= '9')) if (!(b >= 'A' && b <= 'Z') && !(b >= '0' && b <= '9'))
return false; return false;
} }
@ -662,12 +656,10 @@ static bool ValidGameId(u32 id)
bool IsGameboyGame() bool IsGameboyGame()
{ {
if(cartridgeType == 1 && !gbCgbMode && !gbSgbMode) if(cartridgeType == 1 || gbCgbMode || gbSgbMode)
return true; return true;
else return false;
return false;
} }
bool IsGBAGame() bool IsGBAGame()
{ {
if(cartridgeType == 2) if(cartridgeType == 2)
@ -768,7 +760,7 @@ static void ApplyPerImagePreferences()
RomIdCode = rom[0xac] | (rom[0xad] << 8) | (rom[0xae] << 16) | (rom[0xaf] << 24); RomIdCode = rom[0xac] | (rom[0xad] << 8) | (rom[0xae] << 16) | (rom[0xaf] << 24);
RomTitle[0] = '\0'; RomTitle[0] = '\0';
for(int i=0; i < gameSettingsCount; i++) for(int i=0; i < gameSettingsCount; ++i)
{ {
if(gameSettings[i].gameID[0] == rom[0xac] && if(gameSettings[i].gameID[0] == rom[0xac] &&
gameSettings[i].gameID[1] == rom[0xad] && gameSettings[i].gameID[1] == rom[0xad] &&
@ -815,7 +807,7 @@ static void ApplyPerImagePreferences()
void LoadPatch() void LoadPatch()
{ {
int patchsize = 0; int patchsize = 0;
int patchtype; int patchtype = 0;
AllocSaveBuffer (); AllocSaveBuffer ();
@ -825,7 +817,7 @@ void LoadPatch()
sprintf(patchpath[1], "%s%s.ups",browser.dir,ROMFilename); sprintf(patchpath[1], "%s%s.ups",browser.dir,ROMFilename);
sprintf(patchpath[2], "%s%s.ppf",browser.dir,ROMFilename); sprintf(patchpath[2], "%s%s.ppf",browser.dir,ROMFilename);
for(patchtype=0; patchtype<3; patchtype++) for(; patchtype<3; patchtype++)
{ {
patchsize = LoadFile(patchpath[patchtype], SILENT); patchsize = LoadFile(patchpath[patchtype], SILENT);
@ -949,7 +941,7 @@ bool LoadVBAROM()
srcHeight = 160; srcHeight = 160;
loaded = VMCPULoadROM(); loaded = VMCPULoadROM();
srcPitch = 484; srcPitch = 484;
soundSetSampleRate(44100 / 2); soundSetSampleRate(22050); //44100 / 2
cpuSaveType = 0; cpuSaveType = 0;
break; break;

View File

@ -60,7 +60,7 @@ void Gb_Apu::set_output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* ri
void Gb_Apu::synth_volume( int iv ) void Gb_Apu::synth_volume( int iv )
{ {
double v = volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv; double v = volume_ * iv * 0.005 / osc_count;
good_synth.volume( v ); good_synth.volume( v );
med_synth .volume( v ); med_synth .volume( v );
} }
@ -88,8 +88,18 @@ void Gb_Apu::volume( double v )
void Gb_Apu::reset_regs() void Gb_Apu::reset_regs()
{ {
for ( int i = 0; i < 0x20; i++ ) int i = 24; // 32 - 8
regs [i] = 0; do {
regs [i] =
regs [i+1] =
regs [i+2] =
regs [i+3] =
regs [i+4] =
regs [i+5] =
regs [i+6] =
regs [i+7] = 0;
i-=8;
} while(i>=0);
square1.reset(); square1.reset();
square2.reset(); square2.reset();
@ -116,7 +126,7 @@ void Gb_Apu::reduce_clicks( bool reduce )
if ( reduce && wave.mode != mode_agb ) // AGB already eliminates clicks if ( reduce && wave.mode != mode_agb ) // AGB already eliminates clicks
dac_off_amp = -Gb_Osc::dac_bias; dac_off_amp = -Gb_Osc::dac_bias;
for ( int i = 0; i < osc_count; i++ ) for ( int i = 0; i < osc_count; ++i )
oscs [i]->dac_off_amp = dac_off_amp; oscs [i]->dac_off_amp = dac_off_amp;
// AGB always eliminates clicks on wave channel using same method // AGB always eliminates clicks on wave channel using same method
@ -130,7 +140,7 @@ void Gb_Apu::reset( mode_t mode, bool agb_wave )
if ( agb_wave ) if ( agb_wave )
mode = mode_agb; // using AGB wave features implies AGB hardware mode = mode_agb; // using AGB wave features implies AGB hardware
wave.agb_mask = agb_wave ? 0xFF : 0; wave.agb_mask = agb_wave ? 0xFF : 0;
for ( int i = 0; i < osc_count; i++ ) for ( int i = 0; i < osc_count; ++i )
oscs [i]->mode = mode; oscs [i]->mode = mode;
reduce_clicks( reduce_clicks_ ); reduce_clicks( reduce_clicks_ );
@ -147,13 +157,18 @@ void Gb_Apu::reset( mode_t mode, bool agb_wave )
{0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C,0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA}, {0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C,0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA},
{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF}, {0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF},
}; };
for ( int b = 2; --b >= 0; ) unsigned i = 0;
{ unsigned initialSize = sizeof(initial_wave[0]);
// Init both banks (does nothing if not in AGB mode)
// TODO: verify that this works // Init both banks (does nothing if not in AGB mode)
write_register( 0, 0xFF1A, b * 0x40 ); // TODO: verify that this works
for ( unsigned i = 0; i < sizeof initial_wave [0]; i++ ) write_register( 0, 0xFF1A, 0x40 );
write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] ); for (; i < initialSize; ++i ){
write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] );
}
write_register( 0, 0xFF1A, 0 );
for ( i = 0; i < initialSize; ++i ){
write_register( 0, i + wave_ram, initial_wave [(mode != mode_dmg)] [i] );
} }
} }
@ -173,8 +188,8 @@ Gb_Apu::Gb_Apu()
oscs [2] = &wave; oscs [2] = &wave;
oscs [3] = &noise; oscs [3] = &noise;
for ( int i = osc_count; --i >= 0; ) int i = osc_count - 1;
{ do {
Gb_Osc& o = *oscs [i]; Gb_Osc& o = *oscs [i];
o.regs = &regs [i * 5]; o.regs = &regs [i * 5];
o.output = 0; o.output = 0;
@ -184,7 +199,8 @@ Gb_Apu::Gb_Apu()
o.outputs [3] = 0; o.outputs [3] = 0;
o.good_synth = &good_synth; o.good_synth = &good_synth;
o.med_synth = &med_synth; o.med_synth = &med_synth;
} --i;
} while(i >= 0);
reduce_clicks_ = false; reduce_clicks_ = false;
set_tempo( 1.0 ); set_tempo( 1.0 );
@ -272,8 +288,8 @@ void Gb_Apu::silence_osc( Gb_Osc& o )
void Gb_Apu::apply_stereo() void Gb_Apu::apply_stereo()
{ {
for ( int i = osc_count; --i >= 0; ) int i = osc_count - 1;
{ do {
Gb_Osc& o = *oscs [i]; Gb_Osc& o = *oscs [i];
Blip_Buffer* out = o.outputs [calc_output( i )]; Blip_Buffer* out = o.outputs [calc_output( i )];
if ( o.output != out ) if ( o.output != out )
@ -281,7 +297,8 @@ void Gb_Apu::apply_stereo()
silence_osc( o ); silence_osc( o );
o.output = out; o.output = out;
} }
} --i;
} while(i >=0);
} }
void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data ) void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
@ -326,8 +343,11 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
else if ( addr == vol_reg && data != old_data ) else if ( addr == vol_reg && data != old_data )
{ {
// Master volume // Master volume
for ( int i = osc_count; --i >= 0; ) int i = osc_count - 1;
do {
silence_osc( *oscs [i] ); silence_osc( *oscs [i] );
--i;
} while( i >=0);
apply_volume(); apply_volume();
} }
@ -340,8 +360,11 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
{ {
// Power control // Power control
frame_phase = 0; frame_phase = 0;
for ( int i = osc_count; --i >= 0; ) int i = osc_count - 1;
do {
silence_osc( *oscs [i] ); silence_osc( *oscs [i] );
--i;
} while( i >=0);
reset_regs(); reset_regs();
if ( wave.mode != mode_dmg ) if ( wave.mode != mode_dmg )

View File

@ -93,17 +93,17 @@ extern int gfxLastVCOUNT;
static inline void gfxClearArray(u32 *array) static inline void gfxClearArray(u32 *array)
{ {
for(int i = 0; i < 240; i++) { for(unsigned i = 0; i < 240u; ++i) {
*array++ = 0x80000000; *array++ = 0x80000000;
} }
} }
static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u32 *line) u32 *line)
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; u8 *charBase = &vram[((control >> 2) & 0x03) << 14];
u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800]; u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) << 11];
u32 prio = ((control & 3)<<25) + 0x1000000; u32 prio = ((control & 3)<<25) + 0x1000000;
int sizeX = 256; int sizeX = 256;
int sizeY = 256; int sizeY = 256;
@ -125,13 +125,13 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
int maskX = sizeX-1; int maskX = sizeX-1;
int maskY = sizeY-1; int maskY = sizeY-1;
bool mosaicOn = (control & 0x40) ? true : false;
int xxx = hofs & maskX; int xxx = hofs & maskX;
int yyy = (vofs + VCOUNT) & maskY; int yyy = (vofs + VCOUNT) & maskY;
int mosaicX = (MOSAIC & 0x000F)+1; int mosaicX = (MOSAIC & 0x000F)+1;
int mosaicY = ((MOSAIC & 0x00F0)>>4)+1; int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
bool mosaicOn = (control & 0x40) ? true : false;
if(mosaicOn) { if(mosaicOn) {
if((VCOUNT % mosaicY) != 0) { if((VCOUNT % mosaicY) != 0) {
mosaicY = VCOUNT - (VCOUNT % mosaicY); mosaicY = VCOUNT - (VCOUNT % mosaicY);
@ -148,8 +148,8 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
int yshift = ((yyy>>3)<<5); int yshift = ((yyy>>3)<<5);
if((control) & 0x80) { if((control) & 0x80) {
u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift; u16 *screenSource = screenBase + ((xxx>>8) << 10) + ((xxx & 255)>>3) + yshift;
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; x++) {
u16 data = READ16LE(screenSource); u16 data = READ16LE(screenSource);
int tile = data & 0x3FF; int tile = data & 0x3FF;
@ -157,18 +157,18 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
int tileY = yyy & 7; int tileY = yyy & 7;
if(tileX == 7) if(tileX == 7)
screenSource++; ++screenSource;
if(data & 0x0400) if(data & 0x0400)
tileX = 7 - tileX; tileX = 7 - tileX;
if(data & 0x0800) if(data & 0x0800)
tileY = 7 - tileY; tileY = 7 - tileY;
u8 color = charBase[tile * 64 + tileY * 8 + tileX]; u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
line[x] = color ? (READ16LE(&palette[color]) | prio): 0x80000000; line[x] = color ? (READ16LE(&palette[color]) | prio): 0x80000000;
xxx++; ++xxx;
if(xxx == 256) { if(xxx == 256) {
if(sizeX > 256) if(sizeX > 256)
screenSource = screenBase + 0x400 + yshift; screenSource = screenBase + 0x400 + yshift;
@ -181,10 +181,9 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
screenSource = screenBase + yshift; screenSource = screenBase + yshift;
} }
} }
} else { } else {
u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) + u16 *screenSource = screenBase + ((xxx>>8) << 10) +((xxx&255)>>3) + yshift;
yshift; for(u32 x = 0; x < 240u; ++x) {
for(int x = 0; x < 240; x++) {
u16 data = READ16LE(screenSource); u16 data = READ16LE(screenSource);
int tile = data & 0x3FF; int tile = data & 0x3FF;
@ -192,7 +191,7 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
int tileY = yyy & 7; int tileY = yyy & 7;
if(tileX == 7) if(tileX == 7)
screenSource++; ++screenSource;
if(data & 0x0400) if(data & 0x0400)
tileX = 7 - tileX; tileX = 7 - tileX;
@ -202,7 +201,7 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)]; u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
if(tileX & 1) { if(tileX & 1) {
color = (color >> 4); color >>= 4;
} else { } else {
color &= 0x0F; color &= 0x0F;
} }
@ -210,7 +209,7 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
int pal = (data>>8) & 0xF0; int pal = (data>>8) & 0xF0;
line[x] = color ? (READ16LE(&palette[pal + color])|prio): 0x80000000; line[x] = color ? (READ16LE(&palette[pal + color])|prio): 0x80000000;
xxx++; ++xxx;
if(xxx == 256) { if(xxx == 256) {
if(sizeX > 256) if(sizeX > 256)
screenSource = screenBase + 0x400 + yshift; screenSource = screenBase + 0x400 + yshift;
@ -227,12 +226,12 @@ static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
if(mosaicOn) { if(mosaicOn) {
if(mosaicX > 1) { if(mosaicX > 1) {
int m = 1; int m = 1;
for(int i = 0; i < 239; i++) { for(u32 i = 0; i < 239u; ++i) {
line[i+1] = line[i]; line[i+1] = line[i];
m++; ++m;
if(m == mosaicX) { if(m == mosaicX) {
m = 1; m = 1;
i++; ++i;
} }
} }
} }
@ -249,12 +248,12 @@ static inline void gfxDrawRotScreen(u16 control,
u32 *line) u32 *line)
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; u8 *charBase = &vram[((control >> 2) & 0x03) << 14];
u8 *screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800]; u8 *screenBase = (u8 *)&vram[((control >> 8) & 0x1f) << 11];
int prio = ((control & 3) << 25) + 0x1000000; int prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 128; u32 sizeX = 128;
int sizeY = 128; u32 sizeY = 128;
switch((control >> 14) & 3) { switch((control >> 14) & 3) {
case 0: case 0:
break; break;
@ -317,7 +316,7 @@ static inline void gfxDrawRotScreen(u16 control,
} }
if(control & 0x2000) { if(control & 0x2000) {
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
int xxx = (realX >> 8) & maskX; int xxx = (realX >> 8) & maskX;
int yyy = (realY >> 8) & maskY; int yyy = (realY >> 8) & maskY;
@ -334,17 +333,12 @@ static inline void gfxDrawRotScreen(u16 control,
realY += dy; realY += dy;
} }
} else { } else {
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
int xxx = (realX >> 8); int xxx = (realX >> 8);
int yyy = (realY >> 8); int yyy = (realY >> 8);
if(xxx < 0 || if(unsigned(xxx) < sizeX && unsigned(yyy) < sizeY) {
yyy < 0 || int tile = screenBase[(xxx>>3) + ((yyy>>3)<<yshift)];
xxx >= sizeX ||
yyy >= sizeY) {
line[x] = 0x80000000;
} else {
int tile = screenBase[(xxx>>3) + ((yyy>>3)<<yshift)];
int tileX = (xxx & 7); int tileX = (xxx & 7);
int tileY = yyy & 7; int tileY = yyy & 7;
@ -352,6 +346,8 @@ static inline void gfxDrawRotScreen(u16 control,
u8 color = charBase[(tile<<6) + (tileY<<3) + tileX]; u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
line[x] = color ? (READ16LE(&palette[color])|prio): 0x80000000; line[x] = color ? (READ16LE(&palette[color])|prio): 0x80000000;
} else {
line[x] = 0x80000000;
} }
realX += dx; realX += dx;
realY += dy; realY += dy;
@ -362,12 +358,12 @@ static inline void gfxDrawRotScreen(u16 control,
int mosaicX = (MOSAIC & 0xF) + 1; int mosaicX = (MOSAIC & 0xF) + 1;
if(mosaicX > 1) { if(mosaicX > 1) {
int m = 1; int m = 1;
for(int i = 0; i < 239; i++) { for(u32 i = 0; i < 239u; ++i) {
line[i+1] = line[i]; line[i+1] = line[i];
m++; ++m;
if(m == mosaicX) { if(m == mosaicX) {
m = 1; m = 1;
i++; ++i;
} }
} }
} }
@ -385,8 +381,9 @@ static inline void gfxDrawRotScreen16Bit(u16 control,
{ {
u16 *screenBase = (u16 *)&vram[0]; u16 *screenBase = (u16 *)&vram[0];
int prio = ((control & 3) << 25) + 0x1000000; int prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 240;
int sizeY = 160; u32 sizeX = 240;
u32 sizeY = 160;
int startX = (x_l) | ((x_h & 0x07FF)<<16); int startX = (x_l) | ((x_h & 0x07FF)<<16);
if(x_h & 0x0800) if(x_h & 0x0800)
@ -439,15 +436,13 @@ static inline void gfxDrawRotScreen16Bit(u16 control,
int xxx = (realX >> 8); int xxx = (realX >> 8);
int yyy = (realY >> 8); int yyy = (realY >> 8);
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
if(xxx < 0 || if(unsigned(xxx) < sizeX && unsigned(yyy) < sizeY) {
yyy < 0 || line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
xxx >= sizeX ||
yyy >= sizeY) {
line[x] = 0x80000000;
} else { } else {
line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); line[x] = 0x80000000;
} }
realX += dx; realX += dx;
realY += dy; realY += dy;
@ -459,12 +454,12 @@ static inline void gfxDrawRotScreen16Bit(u16 control,
int mosaicX = (MOSAIC & 0xF) + 1; int mosaicX = (MOSAIC & 0xF) + 1;
if(mosaicX > 1) { if(mosaicX > 1) {
int m = 1; int m = 1;
for(int i = 0; i < 239; i++) { for(u32 i = 0; i < 239u; ++i) {
line[i+1] = line[i]; line[i+1] = line[i];
m++; ++m;
if(m == mosaicX) { if(m == mosaicX) {
m = 1; m = 1;
i++; ++i;
} }
} }
} }
@ -483,8 +478,8 @@ static inline void gfxDrawRotScreen256(u16 control,
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
u8 *screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000]; u8 *screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000];
int prio = ((control & 3) << 25) + 0x1000000; int prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 240; u32 sizeX = 240;
int sizeY = 160; u32 sizeY = 160;
int startX = (x_l) | ((x_h & 0x07FF)<<16); int startX = (x_l) | ((x_h & 0x07FF)<<16);
if(x_h & 0x0800) if(x_h & 0x0800)
@ -538,16 +533,12 @@ static inline void gfxDrawRotScreen256(u16 control,
int xxx = (realX >> 8); int xxx = (realX >> 8);
int yyy = (realY >> 8); int yyy = (realY >> 8);
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240; ++x) {
if(xxx < 0 || if(unsigned(xxx) < sizeX && unsigned(yyy) < sizeY) {
yyy < 0 ||
xxx >= sizeX ||
yyy >= sizeY) {
line[x] = 0x80000000;
} else {
u8 color = screenBase[yyy * 240 + xxx]; u8 color = screenBase[yyy * 240 + xxx];
line[x] = color ? (READ16LE(&palette[color])|prio): 0x80000000; line[x] = color ? (READ16LE(&palette[color])|prio): 0x80000000;
} else {
line[x] = 0x80000000;
} }
realX += dx; realX += dx;
realY += dy; realY += dy;
@ -560,12 +551,12 @@ static inline void gfxDrawRotScreen256(u16 control,
int mosaicX = (MOSAIC & 0xF) + 1; int mosaicX = (MOSAIC & 0xF) + 1;
if(mosaicX > 1) { if(mosaicX > 1) {
int m = 1; int m = 1;
for(int i = 0; i < 239; i++) { for(u32 i = 0; i < 239u; ++i) {
line[i+1] = line[i]; line[i+1] = line[i];
m++; ++m;
if(m == mosaicX) { if(m == mosaicX) {
m = 1; m = 1;
i++; ++i;
} }
} }
} }
@ -584,8 +575,8 @@ static inline void gfxDrawRotScreen16Bit160(u16 control,
u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] : u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] :
(u16 *)&vram[0]; (u16 *)&vram[0];
int prio = ((control & 3) << 25) + 0x1000000; int prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 160; u32 sizeX = 160;
int sizeY = 128; u32 sizeY = 128;
int startX = (x_l) | ((x_h & 0x07FF)<<16); int startX = (x_l) | ((x_h & 0x07FF)<<16);
if(x_h & 0x0800) if(x_h & 0x0800)
@ -639,14 +630,11 @@ static inline void gfxDrawRotScreen16Bit160(u16 control,
int xxx = (realX >> 8); int xxx = (realX >> 8);
int yyy = (realY >> 8); int yyy = (realY >> 8);
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
if(xxx < 0 || if(unsigned(xxx) < sizeX && unsigned(yyy) < sizeY) {
yyy < 0 ||
xxx >= sizeX ||
yyy >= sizeY) {
line[x] = 0x80000000;
} else {
line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
} else {
line[x] = 0x80000000;
} }
realX += dx; realX += dx;
realY += dy; realY += dy;
@ -659,12 +647,12 @@ static inline void gfxDrawRotScreen16Bit160(u16 control,
int mosaicX = (MOSAIC & 0xF) + 1; int mosaicX = (MOSAIC & 0xF) + 1;
if(mosaicX > 1) { if(mosaicX > 1) {
int m = 1; int m = 1;
for(int i = 0; i < 239; i++) { for(u32 i = 0; i < 239u; ++i) {
line[i+1] = line[i]; line[i+1] = line[i];
m++; ++m;
if(m == mosaicX) { if(m == mosaicX) {
m = 1; m = 1;
i++; ++i;
} }
} }
} }
@ -684,11 +672,11 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
u16 *spritePalette = &((u16 *)paletteRAM)[256]; u16 *spritePalette = &((u16 *)paletteRAM)[256];
int mosaicY = ((MOSAIC & 0xF000)>>12) + 1; int mosaicY = ((MOSAIC & 0xF000)>>12) + 1;
int mosaicX = ((MOSAIC & 0xF00)>>8) + 1; int mosaicX = ((MOSAIC & 0xF00)>>8) + 1;
for(int x = 0; x < 128 ; x++) { for(u32 x = 0; x < 128u; ++x) {
u16 a0 = READ16LE(sprites++); u16 a0 = READ16LE(sprites++);
u16 a1 = READ16LE(sprites++); u16 a1 = READ16LE(sprites++);
u16 a2 = READ16LE(sprites++); u16 a2 = READ16LE(sprites++);
sprites++; ++sprites;
lineOBJpixleft[x]=lineOBJpix; lineOBJpixleft[x]=lineOBJpix;
@ -705,8 +693,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
a1 &= 0x3FFF; a1 &= 0x3FFF;
} }
int sizeX = 8<<(a1>>14); u32 sizeX = 8<<(a1>>14);
int sizeY = sizeX; u32 sizeY = sizeX;
if ((a0>>14) & 1) if ((a0>>14) & 1)
{ {
@ -742,7 +730,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if((sy+sizeY) > 256) if((sy+sizeY) > 256)
sy -= 256; sy -= 256;
if ((sx+sizeX)> 512) if ((sx+sizeX)> 512)
sx-=512; sx -= 512;
if (sx<0) if (sx<0)
{ {
sizeX+=sx; sizeX+=sx;
@ -752,10 +740,10 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
sizeX=240-sx; sizeX=240-sx;
if ((VCOUNT>=sy) && (VCOUNT<sy+sizeY) && (sx<240)) if ((VCOUNT>=sy) && (VCOUNT<sy+sizeY) && (sx<240))
{ {
if (a0 & 0x0100) lineOBJpix -= (sizeX-2);
lineOBJpix-=8+2*sizeX;
else if (a0 & 0x0100)
lineOBJpix-=sizeX-2; lineOBJpix -= (10+sizeX);
} }
continue; continue;
} }
@ -767,11 +755,9 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(a0 & 0x0100) { if(a0 & 0x0100) {
int fieldX = sizeX; u32 fieldX = sizeX;
int fieldY = sizeY; u32 fieldY = sizeY;
if(a0 & 0x0200) { if(a0 & 0x0200) {
fieldX <<= 1; fieldX <<= 1;
fieldY <<= 1; fieldY <<= 1;
@ -779,8 +765,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if((sy+fieldY) > 256) if((sy+fieldY) > 256)
sy -= 256; sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) { if(unsigned(t) < fieldY) {
int startpix = 0; u32 startpix = 0;
if ((sx+fieldX)> 512) if ((sx+fieldX)> 512)
{ {
startpix=512-sx; startpix=512-sx;
@ -789,18 +775,18 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if((sx < 240) || startpix) { if((sx < 240) || startpix) {
lineOBJpix-=8; lineOBJpix-=8;
// int t2 = t - (fieldY >> 1); // int t2 = t - (fieldY >> 1);
int rot = (a1 >> 9) & 0x1F; int rot = (((a1 >> 9) & 0x1F) << 4);
u16 *OAM = (u16 *)oam; u16 *OAM = (u16 *)oam;
int dx = READ16LE(&OAM[3 + (rot << 4)]); int dx = READ16LE(&OAM[3 + rot]);
if(dx & 0x8000) if(dx & 0x8000)
dx |= 0xFFFF8000; dx |= 0xFFFF8000;
int dmx = READ16LE(&OAM[7 + (rot << 4)]); int dmx = READ16LE(&OAM[7 + rot]);
if(dmx & 0x8000) if(dmx & 0x8000)
dmx |= 0xFFFF8000; dmx |= 0xFFFF8000;
int dy = READ16LE(&OAM[11 + (rot << 4)]); int dy = READ16LE(&OAM[11 + rot]);
if(dy & 0x8000) if(dy & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = READ16LE(&OAM[15 + (rot << 4)]); int dmy = READ16LE(&OAM[15 + rot]);
if(dmy & 0x8000) if(dmy & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
@ -808,10 +794,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
t -= (t % mosaicY); t -= (t % mosaicY);
} }
int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx int realX = ((sizeX) << 7) - (fieldX >> 1)*dx + ((t - (fieldY>>1))* dmx);
+ t * dmx; int realY = ((sizeY) << 7) - (fieldX >> 1)*dy + ((t - (fieldY>>1))* dmy);
int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
+ t * dmy;
u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
@ -824,18 +808,16 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
inc = sizeX >> 2; inc = sizeX >> 2;
else else
c &= 0x3FE; c &= 0x3FE;
for(int x = 0; x < fieldX; x++) { for(u32 x = 0; x < fieldX; x++) {
if (x >= startpix) if (x >= startpix)
lineOBJpix-=2; lineOBJpix-=2;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
if(unsigned(xxx) < sizeX &&
unsigned(yyy) < sizeY && sx < 240){
if(xxx < 0 || xxx >= sizeX ||
yyy < 0 || yyy >= sizeY ||
sx >= 240);
else {
u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5) u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
+ ((yyy & 7)<<3) + ((xxx >> 3)<<6) + + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
(xxx & 7))&0x7FFF)]; (xxx & 7))&0x7FFF)];
@ -851,7 +833,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
} }
if (a0 & 0x1000) { if (a0 & 0x1000) {
m++; ++m;
if (m==mosaicX) if (m==mosaicX)
m=0; m=0;
} }
@ -873,20 +855,19 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if(DISPCNT & 0x40) if(DISPCNT & 0x40)
inc = sizeX >> 3; inc = sizeX >> 3;
int palette = (a2 >> 8) & 0xF0; int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) { for(u32 x = 0; x < fieldX; ++x) {
if (x >= startpix) if (x >= startpix)
lineOBJpix-=2; lineOBJpix-=2;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
if(xxx < 0 || xxx >= sizeX || if(unsigned(xxx) < sizeX &&
yyy < 0 || yyy >= sizeY || unsigned(yyy) < sizeY && sx < 240){
sx >= 240);
else {
u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5) u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
+ ((yyy & 7)<<2) + ((xxx >> 3)<<5) + + ((yyy & 7)<<2) + ((xxx >> 3)<<5)
((xxx & 7)>>1))&0x7FFF)]; + ((xxx & 7)>>1))&0x7FFF)];
if(xxx & 1) if(xxx & 1)
color >>= 4; color >>= 4;
else else
@ -904,7 +885,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
} }
} }
if((a0 & 0x1000) && m) { if((a0 & 0x1000) && m) {
m++; ++m;
if (m==mosaicX) if (m==mosaicX)
m=0; m=0;
} }
@ -925,8 +906,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if(sy+sizeY > 256) if(sy+sizeY > 256)
sy -= 256; sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) { if(unsigned(t) < sizeY) {
int startpix = 0; u32 startpix = 0;
if ((sx+sizeX)> 512) if ((sx+sizeX)> 512)
{ {
startpix=512-sx; startpix=512-sx;
@ -961,9 +942,9 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
xxx = 7; xxx = 7;
u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) { for(u32 xx = 0; xx < sizeX; xx++) {
if (xx >= startpix) if (xx >= startpix)
lineOBJpix--; --lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
@ -980,7 +961,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
} }
if (a0 & 0x1000) { if (a0 & 0x1000) {
m++; ++m;
if (m==mosaicX) if (m==mosaicX)
m=0; m=0;
} }
@ -993,8 +974,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
sx = (sx+1) & 511; sx = (sx+1) & 511;
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx--; --xxx;
address--; --address;
if(xxx == -1) { if(xxx == -1) {
address -= 56; address -= 56;
xxx = 7; xxx = 7;
@ -1002,8 +983,8 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
if(address < 0x10000) if(address < 0x10000)
address += 0x8000; address += 0x8000;
} else { } else {
xxx++; ++xxx;
address++; ++address;
if(xxx == 8) { if(xxx == 8) {
address += 56; address += 56;
xxx = 0; xxx = 0;
@ -1037,15 +1018,16 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
int palette = (a2 >> 8) & 0xF0; int palette = (a2 >> 8) & 0xF0;
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx = 7; xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) { int xx = sizeX - 1;
if (xx >= startpix) do{
lineOBJpix--; if (xx >= (int)(startpix))
--lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
color = (color >> 4); color >>= 4;
} else } else
color &= 0x0F; color &= 0x0F;
@ -1061,7 +1043,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
} }
} }
if (a0 & 0x1000) { if (a0 & 0x1000) {
m++; ++m;
if (m==mosaicX) if (m==mosaicX)
m=0; m=0;
} }
@ -1070,26 +1052,27 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
lineOBJ[sx] = 0x001F; lineOBJ[sx] = 0x001F;
#endif #endif
sx = (sx+1) & 511; sx = (sx+1) & 511;
xxx--; --xxx;
if(!(xx & 1)) if(!(xx & 1))
address--; --address;
if(xxx == -1) { if(xxx == -1) {
xxx = 7; xxx = 7;
address -= 28; address -= 28;
} }
if(address < 0x10000) if(address < 0x10000)
address += 0x8000; address += 0x8000;
} --xx;
}while(xx >= 0);
} else { } else {
for(int xx = 0; xx < sizeX; xx++) { for(u32 xx = 0; xx < sizeX; ++xx) {
if (xx >= startpix) if (xx >= startpix)
lineOBJpix--; --lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
color = (color >> 4); color >>= 4;
} else } else
color &= 0x0F; color &= 0x0F;
@ -1106,7 +1089,7 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
} }
} }
if (a0 & 0x1000) { if (a0 & 0x1000) {
m++; ++m;
if (m==mosaicX) if (m==mosaicX)
m=0; m=0;
} }
@ -1115,9 +1098,9 @@ static inline void gfxDrawSprites(u32 *lineOBJ)
lineOBJ[sx] = 0x001F; lineOBJ[sx] = 0x001F;
#endif #endif
sx = (sx+1) & 511; sx = (sx+1) & 511;
xxx++; ++xxx;
if(xx & 1) if(xx & 1)
address++; ++address;
if(xxx == 8) { if(xxx == 8) {
address += 28; address += 28;
xxx = 0; xxx = 0;
@ -1140,12 +1123,12 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if((layerEnable & 0x9000) == 0x9000) { if((layerEnable & 0x9000) == 0x9000) {
u16 *sprites = (u16 *)oam; u16 *sprites = (u16 *)oam;
// u16 *spritePalette = &((u16 *)paletteRAM)[256]; // u16 *spritePalette = &((u16 *)paletteRAM)[256];
for(int x = 0; x < 128 ; x++) { for(int x = 0; x < 128 ; ++x) {
int lineOBJpix = lineOBJpixleft[x]; int lineOBJpix = lineOBJpixleft[x];
u16 a0 = READ16LE(sprites++); u16 a0 = READ16LE(sprites++);
u16 a1 = READ16LE(sprites++); u16 a1 = READ16LE(sprites++);
u16 a2 = READ16LE(sprites++); u16 a2 = READ16LE(sprites++);
sprites++; ++sprites;
if (lineOBJpix<=0) if (lineOBJpix<=0)
continue; continue;
@ -1163,8 +1146,8 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
a1 &= 0x3FFF; a1 &= 0x3FFF;
} }
int sizeX = 8<<(a1>>14); u32 sizeX = 8<<(a1>>14);
int sizeY = sizeX; u32 sizeY = sizeX;
if ((a0>>14) & 1) if ((a0>>14) & 1)
{ {
@ -1185,7 +1168,7 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(a0 & 0x0100) { if(a0 & 0x0100) {
int fieldX = sizeX; int fieldX = sizeX;
int fieldY = sizeY; u32 fieldY = sizeY;
if(a0 & 0x0200) { if(a0 & 0x0200) {
fieldX <<= 1; fieldX <<= 1;
fieldY <<= 1; fieldY <<= 1;
@ -1193,7 +1176,7 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if((sy+fieldY) > 256) if((sy+fieldY) > 256)
sy -= 256; sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) { if(unsigned(t) < fieldY) {
int sx = (a1 & 0x1FF); int sx = (a1 & 0x1FF);
int startpix = 0; int startpix = 0;
if ((sx+fieldX)> 512) if ((sx+fieldX)> 512)
@ -1203,25 +1186,23 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if((sx < 240) || startpix) { if((sx < 240) || startpix) {
lineOBJpix-=8; lineOBJpix-=8;
// int t2 = t - (fieldY >> 1); // int t2 = t - (fieldY >> 1);
int rot = (a1 >> 9) & 0x1F; int rot = ((a1 >> 9) & 0x1F) << 4;
u16 *OAM = (u16 *)oam; u16 *OAM = (u16 *)oam;
int dx = READ16LE(&OAM[3 + (rot << 4)]); int dx = READ16LE(&OAM[3 + rot]);
if(dx & 0x8000) if(dx & 0x8000)
dx |= 0xFFFF8000; dx |= 0xFFFF8000;
int dmx = READ16LE(&OAM[7 + (rot << 4)]); int dmx = READ16LE(&OAM[7 + rot]);
if(dmx & 0x8000) if(dmx & 0x8000)
dmx |= 0xFFFF8000; dmx |= 0xFFFF8000;
int dy = READ16LE(&OAM[11 + (rot << 4)]); int dy = READ16LE(&OAM[11 + rot]);
if(dy & 0x8000) if(dy & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = READ16LE(&OAM[15 + (rot << 4)]); int dmy = READ16LE(&OAM[15 + rot]);
if(dmy & 0x8000) if(dmy & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx int realX = ((sizeX) << 7) - (fieldX >> 1)*dx + (dmx*(t - (fieldY>>1)));
+ t * dmx; int realY = ((sizeY) << 7) - (fieldX >> 1)*dy + (dmy*(t - (fieldY>>1)));
int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
+ t * dmy;
// u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
@ -1234,7 +1215,7 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
inc = sizeX >> 2; inc = sizeX >> 2;
else else
c &= 0x3FE; c &= 0x3FE;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; ++x) {
if (x >= startpix) if (x >= startpix)
lineOBJpix-=2; lineOBJpix-=2;
if (lineOBJpix<0) if (lineOBJpix<0)
@ -1242,10 +1223,9 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
if(xxx < 0 || xxx >= sizeX || if(unsigned(xxx) < sizeX &&
yyy < 0 || yyy >= sizeY || unsigned(yyy) < sizeY && sx < 240){
sx >= 240) {
} else {
u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5) u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
+ ((yyy & 7)<<3) + ((xxx >> 3)<<6) + + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
(xxx & 7))&0x7fff)]; (xxx & 7))&0x7fff)];
@ -1266,7 +1246,7 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(DISPCNT & 0x40) if(DISPCNT & 0x40)
inc = sizeX >> 3; inc = sizeX >> 3;
// int palette = (a2 >> 8) & 0xF0; // int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; ++x) {
if (x >= startpix) if (x >= startpix)
lineOBJpix-=2; lineOBJpix-=2;
if (lineOBJpix<0) if (lineOBJpix<0)
@ -1278,10 +1258,9 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
// t == 0 || t == (sizeY-1)) { // t == 0 || t == (sizeY-1)) {
// lineOBJ[sx] = 0x001F | prio; // lineOBJ[sx] = 0x001F | prio;
// } else { // } else {
if(xxx < 0 || xxx >= sizeX || if(unsigned(xxx) < sizeX &&
yyy < 0 || yyy >= sizeY || unsigned(yyy) < sizeY && sx < 240){
sx >= 240) {
} else {
u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5) u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
+ ((yyy & 7)<<2) + ((xxx >> 3)<<5) + + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
((xxx & 7)>>1))&0x7fff)]; ((xxx & 7)>>1))&0x7fff)];
@ -1306,9 +1285,9 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if((sy+sizeY) > 256) if((sy+sizeY) > 256)
sy -= 256; sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) { if(unsigned(t) < sizeY) {
int sx = (a1 & 0x1FF); int sx = (a1 & 0x1FF);
int startpix = 0; u32 startpix = 0;
if ((sx+sizeX)> 512) if ((sx+sizeX)> 512)
{ {
startpix=512-sx; startpix=512-sx;
@ -1336,9 +1315,9 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(a1 & 0x1000) if(a1 & 0x1000)
xxx = 7; xxx = 7;
// u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) { for(u32 xx = 0; xx < sizeX; ++xx) {
if (xx >= startpix) if (xx >= startpix)
lineOBJpix--; --lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
@ -1350,8 +1329,8 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
sx = (sx+1) & 511; sx = (sx+1) & 511;
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx--; --xxx;
address--; --address;
if(xxx == -1) { if(xxx == -1) {
address -= 56; address -= 56;
xxx = 7; xxx = 7;
@ -1359,8 +1338,8 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(address < 0x10000) if(address < 0x10000)
address += 0x8000; address += 0x8000;
} else { } else {
xxx++; ++xxx;
address++; ++address;
if(xxx == 8) { if(xxx == 8) {
address += 56; address += 56;
xxx = 0; xxx = 0;
@ -1389,9 +1368,10 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
// int palette = (a2 >> 8) & 0xF0; // int palette = (a2 >> 8) & 0xF0;
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx = 7; xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) { int xx = sizeX - 1;
if (xx >= startpix) do{
lineOBJpix--; if (xx >= (int)(startpix))
--lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
@ -1406,26 +1386,27 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} }
sx = (sx+1) & 511; sx = (sx+1) & 511;
xxx--; --xxx;
if(!(xx & 1)) if(!(xx & 1))
address--; --address;
if(xxx == -1) { if(xxx == -1) {
xxx = 7; xxx = 7;
address -= 28; address -= 28;
} }
if(address < 0x10000) if(address < 0x10000)
address += 0x8000; address += 0x8000;
} --xx;
}while(xx >= 0);
} else { } else {
for(int xx = 0; xx < sizeX; xx++) { for(u32 xx = 0; xx < sizeX; ++xx) {
if (xx >= startpix) if (xx >= startpix)
lineOBJpix--; --lineOBJpix;
if (lineOBJpix<0) if (lineOBJpix<0)
continue; continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
color = (color >> 4); color >>= 4;
} else } else
color &= 0x0F; color &= 0x0F;
@ -1434,9 +1415,9 @@ static inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} }
sx = (sx+1) & 511; sx = (sx+1) & 511;
xxx++; ++xxx;
if(xx & 1) if(xx & 1)
address++; ++address;
if(xxx == 8) { if(xxx == 8) {
address += 28; address += 28;
xxx = 0; xxx = 0;
@ -1458,7 +1439,7 @@ static inline u32 gfxIncreaseBrightness(u32 color, int coeff)
color &= 0xffff; color &= 0xffff;
color = ((color << 16) | color) & 0x3E07C1F; color = ((color << 16) | color) & 0x3E07C1F;
color = color + (((0x3E07C1F - color) * coeff) >> 4); color += (((0x3E07C1F - color) * coeff) >> 4);
color &= 0x3E07C1F; color &= 0x3E07C1F;
return (color >> 16) | color; return (color >> 16) | color;
@ -1466,15 +1447,16 @@ static inline u32 gfxIncreaseBrightness(u32 color, int coeff)
static inline void gfxIncreaseBrightness(u32 *line, int coeff) static inline void gfxIncreaseBrightness(u32 *line, int coeff)
{ {
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
u32 color = *line; u32 color = *line;
int r = (color & 0x1F); int r = (color & 0x1F);
int g = ((color >> 5) & 0x1F); int g = ((color >> 5) & 0x1F);
int b = ((color >> 10) & 0x1F); int b = ((color >> 10) & 0x1F);
r = r + (((31 - r) * coeff) >> 4); r += (((31 - r) * coeff) >> 4);
g = g + (((31 - g) * coeff) >> 4); g += (((31 - g) * coeff) >> 4);
b = b + (((31 - b) * coeff) >> 4); b += (((31 - b) * coeff) >> 4);
if(r > 31) if(r > 31)
r = 31; r = 31;
if(g > 31) if(g > 31)
@ -1490,22 +1472,22 @@ static inline u32 gfxDecreaseBrightness(u32 color, int coeff)
color &= 0xffff; color &= 0xffff;
color = ((color << 16) | color) & 0x3E07C1F; color = ((color << 16) | color) & 0x3E07C1F;
color = color - (((color * coeff) >> 4) & 0x3E07C1F); color -= (((color * coeff) >> 4) & 0x3E07C1F);
return (color >> 16) | color; return (color >> 16) | color;
} }
static inline void gfxDecreaseBrightness(u32 *line, int coeff) static inline void gfxDecreaseBrightness(u32 *line, int coeff)
{ {
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
u32 color = *line; u32 color = *line;
int r = (color & 0x1F); int r = (color & 0x1F);
int g = ((color >> 5) & 0x1F); int g = ((color >> 5) & 0x1F);
int b = ((color >> 10) & 0x1F); int b = ((color >> 10) & 0x1F);
r = r - ((r * coeff) >> 4); r -= ((r * coeff) >> 4);
g = g - ((g * coeff) >> 4); g -= ((g * coeff) >> 4);
b = b - ((b * coeff) >> 4); b -= ((b * coeff) >> 4);
if(r < 0) if(r < 0)
r = 0; r = 0;
if(g < 0) if(g < 0)
@ -1544,7 +1526,7 @@ static inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb) static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
{ {
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
u32 color = *ta; u32 color = *ta;
if(color < 0x80000000) { if(color < 0x80000000) {
int r = (color & 0x1F); int r = (color & 0x1F);
@ -1568,8 +1550,8 @@ static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
*ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
} else { } else {
ta++; ++ta;
tb++; ++tb;
} }
} }
} }