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.)
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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<=x<H
|
||||
(because if x<0, then (unsigned)(x) = 2**32-|x| which is
|
||||
BIG and thus >H )
|
||||
|
||||
|
||||
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<W*H; i++)
|
||||
|
||||
for (i=0; i<W*H; i++)
|
||||
gBuffer8[i]= (gBuffer8[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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user