From e0f44d02f4157b311275cc7e944d64471b0e787d Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 7 Jul 2015 14:09:27 -0400 Subject: [PATCH] screen_savers/Nebula: Convert draw.S to C. Hand-translated. I left the assembly in as comments for easy analysis, I'll remove it in the next commit. (I didn't do this on my own, I had help.) --- src/add-ons/screen_savers/nebula/Draw.c | 148 ++++++++++++++++++++ src/add-ons/screen_savers/nebula/Nebula.cpp | 49 ++++--- src/add-ons/screen_savers/nebula/draw.S | 136 ------------------ src/add-ons/screen_savers/nebula/makefile | 2 +- 4 files changed, 173 insertions(+), 162 deletions(-) create mode 100644 src/add-ons/screen_savers/nebula/Draw.c delete mode 100644 src/add-ons/screen_savers/nebula/draw.S diff --git a/src/add-ons/screen_savers/nebula/Draw.c b/src/add-ons/screen_savers/nebula/Draw.c new file mode 100644 index 0000000000..e4ccd75e94 --- /dev/null +++ b/src/add-ons/screen_savers/nebula/Draw.c @@ -0,0 +1,148 @@ +// Hand-translated from x86 assembly. + +/* memshset (char *dst, int center_shade,int fixed_shade, int length_2) */ +/* dst is the *center* of the dst segment */ +/* center shade is the initial color (at center) (!! 8:8 also) */ +/* fixed_shade is the fixed point increment (8:8) */ +/* length_2 is the 1/2 length to set (to the left, and to the right) */ + +/* a memaddshadedset function (or something like that ) */ + +void memshset(char* dstParam, int center_shade, int fixed_shade, int half_length) +{ + unsigned char* dst; + unsigned char* source; + int offset; + + if (half_length == 0) + return; + +// movl 8(%ebp),%edi /* dst */ +// movl 12(%ebp),%eax /* center_shade*/ +// movl 16(%ebp),%ebx /* fixed_shade */ +// movl 20(%ebp),%ecx /* half_length */ +// +//@ orl %ecx,%ecx +//@ jz 2f +// + + dst = (unsigned char*)dstParam; + source = dst; +// movl %edi,%esi + dst -= half_length; // Left segment +// subl %ecx,%edi /* %edi left segment */ + source += half_length; // Right segment +// addl %ecx,%esi /* %esi right segment */ + source++; // Don't overlap at middle +// incl %esi /* dont overlap at middle */ +// + offset = half_length; +// movl %ecx,%edx + offset = -offset; +// negl %edx + offset--; // For in-advance incl in loop +// decl %edx /* for in-advance incl in loop */ + + do { + int tmp; +//1: + center_shade += fixed_shade; // Increment color. + center_shade &= 0xFFFF; // Mask so we can do overflow tests. +// addl %ebx,%eax /* increment color */ + offset++; +// incl %edx + + tmp = dst[half_length] + (center_shade >> 8); // Increment left pixel. + // addb %ah,(%edi,%ecx) /* increment left pixel */ + // Did it overflow? + if (tmp & 0xFF00) { + // jc 3f /* did overflow ? */ + dst[half_length] = 255; +//3: +// movb $255,(%edi,%ecx) + } else { + dst[half_length] = tmp; + } + + + tmp = source[offset] + (center_shade >> 8); // Increment right pixel. + // Did it overflow? + if (tmp & 0xFF00) { + source[offset] = 255; +//4: +// movb $255,(%esi,%edx) +// decl %ecx +// jnz 1b +// +// popl %ebx +// popl %esi +// popl %edi +// +// leave +// ret + } else { + source[offset] = tmp; + } +// addb %ah,(%esi,%edx) /* increment right pixel */ +// jc 4f +// + } while (--half_length != 0); +// decl %ecx +// jnz 1b +// +//2: +// popl %ebx +// popl %esi +// popl %edi +// +// leave +// ret +} + + +/* do the "motion blur" (actually the pixel fading) */ +void mblur(char* srcParam, int nbpixels) +{ +// movl 8(%ebp),%edi /* dst */ +// movl 12(%ebp),%ecx /* number */ + unsigned int clear1UpperBit = 0x7f7f7f7f; + unsigned int clear3UpperBits = 0x1f1f1f1f; + unsigned long* src = (unsigned long*)srcParam; +// movl $0x7f7f7f7f,%edx /* clear 1 upper bits */ +// movl $0x1f1f1f1f,%esi /* clear 3 upper bits */ + + if ((nbpixels >>= 2) == 0) + // shrl $2,%ecx + return; + // jz 2f +// + do { +//1: + long eax, ebx; + eax = *src; + // movl (%edi),%eax + src++; + // addl $4,%edi + // + ebx = eax; + // movl %eax,%ebx + eax >>= 1; + // shrl $1,%eax + // + // + ebx >>= 3; + // shrl $3,%ebx + eax &= clear1UpperBit; + // andl %edx,%eax + // + ebx &= clear3UpperBits; + // andl %esi,%ebx + eax += ebx; + // addl %ebx,%eax + // + src[-1] = eax; + // movl %eax,-4(%edi) + } while (--nbpixels != 0); + // decl %ecx + // jnz 1b +} diff --git a/src/add-ons/screen_savers/nebula/Nebula.cpp b/src/add-ons/screen_savers/nebula/Nebula.cpp index a77c12ce02..6f6402bc5a 100644 --- a/src/add-ons/screen_savers/nebula/Nebula.cpp +++ b/src/add-ons/screen_savers/nebula/Nebula.cpp @@ -33,8 +33,7 @@ float presin[512]; typedef unsigned short word; extern "C" { - void memshset(char *dst, int center_shade,int fixed_shade, int length_2); - void mblur(char *src, int nbpixels); + #include "Draw.c" void draw_stars320(char *, char); void draw_stars512(char *, char); @@ -173,19 +172,19 @@ drawshdisk(int x0, int y0, int r) //gBuffer8[x0+W*y0] = 10+r*5; return; } - + if (r < SLIMIT+SRANGE) r = ((r-SLIMIT)*SLIMIT)/SRANGE+1; y = ly = r; /* AAaargh */ delta = 3-2*r; - do { + do { if (y != ly) { /* dont overlap these lines */ c = ((r-y+1)<<13)/r; d = -c/(x+1); - + if (y == x+1) /* this would overlap with the next x lines */ goto TOTO; /* WHY NOT */ @@ -193,11 +192,11 @@ drawshdisk(int x0, int y0, int r) (unsigned int)(x) < M <=> 0<=xH ) - + This is clearly a stupid, unmaintanable, unreadable "optimization". But i like it :) */ - if ((uint32)(y0-y-1) < gHeight-3) + if ((uint32)(y0-y-1) < gHeight-3) memshset(&gBuffer8[x0 + gWidth*(y0-y+1)] ,c,d, x); if ((uint32)(y0+y-1) < gHeight-3) memshset(&gBuffer8[x0 + gWidth*(y0+y)] ,c,d, x); @@ -219,7 +218,7 @@ drawshdisk(int x0, int y0, int r) y--; } x++; - } while (x < y); + } while (x < y); } @@ -240,8 +239,8 @@ drawGalaxy() (independant of processor speed) */ static bigtime_t firstTime = system_time(); - t = ((double)gSpeed * system_time()-firstTime)/1000000.0; //opti_scale_time(0.418, &demo_elapsed_time); - + t = ((double)gSpeed * system_time()-firstTime)/1000000.0; //opti_scale_time(0.418, &demo_elapsed_time); + a = 0.9*t; b = t; c = 1.1*t; @@ -255,12 +254,12 @@ drawGalaxy() oa = 140 * osin(a); ob = 140 * ocos(b); oc = 240 * osin(c); - + if (gMotionBlur) { /* mblur does something like that: * (or did, perhaps it's another version!..) - - for (i=0; i>3) + (gBuffer8[i]>>1); */ mblur (gBuffer8, gWidth*gHeight); @@ -314,24 +313,24 @@ setPalette() case 1: // blue for (i = 0; i < 30; i++) gPalette[i] = (uint8)(i*8/10); // << 16 | (uint8)(i*6/10) << 8; // | (uint8)(i*3/10); - + for (i = 30; i < 256; i++) { uint8 b = (i); uint8 g = (i*i >> 8); //(i*8/10); uint8 r = i >= 240 ? (i-240) << 3 : 0; //(i*2/10); - + gPalette[i] = ((r << 16) | (g << 8) | (b)); } break; case 2: // red for (i = 0;i < 128;i++) gPalette[i] = (uint8)i << 16; // << 16 | (uint8)(i*6/10) << 8; // | (uint8)(i*3/10); - + for (i = 128;i < 256;i++) - { + { uint8 r = i; uint8 c = (uint8)((cos((i-256) / 42.0)*0.5 + 0.5)*225); - + gPalette[i] = ((r << 16) | (c << 8) | c); } /* for (i = 192;i < 224;i++) @@ -413,12 +412,12 @@ class SimpleSlider : public BSlider { }; char *UpdateText() const - { + { sprintf(fText, "%s: %d", fLabel, Value()); return fText; }; - + private: mutable char fText[32]; const char *fLabel; @@ -432,10 +431,10 @@ class SimpleSlider : public BSlider { class SettingsView : public BView { public: SettingsView(BRect frame); - + virtual void AttachedToWindow(); virtual void MessageReceived(BMessage *msg); - + private: BMenuField *fWidthMenu,*fColorMenu,*fBorderMenu; BCheckBox *fMotionCheck; @@ -463,7 +462,7 @@ SettingsView::AttachedToWindow() BRect rect(10,0,0,25); rect.right = Bounds().right; - + BStringView *string = new BStringView(rect,B_EMPTY_STRING,"Nebula"); string->SetFontSize(18.0); AddChild(string); @@ -472,7 +471,7 @@ SettingsView::AttachedToWindow() string = new BStringView(rect,B_EMPTY_STRING,VERSION_STRING); AddChild(string); -// rect.OffsetBy(0,height+5); +// rect.OffsetBy(0,height+5); rect.left = 10; rect.top = 27; rect.bottom = 17+height; string = new BStringView(rect,B_EMPTY_STRING,"© 2001-2004 pinc Software, Axel Dörfler."); string->SetAlignment(B_ALIGN_CENTER); @@ -629,7 +628,7 @@ Nebula::Nebula(BMessage *message, image_id id) gSettingsWidth = 320; if (gMaxFramesPerSecond < 1.f) gMaxFramesPerSecond = 40.0f; - + gScreenSaver = this; } diff --git a/src/add-ons/screen_savers/nebula/draw.S b/src/add-ons/screen_savers/nebula/draw.S deleted file mode 100644 index d52243855e..0000000000 --- a/src/add-ons/screen_savers/nebula/draw.S +++ /dev/null @@ -1,136 +0,0 @@ - -.text - -/* memshset (char *dst, int center_shade,int fixed_shade, int length_2) */ -/* dst is the *center* of the dst segment */ -/* center shade is the initial color (at center) (!! 8:8 also) */ -/* fixed_shade is the fixed point increment (8:8) */ -/* length_2 is the 1/2 length to set (to the left, and to the right) */ - -/* a memaddshadedset function (or something like that ) */ - -.globl memshset -.type memshset,@function - - -memshset: - pushl %ebp - movl %esp,%ebp - - pushl %edi /* registres a sauvegarder (convention gcc) */ - pushl %esi - pushl %ebx - - movl 8(%ebp),%edi /* dst */ - movl 12(%ebp),%eax - movl 16(%ebp),%ebx /* fixed point */ - movl 20(%ebp),%ecx /* half length */ - - orl %ecx,%ecx - jz 2f - - movl %edi,%esi - subl %ecx,%edi /* %edi left segment */ - addl %ecx,%esi /* %esi right segment */ - incl %esi /* dont overlap at middle */ - - movl %ecx,%edx - negl %edx - decl %edx /* for in-advance incl in loop */ -1: - addl %ebx,%eax /* increment color */ - incl %edx - - addb %ah,(%edi,%ecx) /* increment left pixel */ - jc 3f /* did overflow ? */ - - addb %ah,(%esi,%edx) /* increment right pixel */ - jc 4f - - decl %ecx - jnz 1b - -2: - popl %ebx - popl %esi - popl %edi - - leave - ret -/* function goes on (several exit points): */ -3: - movb $255,(%edi,%ecx) - addb %ah,(%esi,%edx) /* we recopy all the code.. to avoid jmps (hmm some asm guru here : is it really efficient ?.. */ - jc 4f - decl %ecx - jnz 1b - - popl %ebx - popl %esi - popl %edi - - leave - ret - -4: - movb $255,(%esi,%edx) - decl %ecx - jnz 1b - - popl %ebx - popl %esi - popl %edi - - leave - ret -/* function really stops here */ - - -/*********************************** motion blur **********************************/ - -/* do the "motion blur" (actually the pixel fading) */ -.globl mblur -.type mblur,@function - -mblur: - pushl %ebp - movl %esp,%ebp - - pushl %edi - pushl %esi - pushl %ebx - - movl 8(%ebp),%edi /* dst */ - movl 12(%ebp),%ecx /* number */ - movl $0x7f7f7f7f,%edx /* clear 1 upper bits */ - movl $0x1f1f1f1f,%esi /* clear 3 upper bits */ - shrl $2,%ecx - jz 2f - -1: - movl (%edi),%eax - addl $4,%edi - - movl %eax,%ebx - shrl $1,%eax - - - shrl $3,%ebx - andl %edx,%eax - - andl %esi,%ebx - addl %ebx,%eax - - decl %ecx - movl %eax,-4(%edi) - - - jnz 1b - - -2: - popl %ebx - popl %esi - popl %edi - leave - ret diff --git a/src/add-ons/screen_savers/nebula/makefile b/src/add-ons/screen_savers/nebula/makefile index ebeccb75ca..c074f5808e 100644 --- a/src/add-ons/screen_savers/nebula/makefile +++ b/src/add-ons/screen_savers/nebula/makefile @@ -6,7 +6,7 @@ CFLAGS = -O3 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimiz LIBS = -lbe -lscreensaver NAME = Nebula FILES = Nebula -ASMFILES = draw +ASMFILES = STARFILE = draw_stars STARWIDTHS = 320 512 576 640 800 1024 1152 1280 1400 1600 OBJDIR = obj.x86