From 7219f883825deeba8575078cecce599d1f7b019b Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 28 Jul 2009 04:47:06 +0000 Subject: [PATCH] win32: change osd compositing to 32bpp and decouple from emulation update; add nearest2x resizing filter; add framerate-independent drawing equipment to osd (test in savestate slot display); make lua drawing thread-safe once again; get rid of some warnings --- desmume/src/GPU_osd.cpp | 31 +- desmume/src/MMU.cpp | 8 +- desmume/src/NDSSystem.h | 3 + desmume/src/agg2d.h | 1087 ++++++++++++----------- desmume/src/agg2d.inl | 144 +-- desmume/src/aggdraw.cpp | 136 +-- desmume/src/aggdraw.h | 195 ++++ desmume/src/commandline.cpp | 15 +- desmume/src/commandline.h | 8 +- desmume/src/saves.cpp | 2 +- desmume/src/wifi.cpp | 14 +- desmume/src/windows/DeSmuME_2005.vcproj | 4 + desmume/src/windows/filter/filter.h | 20 + desmume/src/windows/filter/scanline.cpp | 63 +- desmume/src/windows/main.cpp | 190 ++-- desmume/src/windows/resource.h | 1 + desmume/src/windows/resources.rc | Bin 686088 -> 686208 bytes desmume/src/windows/video.h | 7 +- 18 files changed, 1085 insertions(+), 843 deletions(-) diff --git a/desmume/src/GPU_osd.cpp b/desmume/src/GPU_osd.cpp index 08a7881d9..a32deb621 100644 --- a/desmume/src/GPU_osd.cpp +++ b/desmume/src/GPU_osd.cpp @@ -36,11 +36,15 @@ #include "NDSSystem.h" #include "mic.h" #include "saves.h" +#include "glib.h" bool HudEditorMode = false; OSDCLASS *osd = NULL; HudStruct Hud; +//contains a timer to be used for well-timed hud components +static s64 hudTimer; + static void SetHudDummy (HudCoordinates *hud) { hud->x=666; @@ -177,16 +181,19 @@ static void TouchDisplay() { } static int previousslot = 0; -static int fadecounter; static char number[10]; +static s64 slotTimer=0; static void DrawStateSlots(){ const int yloc = Hud.SavestateSlots.y; //160 const int xloc = Hud.SavestateSlots.x; //8 + s64 fadecounter = 512 - (hudTimer-slotTimer)/4; //change constant to alter fade speed + if(fadecounter < 1) fadecounter = 0; + if(fadecounter>255) fadecounter = 255; - int alpha = fadecounter; + int alpha = (int)fadecounter; if(HudEditorMode) alpha = 255; @@ -214,17 +221,19 @@ static void DrawStateSlots(){ } } - if(lastSaveState != previousslot) fadecounter = 256; - previousslot = lastSaveState; - fadecounter--; + if(lastSaveState != previousslot) + slotTimer = hudTimer; - if(fadecounter < 1) fadecounter = 0; + previousslot = lastSaveState; } -#ifdef WIN32 -#include "lua-engine.h" -#endif + void DrawHUD() { + GTimeVal time; + g_get_current_time(&time); + hudTimer = ((s64)time.tv_sec * 1000) + ((s64)time.tv_usec/1000); + + if (CommonSettings.hud.ShowInputDisplay) { std::stringstream ss; @@ -260,9 +269,7 @@ void DrawHUD() osd->addFixed(Hud.Microphone.x, Hud.Microphone.y, "%d",MicDisplay); } #endif -#ifdef WIN32 - CallRegisteredLuaFunctions(LUACALL_AFTEREMULATIONGUI); -#endif + DrawStateSlots(); } diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 129213939..041f02131 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -2087,7 +2087,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) MMU.AUX_SPI_CMD = val & 0xFF; //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command(val)); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val)); return; case REG_DISPA_BG0CNT : @@ -3025,7 +3025,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) MMU.AUX_SPI_CMD = val & 0xFF; //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command(val)); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val)); return; case REG_SPICNT : @@ -3082,7 +3082,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) } else { - MMU.powerMan_Reg[MMU.powerMan_CntReg & 0x3] = val; + MMU.powerMan_Reg[MMU.powerMan_CntReg & 0x3] = (u8)val; } MMU.powerMan_CntRegWritten = FALSE; @@ -3096,7 +3096,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0); break; } - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, val)); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, (u8)val)); return; case 2 : diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 883889275..8979ede86 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -386,6 +386,7 @@ extern struct TCommonSettings { , spuAdpcmCache(false) , gfx3d_flushMode(0) , manualBackupType(0) + , single_core(true) { strcpy(ARM9BIOS, "biosnds9.bin"); strcpy(ARM7BIOS, "biosnds7.bin"); @@ -405,6 +406,8 @@ extern struct TCommonSettings { bool BootFromFirmware; bool DebugConsole; + + bool single_core; int wifiBridgeAdapterNum; diff --git a/desmume/src/agg2d.h b/desmume/src/agg2d.h index 24c89b6d5..e3d414802 100644 --- a/desmume/src/agg2d.h +++ b/desmume/src/agg2d.h @@ -91,173 +91,174 @@ #define TIMAGE Agg2DBase :: Image AGG2D_IMAGE_TEMPLATE_ARG -template +template class PixFormatSetDeclaration { public: typedef Main PixFormat; typedef Pre PixFormatPre; + typedef SG SpanGenerator; }; class Agg2DBase { public: - // JME - //typedef agg::rect Rect; - typedef agg::rect_i Rect; - typedef agg::rect_d RectD; - typedef agg::trans_affine Affine; + // JME + //typedef agg::rect Rect; + typedef agg::rect_i Rect; + typedef agg::rect_d RectD; + typedef agg::trans_affine Affine; - enum LineJoin - { - JOIN_MITER = agg::miter_join, - JOIN_ROUND = agg::round_join, - JOIN_BEVEL = agg::bevel_join - }; + enum LineJoin + { + JOIN_MITER = agg::miter_join, + JOIN_ROUND = agg::round_join, + JOIN_BEVEL = agg::bevel_join + }; - enum LineCap - { - CAP_BUTT = agg::butt_cap, - CAP_SQUARE = agg::square_cap, - CAP_ROUND = agg::round_cap - }; + enum LineCap + { + CAP_BUTT = agg::butt_cap, + CAP_SQUARE = agg::square_cap, + CAP_ROUND = agg::round_cap + }; - enum TextAlignment - { - AlignLeft, - AlignRight, - AlignCenter, - AlignBaseline, - AlignTop = AlignRight, - AlignBottom = AlignLeft - }; + enum TextAlignment + { + AlignLeft, + AlignRight, + AlignCenter, + AlignBaseline, + AlignTop = AlignRight, + AlignBottom = AlignLeft + }; - enum DrawPathFlag - { - FillOnly, - StrokeOnly, - FillAndStroke, - FillWithLineColor - }; + enum DrawPathFlag + { + FillOnly, + StrokeOnly, + FillAndStroke, + FillWithLineColor + }; - enum ViewportOption - { - Anisotropic, - XMinYMin, - XMidYMin, - XMaxYMin, - XMinYMid, - XMidYMid, - XMaxYMid, - XMinYMax, - XMidYMax, - XMaxYMax - }; + enum ViewportOption + { + Anisotropic, + XMinYMin, + XMidYMin, + XMaxYMin, + XMinYMid, + XMidYMid, + XMaxYMid, + XMinYMax, + XMidYMax, + XMaxYMax + }; - enum WindowFitLogic - { - WindowFitLogic_meet, - WindowFitLogic_slice - }; + enum WindowFitLogic + { + WindowFitLogic_meet, + WindowFitLogic_slice + }; - struct Transformations - { - double affineMatrix[6]; - }; + struct Transformations + { + double affineMatrix[6]; + }; - AGG2D_IMAGE_TEMPLATE struct Image - { - agg::rendering_buffer renBuf; + AGG2D_IMAGE_TEMPLATE struct Image + { + agg::rendering_buffer renBuf; Image(const agg::rendering_buffer& srcBuf) : renBuf(srcBuf) {} - Image(unsigned char* buf, unsigned width, unsigned height, int stride) : - renBuf(buf, width, height, stride) {} - void attach(unsigned char* buf, unsigned width, unsigned height, int stride) - { - renBuf.attach(buf, width, height, stride); - } - int width() const { return renBuf.width(); } - int height() const { return renBuf.height(); } - + Image(unsigned char* buf, unsigned width, unsigned height, int stride) : + renBuf(buf, width, height, stride) {} + void attach(unsigned char* buf, unsigned width, unsigned height, int stride) + { + renBuf.attach(buf, width, height, stride); + } + int width() const { return renBuf.width(); } + int height() const { return renBuf.height(); } + AGG2D_TEMPLATE void premultiply() { typename PixFormatSet::PixFormat pixf(renBuf); pixf.premultiply(); } - AGG2D_TEMPLATE void demultiply() + AGG2D_TEMPLATE void demultiply() { typename PixFormatSet::PixFormat pixf(renBuf); pixf.demultiply(); } - }; + }; - enum ImageFilter - { - NoFilter, - Bilinear, - Hanning, - Hermite, - Quadric, - Bicubic, - Catrom, - Spline16, - Spline36, - Blackman144 - }; + enum ImageFilter + { + NoFilter, + Bilinear, + Hanning, + Hermite, + Quadric, + Bicubic, + Catrom, + Spline16, + Spline36, + Blackman144 + }; - enum ImageResample - { - NoResample, - ResampleAlways, - ResampleOnZoomOut - }; + enum ImageResample + { + NoResample, + ResampleAlways, + ResampleOnZoomOut + }; - enum FontCacheType - { - RasterFontCache, - VectorFontCache - }; + enum FontCacheType + { + RasterFontCache, + VectorFontCache + }; - enum BlendMode - { - BlendAlpha = agg::end_of_comp_op_e, - BlendClear = agg::comp_op_clear, - BlendSrc = agg::comp_op_src, - BlendDst = agg::comp_op_dst, - BlendSrcOver = agg::comp_op_src_over, - BlendDstOver = agg::comp_op_dst_over, - BlendSrcIn = agg::comp_op_src_in, - BlendDstIn = agg::comp_op_dst_in, - BlendSrcOut = agg::comp_op_src_out, - BlendDstOut = agg::comp_op_dst_out, - BlendSrcAtop = agg::comp_op_src_atop, - BlendDstAtop = agg::comp_op_dst_atop, - BlendXor = agg::comp_op_xor, - BlendAdd = agg::comp_op_plus, - BlendSub = agg::comp_op_minus, - BlendMultiply = agg::comp_op_multiply, - BlendScreen = agg::comp_op_screen, - BlendOverlay = agg::comp_op_overlay, - BlendDarken = agg::comp_op_darken, - BlendLighten = agg::comp_op_lighten, - BlendColorDodge = agg::comp_op_color_dodge, - BlendColorBurn = agg::comp_op_color_burn, - BlendHardLight = agg::comp_op_hard_light, - BlendSoftLight = agg::comp_op_soft_light, - BlendDifference = agg::comp_op_difference, - BlendExclusion = agg::comp_op_exclusion, - BlendContrast = agg::comp_op_contrast - }; + enum BlendMode + { + BlendAlpha = agg::end_of_comp_op_e, + BlendClear = agg::comp_op_clear, + BlendSrc = agg::comp_op_src, + BlendDst = agg::comp_op_dst, + BlendSrcOver = agg::comp_op_src_over, + BlendDstOver = agg::comp_op_dst_over, + BlendSrcIn = agg::comp_op_src_in, + BlendDstIn = agg::comp_op_dst_in, + BlendSrcOut = agg::comp_op_src_out, + BlendDstOut = agg::comp_op_dst_out, + BlendSrcAtop = agg::comp_op_src_atop, + BlendDstAtop = agg::comp_op_dst_atop, + BlendXor = agg::comp_op_xor, + BlendAdd = agg::comp_op_plus, + BlendSub = agg::comp_op_minus, + BlendMultiply = agg::comp_op_multiply, + BlendScreen = agg::comp_op_screen, + BlendOverlay = agg::comp_op_overlay, + BlendDarken = agg::comp_op_darken, + BlendLighten = agg::comp_op_lighten, + BlendColorDodge = agg::comp_op_color_dodge, + BlendColorBurn = agg::comp_op_color_burn, + BlendHardLight = agg::comp_op_hard_light, + BlendSoftLight = agg::comp_op_soft_light, + BlendDifference = agg::comp_op_difference, + BlendExclusion = agg::comp_op_exclusion, + BlendContrast = agg::comp_op_contrast + }; - enum Direction - { - CW, CCW - }; + enum Direction + { + CW, CCW + }; }; @@ -268,341 +269,341 @@ template class Agg2D : public Agg2DBase public: typedef typename PixFormatSet::PixFormat PixFormat; typedef Image MyImage; - typedef agg::order_bgra ComponentOrder; // Platform dependent! + typedef agg::order_bgra ComponentOrder; // Platform dependent! - typedef agg::rgba8 ColorType; - typedef agg::blender_rgba Blender; - typedef agg::comp_op_adaptor_rgba BlenderComp; - typedef agg::blender_rgba_pre BlenderPre; - typedef agg::comp_op_adaptor_rgba_pre BlenderCompPre; + typedef agg::rgba8 ColorType; + typedef agg::blender_rgba Blender; + typedef agg::comp_op_adaptor_rgba BlenderComp; + typedef agg::blender_rgba_pre BlenderPre; + typedef agg::comp_op_adaptor_rgba_pre BlenderCompPre; // JME - //typedef agg::pixel_formats_rgba PixFormat; - //typedef agg::pixfmt_bgra32 PixFormat; - // JME - //typedef agg::pixfmt_custom_blend_rgba PixFormatComp; - typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + //typedef agg::pixel_formats_rgba PixFormat; + //typedef agg::pixfmt_bgra32 PixFormat; // JME - //typedef agg::pixel_formats_rgba PixFormatPre; + //typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + // JME + //typedef agg::pixel_formats_rgba PixFormatPre; typedef typename PixFormatSet::PixFormatPre PixFormatPre; - // JME - //typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; - typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; + // JME + //typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; + typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; - typedef agg::renderer_base RendererBase; - typedef agg::renderer_base RendererBaseComp; - typedef agg::renderer_base RendererBasePre; - typedef agg::renderer_base RendererBaseCompPre; + typedef agg::renderer_base RendererBase; + typedef agg::renderer_base RendererBaseComp; + typedef agg::renderer_base RendererBasePre; + typedef agg::renderer_base RendererBaseCompPre; - typedef agg::renderer_scanline_aa_solid RendererSolid; - typedef agg::renderer_scanline_aa_solid RendererSolidComp; + typedef agg::renderer_scanline_aa_solid RendererSolid; + typedef agg::renderer_scanline_aa_solid RendererSolidComp; - typedef agg::span_allocator SpanAllocator; - typedef agg::pod_auto_array GradientArray; + typedef agg::span_allocator SpanAllocator; + typedef agg::pod_auto_array GradientArray; - typedef agg::span_gradient, agg::gradient_x, GradientArray> LinearGradientSpan; - typedef agg::span_gradient, agg::gradient_circle, GradientArray> RadialGradientSpan; + typedef agg::span_gradient, agg::gradient_x, GradientArray> LinearGradientSpan; + typedef agg::span_gradient, agg::gradient_circle, GradientArray> RadialGradientSpan; #ifdef AGG2D_USE_VECTORFONTS #ifdef AGG2D_USE_FREETYPE - typedef agg::font_engine_freetype_int32 FontEngine; + typedef agg::font_engine_freetype_int32 FontEngine; #else - typedef agg::font_engine_win32_tt_int32 FontEngine; + typedef agg::font_engine_win32_tt_int32 FontEngine; #endif - typedef agg::font_cache_manager FontCacheManager; - typedef FontCacheManager::gray8_adaptor_type FontRasterizer; - typedef FontCacheManager::gray8_scanline_type FontScanline; + typedef agg::font_cache_manager FontCacheManager; + typedef FontCacheManager::gray8_adaptor_type FontRasterizer; + typedef FontCacheManager::gray8_scanline_type FontScanline; #endif - typedef agg::conv_curve ConvCurve; - typedef agg::conv_stroke ConvStroke; - typedef agg::conv_transform PathTransform; - typedef agg::conv_transform StrokeTransform; - enum Gradient - { - Solid, - Linear, - Radial - }; + typedef agg::conv_curve ConvCurve; + typedef agg::conv_stroke ConvStroke; + typedef agg::conv_transform PathTransform; + typedef agg::conv_transform StrokeTransform; + enum Gradient + { + Solid, + Linear, + Radial + }; public: template friend class Agg2DRenderer; - typedef ColorType Color; + typedef ColorType Color; - - struct State - { - RectD m_clipBox; - BlendMode m_blendMode; - BlendMode m_imageBlendMode; - Color m_imageBlendColor; + struct State + { + RectD m_clipBox; - double m_masterAlpha; - double m_antiAliasGamma; + BlendMode m_blendMode; + BlendMode m_imageBlendMode; + Color m_imageBlendColor; - const agg::int8u* m_font; + double m_masterAlpha; + double m_antiAliasGamma; - Color m_fillColor; - Color m_lineColor; - GradientArray m_fillGradient; - GradientArray m_lineGradient; + const agg::int8u* m_font; - LineCap m_lineCap; - LineJoin m_lineJoin; + Color m_fillColor; + Color m_lineColor; + GradientArray m_fillGradient; + GradientArray m_lineGradient; - Gradient m_fillGradientFlag; - Gradient m_lineGradientFlag; - agg::trans_affine m_fillGradientMatrix; - agg::trans_affine m_lineGradientMatrix; - double m_fillGradientD1; - double m_lineGradientD1; - double m_fillGradientD2; - double m_lineGradientD2; + LineCap m_lineCap; + LineJoin m_lineJoin; - double m_textAngle; - TextAlignment m_textAlignX; - TextAlignment m_textAlignY; - bool m_textHints; - double m_fontHeight; - double m_fontAscent; - double m_fontDescent; - FontCacheType m_fontCacheType; + Gradient m_fillGradientFlag; + Gradient m_lineGradientFlag; + agg::trans_affine m_fillGradientMatrix; + agg::trans_affine m_lineGradientMatrix; + double m_fillGradientD1; + double m_lineGradientD1; + double m_fillGradientD2; + double m_lineGradientD2; - double m_lineWidth; - bool m_evenOddFlag; + double m_textAngle; + TextAlignment m_textAlignX; + TextAlignment m_textAlignY; + bool m_textHints; + double m_fontHeight; + double m_fontAscent; + double m_fontDescent; + FontCacheType m_fontCacheType; - agg::trans_affine m_transform; - agg::trans_affine m_affine; + double m_lineWidth; + bool m_evenOddFlag; - }; + agg::trans_affine m_transform; + agg::trans_affine m_affine; + + }; - ~Agg2D(); - Agg2D(); + ~Agg2D(); + Agg2D(); - // Setup - //----------------------- - void attach(unsigned char* buf, unsigned width, unsigned height, int stride); - void attach(MyImage& img); + // Setup + //----------------------- + void attach(unsigned char* buf, unsigned width, unsigned height, int stride); + void attach(MyImage& img); - void clipBox(double x1, double y1, double x2, double y2); - RectD clipBox() const; + void clipBox(double x1, double y1, double x2, double y2); + RectD clipBox() const; - void clearAll(Color c); - void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void clearAll(Color c); + void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255); - void clearClipBox(Color c); - void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void clearClipBox(Color c); + void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255); - unsigned width() const { return m_rbuf.width(); } - unsigned height() const { return m_rbuf.height(); } + unsigned width() const { return m_rbuf.width(); } + unsigned height() const { return m_rbuf.height(); } unsigned stride() const { return m_rbuf.stride(); } - // Conversions - //----------------------- - void worldToScreen(double& x, double& y) const; - void screenToWorld(double& x, double& y) const; - double worldToScreen(double scalar) const; - double screenToWorld(double scalar) const; - void alignPoint(double& x, double& y) const; - bool inBox(double worldX, double worldY) const; + // Conversions + //----------------------- + void worldToScreen(double& x, double& y) const; + void screenToWorld(double& x, double& y) const; + double worldToScreen(double scalar) const; + double screenToWorld(double scalar) const; + void alignPoint(double& x, double& y) const; + bool inBox(double worldX, double worldY) const; - // General Attributes - //----------------------- - void blendMode(BlendMode m); - BlendMode blendMode() const; + // General Attributes + //----------------------- + void blendMode(BlendMode m); + BlendMode blendMode() const; - void imageBlendMode(BlendMode m); - BlendMode imageBlendMode() const; + void imageBlendMode(BlendMode m); + BlendMode imageBlendMode() const; - void imageBlendColor(Color c); - void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); - Color imageBlendColor() const; + void imageBlendColor(Color c); + void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + Color imageBlendColor() const; - void masterAlpha(double a); - double masterAlpha() const; + void masterAlpha(double a); + double masterAlpha() const; - void antiAliasGamma(double g); - double antiAliasGamma() const; + void antiAliasGamma(double g); + double antiAliasGamma() const; void font(const agg::int8u* font) { m_font = font; } const agg::int8u* font() { return m_font; } - void fillColor(Color c); - void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); - void noFill(); + void fillColor(Color c); + void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void noFill(); - void lineColor(Color c); - void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); - void noLine(); + void lineColor(Color c); + void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void noLine(); - Color fillColor() const; - Color lineColor() const; + Color fillColor() const; + Color lineColor() const; - void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); - void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); + void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); + void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); - void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); - void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); + void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); + void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); - void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); - void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); + void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); + void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); - void fillRadialGradient(double x, double y, double r); - void lineRadialGradient(double x, double y, double r); + void fillRadialGradient(double x, double y, double r); + void lineRadialGradient(double x, double y, double r); - void lineWidth(double w); - double lineWidth() const; + void lineWidth(double w); + double lineWidth() const; - void lineCap(LineCap cap); - LineCap lineCap() const; + void lineCap(LineCap cap); + LineCap lineCap() const; - void lineJoin(LineJoin join); - LineJoin lineJoin() const; + void lineJoin(LineJoin join); + LineJoin lineJoin() const; - void fillEvenOdd(bool evenOddFlag); - bool fillEvenOdd() const; + void fillEvenOdd(bool evenOddFlag); + bool fillEvenOdd() const; - // Transformations - //----------------------- - Transformations transformations() const; - void transformations(const Transformations& tr); + // Transformations + //----------------------- + Transformations transformations() const; + void transformations(const Transformations& tr); - const Affine& affine() const; - void affine(const Affine&); + const Affine& affine() const; + void affine(const Affine&); - void resetTransformations(); - void matrix(const Affine& tr); - void matrix(const Transformations& tr); - void rotate(double angle); - void rotate(double angle, double cx, double cy); - void scale(double s); - void scale(double sx, double sy); - void skew(double sx, double sy); - void translate(double x, double y); - void parallelogram(double x1, double y1, double x2, double y2, const double* para); - void viewport(double worldX1, double worldY1, double worldX2, double worldY2, - double screenX1, double screenY1, double screenX2, double screenY2, - ViewportOption opt=XMidYMid, WindowFitLogic fl = WindowFitLogic_meet); + void resetTransformations(); + void matrix(const Affine& tr); + void matrix(const Transformations& tr); + void rotate(double angle); + void rotate(double angle, double cx, double cy); + void scale(double s); + void scale(double sx, double sy); + void skew(double sx, double sy); + void translate(double x, double y); + void parallelogram(double x1, double y1, double x2, double y2, const double* para); + void viewport(double worldX1, double worldY1, double worldX2, double worldY2, + double screenX1, double screenY1, double screenX2, double screenY2, + ViewportOption opt=XMidYMid, WindowFitLogic fl = WindowFitLogic_meet); - // Basic Shapes - //----------------------- - void line(double x1, double y1, double x2, double y2); - void triangle(double x1, double y1, double x2, double y2, double x3, double y3); - void rectangle(double x1, double y1, double x2, double y2); - void roundedRect(double x1, double y1, double x2, double y2, double r); - void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry); - void roundedRect(double x1, double y1, double x2, double y2, - double rxBottom, double ryBottom, - double rxTop, double ryTop); - void ellipse(double cx, double cy, double rx, double ry); - void arc(double cx, double cy, double rx, double ry, double start, double sweep); - void star(double cx, double cy, double r1, double r2, double startAngle, int numRays); - void curve(double x1, double y1, double x2, double y2, double x3, double y3); - void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); - void polygon(double* xy, int numPoints); - void polyline(double* xy, int numPoints); + // Basic Shapes + //----------------------- + void line(double x1, double y1, double x2, double y2); + void triangle(double x1, double y1, double x2, double y2, double x3, double y3); + void rectangle(double x1, double y1, double x2, double y2); + void roundedRect(double x1, double y1, double x2, double y2, double r); + void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry); + void roundedRect(double x1, double y1, double x2, double y2, + double rxBottom, double ryBottom, + double rxTop, double ryTop); + void ellipse(double cx, double cy, double rx, double ry); + void arc(double cx, double cy, double rx, double ry, double start, double sweep); + void star(double cx, double cy, double r1, double r2, double startAngle, int numRays); + void curve(double x1, double y1, double x2, double y2, double x3, double y3); + void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); + void polygon(double* xy, int numPoints); + void polyline(double* xy, int numPoints); - // Text - //----------------------- - #ifdef AGG2D_USE_VECTORFONTS - void flipText(bool flip); - void font(const char* fileName, double height, - bool bold = false, - bool italic = false, - FontCacheType ch = RasterFontCache, - double angle = 0.0); - double fontHeight() const; - double fontAscent() const; + // Text + //----------------------- +#ifdef AGG2D_USE_VECTORFONTS + void flipText(bool flip); + void font(const char* fileName, double height, + bool bold = false, + bool italic = false, + FontCacheType ch = RasterFontCache, + double angle = 0.0); + double fontHeight() const; + double fontAscent() const; - void textAlignment(TextAlignment alignX, TextAlignment alignY); - bool textHints() const; - void textHints(bool hints); - double textWidth(const char* str, unsigned int len); - double textWidth(const wchar_t* str, unsigned int len); - void text(double x, double y, const char* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); - void text(double x, double y, const wchar_t* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); + void textAlignment(TextAlignment alignX, TextAlignment alignY); + bool textHints() const; + void textHints(bool hints); + double textWidth(const char* str, unsigned int len); + double textWidth(const wchar_t* str, unsigned int len); + void text(double x, double y, const char* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); + void text(double x, double y, const wchar_t* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); - double textWidth(const char* str); - void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0); - #endif + double textWidth(const char* str); + void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0); +#endif - // Path commands - //----------------------- - void resetPath(); + // Path commands + //----------------------- + void resetPath(); - void moveTo(double x, double y); - void moveRel(double dx, double dy); + void moveTo(double x, double y); + void moveRel(double dx, double dy); - void lineTo(double x, double y); - void lineRel(double dx, double dy); + void lineTo(double x, double y); + void lineRel(double dx, double dy); - void horLineTo(double x); - void horLineRel(double dx); + void horLineTo(double x); + void horLineRel(double dx); - void verLineTo(double y); - void verLineRel(double dy); + void verLineTo(double y); + void verLineRel(double dy); - void arcTo(double rx, double ry, - double angle, - bool largeArcFlag, - bool sweepFlag, - double x, double y); + void arcTo(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double x, double y); - void arcRel(double rx, double ry, - double angle, - bool largeArcFlag, - bool sweepFlag, - double dx, double dy); + void arcRel(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double dx, double dy); - void quadricCurveTo(double xCtrl, double yCtrl, - double xTo, double yTo); - void quadricCurveRel(double dxCtrl, double dyCtrl, - double dxTo, double dyTo); - void quadricCurveTo(double xTo, double yTo); - void quadricCurveRel(double dxTo, double dyTo); + void quadricCurveTo(double xCtrl, double yCtrl, + double xTo, double yTo); + void quadricCurveRel(double dxCtrl, double dyCtrl, + double dxTo, double dyTo); + void quadricCurveTo(double xTo, double yTo); + void quadricCurveRel(double dxTo, double dyTo); - void cubicCurveTo(double xCtrl1, double yCtrl1, - double xCtrl2, double yCtrl2, - double xTo, double yTo); + void cubicCurveTo(double xCtrl1, double yCtrl1, + double xCtrl2, double yCtrl2, + double xTo, double yTo); - void cubicCurveRel(double dxCtrl1, double dyCtrl1, - double dxCtrl2, double dyCtrl2, - double dxTo, double dyTo); + void cubicCurveRel(double dxCtrl1, double dyCtrl1, + double dxCtrl2, double dyCtrl2, + double dxTo, double dyTo); - void cubicCurveTo(double xCtrl2, double yCtrl2, - double xTo, double yTo); + void cubicCurveTo(double xCtrl2, double yCtrl2, + double xTo, double yTo); - void cubicCurveRel(double xCtrl2, double yCtrl2, - double xTo, double yTo); + void cubicCurveRel(double xCtrl2, double yCtrl2, + double xTo, double yTo); - void addEllipse(double cx, double cy, double rx, double ry, Direction dir); - void closePolygon(); + void addEllipse(double cx, double cy, double rx, double ry, Direction dir); + void closePolygon(); - void drawPath(DrawPathFlag flag = FillAndStroke); - void drawPathNoTransform(DrawPathFlag flag = FillAndStroke); + void drawPath(DrawPathFlag flag = FillAndStroke); + void drawPathNoTransform(DrawPathFlag flag = FillAndStroke); - // Image Transformations - //----------------------- - void imageFilter(ImageFilter f); - ImageFilter imageFilter() const; + // Image Transformations + //----------------------- + void imageFilter(ImageFilter f); + ImageFilter imageFilter() const; - void imageResample(ImageResample f); - ImageResample imageResample() const; + void imageResample(ImageResample f); + ImageResample imageResample() const; //--------- //if anyone can figure out how to put these in the .inl file, theyre more than welcome to. I couldnt declare them correctly to match //the .h file declaration - AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - double dstX1, double dstY1, double dstX2, double dstY2) + AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) { resetPath(); moveTo(dstX1, dstY1); @@ -614,8 +615,8 @@ public: renderImage (img, imgX1, imgY1, imgX2, imgY2, parallelogram); } - AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, - double dstX1, double dstY1, double dstX2, double dstY2) + AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, + double dstX1, double dstY1, double dstX2, double dstY2) { resetPath(); moveTo(dstX1, dstY1); @@ -628,90 +629,90 @@ public: } - AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - const double* parallelogram) + AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) { resetPath(); moveTo(parallelogram[0], parallelogram[1]); lineTo(parallelogram[2], parallelogram[3]); lineTo(parallelogram[4], parallelogram[5]); lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], - parallelogram[1] + parallelogram[5] - parallelogram[3]); + parallelogram[1] + parallelogram[5] - parallelogram[3]); closePolygon(); renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); } - AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, const double* parallelogram) -{ - resetPath(); - moveTo(parallelogram[0], parallelogram[1]); - lineTo(parallelogram[2], parallelogram[3]); - lineTo(parallelogram[4], parallelogram[5]); - lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], - parallelogram[1] + parallelogram[5] - parallelogram[3]); - closePolygon(); - renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); -} - - - - AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - double dstX1, double dstY1, double dstX2, double dstY2) - { - double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; - renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); -} - - - AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, - double dstX1, double dstY1, double dstX2, double dstY2) -{ - double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; - renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); -} - - - - AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - const double* parallelogram) + AGG2D_IMAGE_TEMPLATE void transformImage(const TIMAGE& img, const double* parallelogram) { - renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); -} - - - AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, const double* parallelogram) -{ - renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); -} + resetPath(); + moveTo(parallelogram[0], parallelogram[1]); + lineTo(parallelogram[2], parallelogram[3]); + lineTo(parallelogram[4], parallelogram[5]); + lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], + parallelogram[1] + parallelogram[5] - parallelogram[3]); + closePolygon(); + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); + } - // Image Blending (no transformations available) - AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - double dstX, double dstY, unsigned alpha=255) -{ - worldToScreen(dstX, dstY); - PixFormat pixF(img.renBuf); - // JME - //agg::rect r(imgX1, imgY1, imgX2, imgY2); - Rect r(imgX1, imgY1, imgX2, imgY2); - if(m_blendMode == BlendAlpha) - { - m_renBasePre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); - } - else - { - m_renBaseCompPre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); - } -} + AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) + { + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); + } - - void renderText(double dstX, double dstY, const std::string& str) + + AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, + double dstX1, double dstY1, double dstX2, double dstY2) + { + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); + } + + + + AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) + { + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); + } + + + AGG2D_IMAGE_TEMPLATE void transformImagePath(const TIMAGE& img, const double* parallelogram) + { + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); + } + + + + // Image Blending (no transformations available) + AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY, unsigned alpha=255) + { + worldToScreen(dstX, dstY); + PixFormat pixF(img.renBuf); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + if(m_blendMode == BlendAlpha) + { + m_renBasePre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } + else + { + m_renBaseCompPre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } + } + + + void renderText(double dstX, double dstY, const std::string& str) { worldToScreen(dstX, dstY); PixFormat pixF(m_rbuf); @@ -739,7 +740,7 @@ public: } - AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img, double dstX, double dstY, unsigned alpha=255) + AGG2D_IMAGE_TEMPLATE void blendImage(TIMAGE& img, double dstX, double dstY, unsigned alpha=255) { worldToScreen(dstX, dstY); PixFormat pixF(img.renBuf); @@ -756,59 +757,59 @@ public: - // Copy image directly, together with alpha-channel - AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img, - int imgX1, int imgY1, int imgX2, int imgY2, - double dstX, double dstY) -{ - worldToScreen(dstX, dstY); - // JME - //agg::rect r(imgX1, imgY1, imgX2, imgY2); - Rect r(imgX1, imgY1, imgX2, imgY2); - m_renBase.copy_from(img.renBuf, &r, int(dstX)-imgX1, int(dstY)-imgY1); -} + // Copy image directly, together with alpha-channel + AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY) + { + worldToScreen(dstX, dstY); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + m_renBase.copy_from(img.renBuf, &r, int(dstX)-imgX1, int(dstY)-imgY1); + } - AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img, double dstX, double dstY) -{ - worldToScreen(dstX, dstY); - m_renBase.copy_from(img.renBuf, 0, int(dstX), int(dstY)); -} + AGG2D_IMAGE_TEMPLATE void copyImage(TIMAGE& img, double dstX, double dstY) + { + worldToScreen(dstX, dstY); + m_renBase.copy_from(img.renBuf, 0, int(dstX), int(dstY)); + } - // State - //----------------------- + // State + //----------------------- - void saveStateTo(State& st); - void restoreStateFrom(const State& st); + void saveStateTo(State& st); + void restoreStateFrom(const State& st); - // Auxiliary - //----------------------- - static double pi() { return agg::pi; } - static double deg2Rad(double v) { return v * agg::pi / 180.0; } - static double rad2Deg(double v) { return v * 180.0 / agg::pi; } + // Auxiliary + //----------------------- + static double pi() { return agg::pi; } + static double deg2Rad(double v) { return v * agg::pi / 180.0; } + static double rad2Deg(double v) { return v * 180.0 / agg::pi; } PixFormat & pixFormat() { return m_pixFormat; } agg::rendering_buffer & buf() { return m_rbuf; } private: - void render(bool fillColor); + void render(bool fillColor); #ifdef AGG2D_USE_VECTORFONTS #if !defined( UNDER_CE ) - void render(FontRasterizer& ras, FontScanline& sl); + void render(FontRasterizer& ras, FontScanline& sl); #endif #endif - void addLine(double x1, double y1, double x2, double y2); - void updateRasterizerGamma(); - AGG2D_IMAGE_TEMPLATE void renderImage(const TIMAGE& img, int x1, int y1, int x2, int y2, const double* parl) + void addLine(double x1, double y1, double x2, double y2); + void updateRasterizerGamma(); + AGG2D_IMAGE_TEMPLATE void renderImage(const TIMAGE& img, int x1, int y1, int x2, int y2, const double* parl) { agg::trans_affine mtx((double)x1, - (double)y1, - (double)x2, - (double)y2, - parl); + (double)y1, + (double)x2, + (double)y2, + parl); mtx *= m_transform; mtx.invert(); @@ -830,95 +831,95 @@ private: } - void updateTransformations(); + void updateTransformations(); - agg::rendering_buffer m_rbuf; - PixFormat m_pixFormat; - PixFormatComp m_pixFormatComp; - PixFormatPre m_pixFormatPre; - PixFormatCompPre m_pixFormatCompPre; - RendererBase m_renBase; - RendererBaseComp m_renBaseComp; - RendererBasePre m_renBasePre; - RendererBaseCompPre m_renBaseCompPre; - RendererSolid m_renSolid; - RendererSolidComp m_renSolidComp; + agg::rendering_buffer m_rbuf; + PixFormat m_pixFormat; + PixFormatComp m_pixFormatComp; + PixFormatPre m_pixFormatPre; + PixFormatCompPre m_pixFormatCompPre; + RendererBase m_renBase; + RendererBaseComp m_renBaseComp; + RendererBasePre m_renBasePre; + RendererBaseCompPre m_renBaseCompPre; + RendererSolid m_renSolid; + RendererSolidComp m_renSolidComp; - SpanAllocator m_allocator; - RectD m_clipBox; + SpanAllocator m_allocator; + RectD m_clipBox; - BlendMode m_blendMode; - BlendMode m_imageBlendMode; - Color m_imageBlendColor; + BlendMode m_blendMode; + BlendMode m_imageBlendMode; + Color m_imageBlendColor; - agg::scanline_u8 m_scanline; - agg::rasterizer_scanline_aa<> m_rasterizer; + agg::scanline_u8 m_scanline; + agg::rasterizer_scanline_aa<> m_rasterizer; - double m_masterAlpha; - double m_antiAliasGamma; + double m_masterAlpha; + double m_antiAliasGamma; - const agg::int8u* m_font; + const agg::int8u* m_font; - Color m_fillColor; - Color m_lineColor; - GradientArray m_fillGradient; - GradientArray m_lineGradient; + Color m_fillColor; + Color m_lineColor; + GradientArray m_fillGradient; + GradientArray m_lineGradient; - LineCap m_lineCap; - LineJoin m_lineJoin; + LineCap m_lineCap; + LineJoin m_lineJoin; - Gradient m_fillGradientFlag; - Gradient m_lineGradientFlag; - agg::trans_affine m_fillGradientMatrix; - agg::trans_affine m_lineGradientMatrix; - double m_fillGradientD1; - double m_lineGradientD1; - double m_fillGradientD2; - double m_lineGradientD2; + Gradient m_fillGradientFlag; + Gradient m_lineGradientFlag; + agg::trans_affine m_fillGradientMatrix; + agg::trans_affine m_lineGradientMatrix; + double m_fillGradientD1; + double m_lineGradientD1; + double m_fillGradientD2; + double m_lineGradientD2; - double m_textAngle; - TextAlignment m_textAlignX; - TextAlignment m_textAlignY; - bool m_textHints; - double m_fontHeight; - double m_fontAscent; - double m_fontDescent; - FontCacheType m_fontCacheType; + double m_textAngle; + TextAlignment m_textAlignX; + TextAlignment m_textAlignY; + bool m_textHints; + double m_fontHeight; + double m_fontAscent; + double m_fontDescent; + FontCacheType m_fontCacheType; - ImageFilter m_imageFilter; - ImageResample m_imageResample; - agg::image_filter_lut m_imageFilterLut; + ImageFilter m_imageFilter; + ImageResample m_imageResample; + agg::image_filter_lut m_imageFilterLut; - agg::span_interpolator_linear<> m_fillGradientInterpolator; - agg::span_interpolator_linear<> m_lineGradientInterpolator; + agg::span_interpolator_linear<> m_fillGradientInterpolator; + agg::span_interpolator_linear<> m_lineGradientInterpolator; - agg::gradient_x m_linearGradientFunction; - agg::gradient_circle m_radialGradientFunction; + agg::gradient_x m_linearGradientFunction; + agg::gradient_circle m_radialGradientFunction; - double m_lineWidth; - bool m_evenOddFlag; + double m_lineWidth; + bool m_evenOddFlag; - double m_start_x; - double m_start_y; + double m_start_x; + double m_start_y; - agg::path_storage m_path; - agg::trans_affine m_transform; + agg::path_storage m_path; + agg::trans_affine m_transform; - agg::trans_affine m_viewport; - agg::trans_affine m_affine; + agg::trans_affine m_viewport; + agg::trans_affine m_affine; - ConvCurve m_convCurve; - ConvStroke m_convStroke; + ConvCurve m_convCurve; + ConvStroke m_convStroke; - PathTransform m_pathTransform; - StrokeTransform m_strokeTransform; + PathTransform m_pathTransform; + StrokeTransform m_strokeTransform; #ifdef AGG2D_USE_VECTORFONTS #ifndef AGG2D_USE_FREETYPE - HDC m_fontDC; + HDC m_fontDC; #endif - FontEngine m_fontEngine; - FontCacheManager m_fontCacheManager; + FontEngine m_fontEngine; + FontCacheManager m_fontCacheManager; #endif }; diff --git a/desmume/src/agg2d.inl b/desmume/src/agg2d.inl index d4b7c51bc..756d193b9 100644 --- a/desmume/src/agg2d.inl +++ b/desmume/src/agg2d.inl @@ -98,8 +98,8 @@ AGG2D_TEMPLATE inline TAGG2D::Agg2D() : m_fontDescent(0.0), m_fontCacheType(RasterFontCache), - m_imageFilter(Bilinear), //less quality more speed - //m_imageFilter(NoFilter), + //m_imageFilter(Bilinear), //less quality more speed + m_imageFilter(NoFilter), m_imageResample(NoResample), m_imageFilterLut(agg::image_filter_bilinear(), true), @@ -257,8 +257,8 @@ AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::attach(unsigned char* buf, unsign textAlignment(AlignLeft, AlignBottom); flipText(false); #endif - imageFilter(Bilinear); //less quality more speed - //imageFilter(NoFilter); + //imageFilter(Bilinear); //less quality more speed + imageFilter(NoFilter); imageResample(NoResample); m_masterAlpha = 1.0; m_antiAliasGamma = 1.0; @@ -1841,83 +1841,85 @@ public: SpanConvImageBlend blend(gr.m_imageBlendMode, gr.m_imageBlendColor); if(gr.m_imageFilter == TAGG2D::NoFilter) { - - //modifications less quality more speed - + //original way typedef agg::span_image_filter_rgba_nn SpanGenType; - //typedef agg::span_converter SpanConvType; typedef agg::renderer_scanline_aa RendererType; - //typedef agg::renderer_scanline_bin RendererType; - SpanGenType sg(source,interpolator); - //SpanConvType sc(sg, blend); RendererType ri(renBase,gr.m_allocator,sg); agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + + //our way, using our own span generator to support 555 + //but, it isnt working yet + //typedef ImagePixFormatSet::SpanGenerator SpanGenType; + //typedef agg::renderer_scanline_aa RendererType; + //SpanGenType sg(imgc.renBuf); + //RendererType ri(renBase,gr.m_allocator,sg); + //agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); } - else - { - bool resample = (gr.m_imageResample == TAGG2D::ResampleAlways); - if(gr.m_imageResample == TAGG2D::ResampleOnZoomOut) - { - double sx, sy; - interpolator.transformer().scaling_abs(&sx, &sy); - if (sx > 1.125 || sy > 1.125) - { - resample = true; - } - } + //else + // { + // bool resample = (gr.m_imageResample == TAGG2D::ResampleAlways); + // if(gr.m_imageResample == TAGG2D::ResampleOnZoomOut) + // { + // double sx, sy; + // interpolator.transformer().scaling_abs(&sx, &sy); + // if (sx > 1.125 || sy > 1.125) + // { + // resample = true; + // } + // } - if(resample) - { - typedef agg::span_image_resample_rgba_affine SpanGenType; - typedef agg::span_converter SpanConvType; - typedef agg::renderer_scanline_aa RendererType; + // if(resample) + // { + // typedef agg::span_image_resample_rgba_affine SpanGenType; + // typedef agg::span_converter SpanConvType; + // typedef agg::renderer_scanline_aa RendererType; - SpanGenType sg(source,interpolator,gr.m_imageFilterLut); - SpanConvType sc(sg, blend); - RendererType ri(renBase,gr.m_allocator,sg); - agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); - } - else - { - // this is the AGG2D default - if(gr.m_imageFilter == TAGG2D::Bilinear) - { - typedef agg::span_image_filter_rgba_bilinear SpanGenType; - typedef agg::span_converter SpanConvType; - typedef agg::renderer_scanline_aa RendererType; + // SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + // SpanConvType sc(sg, blend); + // RendererType ri(renBase,gr.m_allocator,sg); + // agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + // } + // else + // { + //// this is the AGG2D default + // if(gr.m_imageFilter == TAGG2D::Bilinear) + // { + // typedef agg::span_image_filter_rgba_bilinear SpanGenType; + // typedef agg::span_converter SpanConvType; + // typedef agg::renderer_scanline_aa RendererType; - SpanGenType sg(source,interpolator); - SpanConvType sc(sg, blend); - RendererType ri(renBase,gr.m_allocator,sg); - agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); - } - else - { - if(gr.m_imageFilterLut.diameter() == 2) - { - typedef agg::span_image_filter_rgba_2x2 SpanGenType; - typedef agg::span_converter SpanConvType; - typedef agg::renderer_scanline_aa RendererType; + // SpanGenType sg(source,interpolator); + // SpanConvType sc(sg, blend); + // RendererType ri(renBase,gr.m_allocator,sg); + // agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + // } + // else + // { + // if(gr.m_imageFilterLut.diameter() == 2) + // { + // typedef agg::span_image_filter_rgba_2x2 SpanGenType; + // typedef agg::span_converter SpanConvType; + // typedef agg::renderer_scanline_aa RendererType; - SpanGenType sg(source,interpolator,gr.m_imageFilterLut); - SpanConvType sc(sg, blend); - RendererType ri(renBase,gr.m_allocator,sg); - agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); - } - else - { - typedef agg::span_image_filter_rgba SpanGenType; - typedef agg::span_converter SpanConvType; - typedef agg::renderer_scanline_aa RendererType; - SpanGenType sg(source,interpolator,gr.m_imageFilterLut); - SpanConvType sc(sg, blend); - RendererType ri(renBase,gr.m_allocator,sg); - agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); - } - } - } - } + // SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + // SpanConvType sc(sg, blend); + // RendererType ri(renBase,gr.m_allocator,sg); + // agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + // } + // else + // { + // typedef agg::span_image_filter_rgba SpanGenType; + // typedef agg::span_converter SpanConvType; + // typedef agg::renderer_scanline_aa RendererType; + // SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + // SpanConvType sc(sg, blend); + // RendererType ri(renBase,gr.m_allocator,sg); + // agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + // } + // } + // } + // } } }; diff --git a/desmume/src/aggdraw.cpp b/desmume/src/aggdraw.cpp index e83be5986..af1072fd3 100644 --- a/desmume/src/aggdraw.cpp +++ b/desmume/src/aggdraw.cpp @@ -35,10 +35,6 @@ #include "agg_path_storage.h" #include "agg_color_rgba.h" -#include "agg_pixfmt_rgb.h" -#include "agg_pixfmt_rgba.h" -#include "agg_pixfmt_rgb_packed.h" - #include "agg_rasterizer_scanline_aa.h" #include "agg_scanline_u.h" #include "agg_renderer_scanline.h" @@ -63,98 +59,6 @@ #include "agg_span_allocator.h" -namespace agg -{ - //NOTE - these blenders are necessary to change the rgb order from the defaults, which are incorrect for us - - //this custom blender does more correct blending math than the default - //which is necessary or else drawing transparent pixels on (31,31,31) will yield (30,30,30) - struct my_blender_rgb555_pre - { - typedef rgba8 color_type; - typedef color_type::value_type value_type; - typedef color_type::calc_type calc_type; - typedef int16u pixel_type; - - static AGG_INLINE void blend_pix(pixel_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover) - { - //not sure whether this is right... - alpha = color_type::base_mask - alpha; - pixel_type rgb = *p; - calc_type b = (rgb >> 10) & 31; - calc_type g = (rgb >> 5) & 31; - calc_type r = (rgb ) & 31; - b = ((b+1)*(alpha+1) + (cb)*(cover)-1)>>8; - g = ((g+1)*(alpha+1) + (cg)*(cover)-1)>>8; - r = ((r+1)*(alpha+1) + (cr)*(cover)-1)>>8; - *p = (b<<10)|(g<<5)|r; - } - - static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) - { - return (pixel_type)(((b & 0xF8) << 7) | - ((g & 0xF8) << 2) | - (r >> 3) | 0x8000); - } - - static AGG_INLINE color_type make_color(pixel_type p) - { - return color_type((p << 3) & 0xF8, - (p >> 2) & 0xF8, - (p >> 7) & 0xF8); - } - }; - - struct my_blender_rgb555 - { - typedef rgba8 color_type; - typedef color_type::value_type value_type; - typedef color_type::calc_type calc_type; - typedef int16u pixel_type; - - static AGG_INLINE void blend_pix(pixel_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned) - { - pixel_type rgb = *p; - calc_type b = (rgb >> 7) & 0xF8; - calc_type g = (rgb >> 2) & 0xF8; - calc_type r = (rgb << 3) & 0xF8; - *p = (pixel_type) - (((((cb - b) * alpha + (b << 8)) >> 1) & 0x7C00) | - ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) | - (((cr - r) * alpha + (r << 8)) >> 11) | 0x8000); - } - - static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) - { - return (pixel_type)(((b & 0xF8) << 7) | - ((g & 0xF8) << 2) | - (r >> 3) | 0x8000); - } - - static AGG_INLINE color_type make_color(pixel_type p) - { - return color_type((p << 3) & 0xF8, - (p >> 2) & 0xF8, - (p >> 7) & 0xF8); - - } - }; - - - typedef pixfmt_alpha_blend_rgb_packed my_pixfmt_rgb555_pre; //----pixfmt_rgb555_pre - - typedef pixfmt_alpha_blend_rgb_packed my_pixfmt_rgb555; //----pixfmt_rgb555_pre -} - - - - typedef std::map TAgg_Font_Table; static TAgg_Font_Table font_table; @@ -216,10 +120,6 @@ static void Agg_init_fonts() AggDraw_Desmume aggDraw; - -typedef AggDrawTargetImplementation > T_AGG_RGB555; -typedef AggDrawTargetImplementation > T_AGG_RGBA; - T_AGG_RGB555 agg_targetScreen(GPU_screen, 256, 384, 512); static u32 luaBuffer[256*192*2]; @@ -230,18 +130,28 @@ T_AGG_RGBA agg_targetHud((u8*)hudBuffer, 256, 384, 1024); static AggDrawTarget* targets[] = { &agg_targetScreen, - &agg_targetScreen, //THATS RIGHT! for now, hud maps to screen + &agg_targetHud, &agg_targetLua, }; void Agg_init() { Agg_init_fonts(); - aggDraw.target = targets[0]; aggDraw.screen = targets[0]; aggDraw.hud = targets[1]; aggDraw.lua = targets[2]; + aggDraw.target = targets[0]; + + //if we're single core, we don't want to waste time compositing + if(CommonSettings.single_core) + aggDraw.hud = &agg_targetScreen; + + //and the more clever compositing isnt supported in non-windows + #ifndef WIN32 + aggDraw.hud = &agg_targetScreen; + #endif + aggDraw.hud->setFont("verdana18_bold"); } @@ -250,27 +160,7 @@ void AggDraw_Desmume::setTarget(AggTarget newTarget) target = targets[newTarget]; } -//this code would do compositing.. and maybe it will.. one day. but not for now. -//void AggDraw_Desmume::composite(void* dest) -//{ -// T_AGG_RGB555 target((u8*)dest, 256, 384, 512); -// -// ctr = 0; -// -// //if lua is nonempty, blend it -// if(!agg_targetLua.empty) -// { -// T_AGG_RGBA::MyImage luaImage(agg_targetLua.buf()); -// target.transformImage(luaImage, 0,40,256-1,384-1); -// } -// -// //if hud is nonempty, blend it -// if(!agg_targetHud.empty) -// { -// T_AGG_RGBA::MyImage hudImage(agg_targetHud.buf()); -// target.transformImage(hudImage, 0,0,256-1,384-1); -// } -//} + ////temporary, just for testing the lib //void AGGDraw() { diff --git a/desmume/src/aggdraw.h b/desmume/src/aggdraw.h index 3549c761c..377a2e817 100644 --- a/desmume/src/aggdraw.h +++ b/desmume/src/aggdraw.h @@ -39,10 +39,185 @@ #include "agg_renderer_outline_aa.h" #include "agg_renderer_markers.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" +#include "agg_pixfmt_rgb_packed.h" + #include "agg2d.h" typedef agg::rgba8 AggColor; +namespace agg +{ + //NOTE - these blenders are necessary to change the rgb order from the defaults, which are incorrect for us + + //this custom blender does more correct blending math than the default + //which is necessary or else drawing transparent pixels on (31,31,31) will yield (30,30,30) + struct my_blender_rgb555_pre + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + //not sure whether this is right... + alpha = color_type::base_mask - alpha; + pixel_type rgb = *p; + calc_type b = (rgb >> 10) & 31; + calc_type g = (rgb >> 5) & 31; + calc_type r = (rgb ) & 31; + b = ((b+1)*(alpha+1) + (cb)*(cover)-1)>>8; + g = ((g+1)*(alpha+1) + (cg)*(cover)-1)>>8; + r = ((r+1)*(alpha+1) + (cr)*(cover)-1)>>8; + *p = (b<<10)|(g<<5)|r; + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (r >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 3) & 0xF8, + (p >> 2) & 0xF8, + (p >> 7) & 0xF8); + } + }; + + struct my_blender_rgb555 + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type b = (rgb >> 7) & 0xF8; + calc_type g = (rgb >> 2) & 0xF8; + calc_type r = (rgb << 3) & 0xF8; + *p = (pixel_type) + (((((cb - b) * alpha + (b << 8)) >> 1) & 0x7C00) | + ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) | + (((cr - r) * alpha + (r << 8)) >> 11) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (r >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 3) & 0xF8, + (p >> 2) & 0xF8, + (p >> 7) & 0xF8); + + } + }; + + //this is a prototype span generator which should be able to generate 8888 and 555 spans + //it would be used in agg2d.inl renderImage() + //but it isn't being used yet. + //this will need to be completed before we can use 555 as a source imge + template class span_simple_blur_rgb24 + { + public: + //-------------------------------------------------------------------- + typedef rgba8 color_type; + + //-------------------------------------------------------------------- + span_simple_blur_rgb24() : m_source_image(0) {} + + //-------------------------------------------------------------------- + span_simple_blur_rgb24(const rendering_buffer& src) : + m_source_image(&src) {} + + //-------------------------------------------------------------------- + void source_image(const rendering_buffer& src) { m_source_image = &src; } + const rendering_buffer& source_image() const { return *m_source_image; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, int len) + { + if(y < 1 || y >= int(m_source_image->height() - 1)) + { + do + { + *span++ = rgba8(0,0,0,0); + } + while(--len); + return; + } + + do + { + int color[4]; + color[0] = color[1] = color[2] = color[3] = 0; + if(x > 0 && x < int(m_source_image->width()-1)) + { + int i = 3; + do + { + const int8u* ptr = m_source_image->row_ptr(y - i + 2) + (x - 1) * 3; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + color[3] += 255; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + color[3] += 255; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + color[3] += 255; + } + while(--i); + color[0] /= 9; + color[1] /= 9; + color[2] /= 9; + color[3] /= 9; + } + *span++ = rgba8(color[Order::R], color[Order::G], color[Order::B], color[3]); + ++x; + } + while(--len); + } + + private: + const rendering_buffer* m_source_image; + }; + + typedef pixfmt_alpha_blend_rgb_packed my_pixfmt_rgb555_pre; //----pixfmt_rgb555_pre + + typedef pixfmt_alpha_blend_rgb_packed my_pixfmt_rgb555; //----pixfmt_rgb555_pre +} + + + +typedef PixFormatSetDeclaration > T_AGG_PF_RGB555; +typedef PixFormatSetDeclaration > T_AGG_PF_RGBA; class AggDrawTarget { public: @@ -61,6 +236,12 @@ public: virtual void clear() = 0; + virtual agg::rendering_buffer & buf() = 0; + + //returns an image for this target. you must provide the pixel type, but if it is wrong, + //then you have just created trouble for yourself + AGG2D_IMAGE_TEMPLATE TIMAGE image() { return TIMAGE(buf()); } + // Setup virtual void attach(unsigned char* buf, unsigned width, unsigned height, int stride) = 0; // virtual void attach(Agg2DBase::Image& img) {attach(img);}; @@ -113,6 +294,9 @@ public: virtual void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) = 0; virtual void noLine() = 0; + virtual void transformImage(const Agg2DBase::Image &img, double dstX1, double dstY1, double dstX2, double dstY2) = 0; + //virtual void transformImage(const Agg2DBase::Image &img, double dstX1, double dstY1, double dstX2, double dstY2) = 0; + virtual AggColor fillColor() = 0; virtual AggColor lineColor() = 0; @@ -265,6 +449,9 @@ public: } } + virtual agg::rendering_buffer & buf() { return BASE::buf(); } + typename BASE::MyImage image() { return BASE::MyImage(buf()); } + // Setup virtual void attach(unsigned char* buf, unsigned width, unsigned height, int stride) {BASE::attach(buf, width, height, stride);}; // virtual void attach(Agg2DBase::Image& img) {attach(img);}; @@ -343,6 +530,9 @@ public: virtual void fillEvenOdd(bool evenOddFlag) {BASE::fillEvenOdd(evenOddFlag);}; virtual bool fillEvenOdd() {return BASE::fillEvenOdd();}; + virtual void transformImage(const Agg2DBase::Image& img, double dstX1, double dstY1, double dstX2, double dstY2) { BASE::transformImage(img,dstX1,dstY1,dstX2,dstY2); } + //virtual void transformImage(const Agg2DBase::Image &img, double dstX1, double dstY1, double dstX2, double dstY2) { BASE::transformImage(img,dstX1,dstY1,dstX2,dstY2); } + // Transformations virtual Agg2DBase::Transformations transformations() {return BASE::transformations();}; virtual void transformations(const Agg2DBase::Transformations& tr) {BASE::transformations(tr);}; @@ -434,6 +624,11 @@ public: virtual double rad2Deg(double v) { return v * 180.0 / agg::pi; } }; +//the main aggdraw targets for different pixel formats +typedef AggDrawTargetImplementation T_AGG_RGB555; +typedef AggDrawTargetImplementation T_AGG_RGBA; + + class AggDraw { public: diff --git a/desmume/src/commandline.cpp b/desmume/src/commandline.cpp index 2a7ed7735..aed351724 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -28,6 +28,7 @@ #include "types.h" #include "movie.h" #include "addons.h" +#include "NDSSystem.h" int scanline_filter_a = 2, scanline_filter_b = 4; @@ -35,10 +36,14 @@ CommandLine::CommandLine() : error(NULL) , ctx(g_option_context_new ("")) , is_cflash_configured(false) +, _single_core(0) +, _play_movie_file(0) +, _record_movie_file(0) +, _cflash_image(0) +, _cflash_path(0) { load_slot = 0; arm9_gdb_port = arm7_gdb_port = 0; - single_core = 0; start_paused = FALSE; } @@ -48,11 +53,6 @@ CommandLine::~CommandLine() g_option_context_free (ctx); } -static const char* _play_movie_file; -static const char* _record_movie_file; -static const char* _cflash_image; -static const char* _cflash_path; - void CommandLine::loadCommonOptions() { //these options should be available in every port. @@ -67,7 +67,7 @@ void CommandLine::loadCommonOptions() { "cflash-image", 0, 0, G_OPTION_ARG_FILENAME, &_cflash_image, "Requests cflash in gbaslot with fat image at this path", "CFLASH_IMAGE"}, { "cflash-path", 0, 0, G_OPTION_ARG_FILENAME, &_cflash_path, "Requests cflash in gbaslot with filesystem rooted at this path", "CFLASH_PATH"}, #ifdef _MSC_VER - { "single-core", 0, 0, G_OPTION_ARG_NONE, &single_core, "Limit execution to use approximately only one core", "NUM_CORES"}, + { "single-core", 0, 0, G_OPTION_ARG_NONE, &_single_core, "Limit execution to use approximately only one core", "NUM_CORES"}, { "scanline-filter-a", 0, 0, G_OPTION_ARG_INT, &scanline_filter_a, "Intensity of fadeout for scanlines filter (edge) (default 2)", "SCANLINE_FILTER_A"}, { "scanline-filter-b", 0, 0, G_OPTION_ARG_INT, &scanline_filter_b, "Intensity of fadeout for scanlines filter (corner) (default 4)", "SCANLINE_FILTER_B"}, #endif @@ -95,6 +95,7 @@ bool CommandLine::parse(int argc,char **argv) if(_cflash_image) cflash_image = _cflash_image; if(_cflash_path) cflash_path = _cflash_path; + CommonSettings.single_core = _single_core!=0; if (argc == 2) nds_file = argv[1]; diff --git a/desmume/src/commandline.h b/desmume/src/commandline.h index b550be083..689ac776d 100644 --- a/desmume/src/commandline.h +++ b/desmume/src/commandline.h @@ -41,7 +41,6 @@ public: std::string play_movie_file; std::string record_movie_file; int arm9_gdb_port, arm7_gdb_port; - int single_core; int start_paused; std::string cflash_image; std::string cflash_path; @@ -68,6 +67,13 @@ public: GError *error; GOptionContext *ctx; + +private: + char* _play_movie_file; + char* _record_movie_file; + char* _cflash_image; + char* _cflash_path; + int _single_core; }; #endif diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index b57ea3867..7f173f83f 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -1172,4 +1172,4 @@ void dorewind() rewindbuffer.pop_back(); } -} \ No newline at end of file +} diff --git a/desmume/src/wifi.cpp b/desmume/src/wifi.cpp index c671a9afa..c19ec2385 100644 --- a/desmume/src/wifi.cpp +++ b/desmume/src/wifi.cpp @@ -515,7 +515,7 @@ u8 WIFI_getBB_DATA(wifimac_t *wifi) void WIFI_setBB_DATA(wifimac_t *wifi, u8 val) { - wifi->bbDataToWrite = (val & 0xFF); + wifi->bbDataToWrite = (val); // if ((wifi->bbIOCnt.bits.mode != 1) || !(wifi->bbIOCnt.bits.enable)) return ; /* not for write or disabled */ // wifi->BB.data[wifi->bbIOCnt.bits.address] = val ; } @@ -880,7 +880,7 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val) WIFI_setBB_CNT(wifi,val) ; break ; case REG_WIFI_BBSIOWRITE: - WIFI_setBB_DATA(wifi,val) ; + WIFI_setBB_DATA(wifi,val&0xFF) ; break ; case REG_WIFI_RXBUF_COUNT: wifi->RXBufCount = val & 0x0FFF ; @@ -1077,13 +1077,13 @@ u16 WIFI_read16(wifimac_t *wifi,u32 address) case REG_WIFI_EXTRACOUNT: return wifi->eCount ; case REG_WIFI_USCOMPARE0: - return (wifi->usec & 0xFFFF); + return (u16)wifi->usec; case REG_WIFI_USCOMPARE1: - return ((wifi->usec >> 16) & 0xFFFF); + return (u16)(wifi->usec >> 16); case REG_WIFI_USCOMPARE2: - return ((wifi->usec >> 32) & 0xFFFF); + return (u16)(wifi->usec >> 32); case REG_WIFI_USCOMPARE3: - return ((wifi->usec >> 48) & 0xFFFF); + return (u16)(wifi->usec >> 48); case REG_WIFI_POWER_US: return wifi->crystalEnabled?0:1 ; case REG_WIFI_CIRCBUFRD_END: @@ -1112,8 +1112,6 @@ u16 WIFI_read16(wifimac_t *wifi,u32 address) void WIFI_usTrigger(wifimac_t *wifi) { - u8 dataBuffer[0x2000] ; - u16 rcvSize ; if (wifi->crystalEnabled) { /* a usec (=3F03 cycles) has passed */ diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index dd5b67054..891bbdbc0 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -583,6 +583,10 @@ RelativePath=".\tileView.h" > + + diff --git a/desmume/src/windows/filter/filter.h b/desmume/src/windows/filter/filter.h index 3dbc99d9a..ac5914004 100644 --- a/desmume/src/windows/filter/filter.h +++ b/desmume/src/windows/filter/filter.h @@ -1,3 +1,22 @@ +/* Copyright (C) 2009 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + struct SSurface { unsigned char *Surface; @@ -5,6 +24,7 @@ struct SSurface { unsigned int Width, Height; }; +void RenderNearest2X (SSurface Src, SSurface Dst); void RenderHQ2X (SSurface Src, SSurface Dst); void Render2xSaI (SSurface Src, SSurface Dst); void RenderSuper2xSaI (SSurface Src, SSurface Dst); diff --git a/desmume/src/windows/filter/scanline.cpp b/desmume/src/windows/filter/scanline.cpp index 96ffdd5fb..2fdd4f827 100644 --- a/desmume/src/windows/filter/scanline.cpp +++ b/desmume/src/windows/filter/scanline.cpp @@ -1,3 +1,22 @@ +/* Copyright (C) 2009 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "filter.h" #include "types.h" #include @@ -9,21 +28,27 @@ extern CACHE_ALIGN u16 fadeOutColors[17][0x8000]; extern int scanline_filter_a, scanline_filter_b; -// stretches a single line -inline void DoubleLine16( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ +FORCEINLINE void ScanLine16( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ while(Width--){ *lpDst++ = *lpSrc; *lpDst++ = fadeOutColors[scanline_filter_a][(*lpSrc++)]; } } -inline void DoubleLine16_2( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ +FORCEINLINE void ScanLine16_2( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ while(Width--){ *lpDst++ = fadeOutColors[scanline_filter_a][(*lpSrc)]; *lpDst++ = fadeOutColors[scanline_filter_b][(*lpSrc++)]; } } +FORCEINLINE void DoubleLine16( uint16 *lpDst, uint16 *lpSrc, unsigned int Width){ + while(Width--){ + *lpDst++ = *lpSrc; + *lpDst++ = *lpSrc++; + } +} + void RenderScanline( SSurface Src, SSurface Dst) { uint16 *lpSrc; @@ -36,13 +61,25 @@ void RenderScanline( SSurface Src, SSurface Dst) const unsigned int dstPitch = Dst.Pitch >> 1; uint16 *lpDst = (uint16*)Dst.Surface; - if(Src.Width != 512) - for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) - DoubleLine16 (lpDst, lpSrc, Src.Width), lpDst += dstPitch, - DoubleLine16_2 (lpDst, lpSrc, Src.Width), lpDst += dstPitch; - //memset (lpDst, 0, 512*2), lpDst += dstPitch; - else - for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) - memcpy (lpDst, lpSrc, Src.Width << 1), lpDst += dstPitch, - memset (lpDst, 0, 512*2), lpDst += dstPitch; -} \ No newline at end of file + for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) + ScanLine16 (lpDst, lpSrc, Src.Width), lpDst += dstPitch, + ScanLine16_2 (lpDst, lpSrc, Src.Width), lpDst += dstPitch; + //memset (lpDst, 0, 512*2), lpDst += dstPitch; +} + +void RenderNearest2X (SSurface Src, SSurface Dst) +{ + uint16 *lpSrc; + unsigned int H; + + const uint32 srcHeight = Src.Height; + + const unsigned int srcPitch = Src.Pitch >> 1; + lpSrc = reinterpret_cast(Src.Surface); + + const unsigned int dstPitch = Dst.Pitch >> 1; + uint16 *lpDst = (uint16*)Dst.Surface; + for (H = 0; H < srcHeight; H++, lpSrc += srcPitch) + DoubleLine16 (lpDst, lpSrc, Src.Width), lpDst += dstPitch, + DoubleLine16 (lpDst, lpSrc, Src.Width), lpDst += dstPitch; +} diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index f41acbec8..4a433320c 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -648,17 +648,18 @@ int CreateDDrawBuffers() ddsd.dwWidth = video.rotatedwidth(); ddsd.dwHeight = video.rotatedheight(); - if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL) != DD_OK) return -2; + if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL) != DD_OK) return -2; - if (IDirectDraw7_CreateClipper(lpDDraw, 0, &lpDDClipPrimary, NULL) != DD_OK) return -3; + if (IDirectDraw7_CreateClipper(lpDDraw, 0, &lpDDClipPrimary, NULL) != DD_OK) return -3; - if (IDirectDrawClipper_SetHWnd(lpDDClipPrimary, 0, MainWindow->getHWnd()) != DD_OK) return -4; - if (IDirectDrawSurface7_SetClipper(lpPrimarySurface, lpDDClipPrimary) != DD_OK) return -5; + if (IDirectDrawClipper_SetHWnd(lpDDClipPrimary, 0, MainWindow->getHWnd()) != DD_OK) return -4; + if (IDirectDrawSurface7_SetClipper(lpPrimarySurface, lpDDClipPrimary) != DD_OK) return -5; - return 1; + return 1; } -template static T convert(u16 val) + +template static T realConvert(u16 val) { switch(bpp) { @@ -670,11 +671,26 @@ template static T convert(u16 val) } } + +template static FORCEINLINE T ddconvert(u32 val) +{ + //not supported yet, needs to drop from 32 to 16 + return val; + //switch(bpp) + //{ + // case 24: case 32: + // return RGB15TO24_REVERSE(val); + // case 16: return RGB15TO16_REVERSE(val); + // default: + // return 0; + //} +} + template static void doRotate(void* dst) { u8* buffer = (u8*)dst; int size = video.size(); - u16* src = video.finalBuffer(); + u32* src = video.filteredbuffer32bpp; switch(video.rotation) { case 0: @@ -684,10 +700,10 @@ template static void doRotate(void* dst) { if(video.rotation==180) for(int i = 0, j=size-1; j>=0; i++,j--) - ((T*)buffer)[i] = convert((src)[j]); + ((T*)buffer)[i] = ddconvert((src)[j]); else for(int i = 0; i < size; i++) - ((T*)buffer)[i] = convert(src[i]); + ((T*)buffer)[i] = ddconvert(src[i]); } else { @@ -695,7 +711,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.height; y++) { for(int x = 0; x < video.width; x++) - ((T*)buffer)[x] = convert(src[video.height*video.width - (y * video.width) - x - 1]); + ((T*)buffer)[x] = ddconvert(src[video.height*video.width - (y * video.width) - x - 1]); buffer += ddsd.lPitch; } @@ -703,7 +719,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.height; y++) { for(int x = 0; x < video.width; x++) - ((T*)buffer)[x] = convert(src[(y * video.width) + x]); + ((T*)buffer)[x] = ddconvert(src[(y * video.width) + x]); buffer += ddsd.lPitch; } @@ -717,7 +733,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.width; y++) { for(int x = 0; x < video.height; x++) - ((T*)buffer)[x] = convert(src[(((video.height-1)-x) * video.width) + y]); + ((T*)buffer)[x] = ddconvert(src[(((video.height-1)-x) * video.width) + y]); buffer += ddsd.lPitch; } @@ -725,7 +741,7 @@ template static void doRotate(void* dst) for(int y = 0; y < video.width; y++) { for(int x = 0; x < video.height; x++) - ((T*)buffer)[x] = convert(src[((x) * video.width) + (video.width-1) - y]); + ((T*)buffer)[x] = ddconvert(src[((x) * video.width) + (video.width-1) - y]); buffer += ddsd.lPitch; } @@ -807,21 +823,56 @@ static void DD_DoDisplay() //tripple buffering logic u16 displayBuffers[3][256*192*4]; -int currDisplayBuffer=-1; -int newestDisplayBuffer=-2; +volatile int currDisplayBuffer=-1; +volatile int newestDisplayBuffer=-2; GMutex *display_mutex = NULL; GThread *display_thread = NULL; -//does a single display work unit. only to be used from the display thread -static void DoDisplay() +static void DoDisplay_DrawHud() { osd->update(); DrawHUD(); - video.filter(); - DD_DoDisplay(); osd->clear(); } +//does a single display work unit. only to be used from the display thread +static void DoDisplay(bool firstTime) +{ + if(firstTime) + { + //on single core systems, draw straight to the screen + //we only do this once per emulated frame because we don't want to waste time redrawing + //on such lousy computers + if(CommonSettings.single_core) + { + aggDraw.hud->attach(video.srcBuffer, 256, 384, 512); + DoDisplay_DrawHud(); + } + + //apply user's filter + video.filter(); + } + + //convert pixel format to 32bpp for compositing + //why do we do this over and over? well, we are compositing to + //filteredbuffer32bpp, and it needs to get refreshed each frame.. + const int size = video.size(); + u16* src = video.finalBuffer(); + for(int i=0;iimage(), 0,0,video.width-1,video.height-1); + aggDraw.hud->clear(); + } + + DD_DoDisplay(); +} + void displayProc() { g_mutex_lock(display_mutex); @@ -832,17 +883,18 @@ void displayProc() g_mutex_unlock(display_mutex); - //nothing to display. give up. - if(alreadyDisplayed) return; + //something new to display: + if(!alreadyDisplayed) { + //start displaying a new buffer + currDisplayBuffer = todo; + video.srcBuffer = (u8*)displayBuffers[currDisplayBuffer]; - //start displaying a new buffer - currDisplayBuffer = todo; - - video.srcBuffer = (u8*)displayBuffers[currDisplayBuffer]; - - aggDraw.hud->attach(video.srcBuffer, 256, 384, 512); - - DoDisplay(); + DoDisplay(true); + } + else + { + DoDisplay(false); + } } @@ -856,40 +908,44 @@ void displayThread(void*) void Display() { - if(display_thread == NULL) + CallRegisteredLuaFunctions(LUACALL_AFTEREMULATIONGUI); + + if(CommonSettings.single_core) { - display_mutex = g_mutex_new(); - display_thread = g_thread_create( (GThreadFunc)displayThread, - NULL, - TRUE, - NULL); + video.srcBuffer = (u8*)GPU_screen; + DoDisplay(true); } + else + { + if(display_thread == NULL) + { + display_mutex = g_mutex_new(); + display_thread = g_thread_create( (GThreadFunc)displayThread, + NULL, + TRUE, + NULL); + } - g_mutex_lock(display_mutex); + g_mutex_lock(display_mutex); - //huh... i wonder if there is a less ugly way to do this - if(currDisplayBuffer == 0) - if(newestDisplayBuffer == 1) - newestDisplayBuffer = 2; - else newestDisplayBuffer = 1; - else if(currDisplayBuffer == 1) - if(newestDisplayBuffer == 2) - newestDisplayBuffer = 0; - else newestDisplayBuffer = 2; - else //if(currDisplayBuffer == 1) - if(newestDisplayBuffer == 0) - newestDisplayBuffer = 1; - else newestDisplayBuffer = 0; + //huh... i wonder if there is a less ugly way to do this + if(currDisplayBuffer == 0) + if(newestDisplayBuffer == 1) + newestDisplayBuffer = 2; + else newestDisplayBuffer = 1; + else if(currDisplayBuffer == 1) + if(newestDisplayBuffer == 2) + newestDisplayBuffer = 0; + else newestDisplayBuffer = 2; + else //if(currDisplayBuffer == 1) + if(newestDisplayBuffer == 0) + newestDisplayBuffer = 1; + else newestDisplayBuffer = 0; - memcpy(displayBuffers[newestDisplayBuffer],GPU_screen,256*192*4); + memcpy(displayBuffers[newestDisplayBuffer],GPU_screen,256*192*4); - g_mutex_unlock(display_mutex); - - //the no-multithreading codepath - //but based on my research, this runs just fine on a single core system due to the generous - //sleep in the display loop - //video.srcBuffer = (u8*)GPU_screen; - //doDisplay(); + g_mutex_unlock(display_mutex); + } } @@ -1416,7 +1472,6 @@ std::string GetPrivateProfileStdString(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR int _main() { - Desmume_InitOnce(); InitDecoder(); #ifdef WX_STUB @@ -1522,7 +1577,19 @@ int _main() return 1; } - if(cmdline.single_core) + //try and detect this for users who didn't specify it on the commandline + //(can't say I really blame them) + //this helps give a substantial speedup for singlecore users + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + if(systemInfo.dwNumberOfProcessors==1) + CommonSettings.single_core = true; + + Desmume_InitOnce(); + + //in case this isnt actually a singlecore system, but the user requested it + //then restrict ourselves to one core + if(CommonSettings.single_core) SetProcessAffinityMask(GetCurrentProcess(),1); //sprintf(text, "%s", DESMUME_NAME_AND_VERSION); @@ -2610,6 +2677,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM MainWindow->checkMenu(IDM_RENDER_SUPEREAGLE, video.currentfilter == video.SUPEREAGLE ); MainWindow->checkMenu(IDM_RENDER_SCANLINE, video.currentfilter == video.SCANLINE ); MainWindow->checkMenu(IDM_RENDER_BILINEAR, video.currentfilter == video.BILINEAR ); + MainWindow->checkMenu(IDM_RENDER_NEAREST2X, video.currentfilter == video.NEAREST2X ); MainWindow->checkMenu(IDC_STATEREWINDING, staterewindingenabled == 1 ); @@ -2983,6 +3051,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM video.setfilter(video.BILINEAR); FilterUpdate(hwnd); break; + case IDM_RENDER_NEAREST2X: + video.setfilter(video.NEAREST2X); + FilterUpdate(hwnd); + break; case IDM_STATE_LOAD: { OPENFILENAME ofn; diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index c08994851..0c8da5398 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -170,6 +170,7 @@ #define IDM_RENDER_SUPEREAGLE 555 #define IDM_RENDER_SCANLINE 556 #define IDM_RENDER_BILINEAR 557 +#define IDM_RENDER_NEAREST2X 558 #define IDD_IO_REG 601 #define IDM_RECORD_MOVIE 602 #define IDM_PLAY_MOVIE 603 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 579d1e946838eef67268d0cd1044c319dedda136..558b11abdcccc64aab322a6ae0d3c2022cceb4f4 100644 GIT binary patch delta 105 zcmeD9pxN+Iv!R8tg{g(Pg=GtC9^3RTR#q`#KZaC>M1~?DS