Posts for Bisqwit


Post subject: Youtube video of writing C++ code
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
I actually went ahead and Youtubed the process of writing a Mandelbrot fractal renderer. This one uses the Boundary Tracing Algorithm, which greatly speeds up the rendering process when large regions of same color are present. http://www.youtube.com/watch?v=rVQMaiz0ydk P.S. It took about seven hours to produce this video, not counting the time spent designing the program. And I had to redo the recording six times. In the background, it features a couple of AdLib music pieces I created in the 90s.
Post subject: Re: z := z² + c
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Bisqwit wrote:
Fractals are just so fascinating.
I admit that the above source code failed to demonstrate "why". Why? Because they're so simple. Here is a version that is rewritten for simplicity and clarity, and all speed optimizations are taken out. This program outputs an image file in PNM format to stdout.
#include <cmath>
#include <complex>
#include <iostream>

typedef std::complex<double> Value;

/* Define the window of the fractal we want to view. */
static const Value min(-0.370846195, -0.651744395);
static const Value max(-0.369578005, -0.645876205);
/* Define the rendering. */
static const int Width = 512, Height = 384, MaxIter = 1024;

int main()
{
    const Value step = (max-min) / Value(Width,Height);
    std::cout << "P3\n" << Width << ' ' << Height << "\n100\n";
    for(int y=0; y<Height; ++y)
        for(int x=0; x<Width; ++x)
        {
            Value c = min + step*Value(x,y), z = c;
            int iter;
            for(iter=0; iter<MaxIter; ++iter)
            {
                if(std::abs(z) >= 2.0) break;
                z = z * z + c; /* This is the core of the fractal! */
            }
            /* The following is just an arbitrary manner of converting the iter value into a colour. */
            int Red   = 50 + 49 * std::cos(iter/100.0);
            int Green = 50 - 49 * std::cos(iter/80.0);
            int Blue  = 50 - 49 * std::sin(iter/70.0+2);
            std::cout << Blue << ' ' << Green << ' ' << Red << '\n';
        }
}
The image it produces is: I call this one the Menorah Fractal. It has got the Mandelbrot set surrounded by four Menorahs.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Sonikkustar wrote:
I did some tests and level 1 sadly cant be improved using that. Nice try though. ;)
Really? Oh well. Because I did two lax attempts, one in the old manner and one in the suggested manner (both of course optimized such that not a frame is wasted not doing something), and the new one was two or three frames faster. But the timings in the game are indeed much unreliable.
Post subject: Re: Should I change my username?
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
$whateveryouwanttobecalled, do these colours have a particular significance?
Post subject: z := z² + c
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Fractals are just so fascinating. (Click the above image to zoom.) Below, is the source code of the program used to generate that image*. It uses OpenMP for multithreading and SSE2 SIMD intrinsics for doing parallel mathematics on single core. On a 4-core CPU, it calculates 8 pixels simultaneously. Language: C++.
#include <SDL.h>
#include <math.h>
#include <signal.h>

#include <iostream>
#include <emmintrin.h>

static const unsigned MaxIter = 2048;
static const double Xmin = -.743643135-.000014628/2;//-2.02;
static const double Xmax = -.743643135+.000014628/2;//+0.5;
static const double Ymin = .131825963-.000014628/2; //-1.15;
static const double Ymax = .131825963+.000014628/2;//+1.15;

static inline double Smooth(unsigned c, double r2, double i2)
{
    //return c + 1 - log2(log2(sqrt(r2+i2)));
    return log(log(r2+i2))*-1.442695+c+1.4712336;
}

static inline double Mand(double r,double i, double X,double Y, unsigned firstiter=0)
{
    double p = sqrt((r-0.25)*(r-0.25) + i*i);
    if(r < p-2*p*p+0.25
    || (r+1)*(r+1)+i*i < 1/16.0) return 0.0;

    for(unsigned c=firstiter; ; )
    {
        double r2 = r*r;
        double i2 = i*i;
        
        if(r2+i2 >= 4) return Smooth(c, r2,i2);
        
        if(++c >= MaxIter) break;
        
        double ri = r*i;
        i = ri+ri + Y;
        r = r2-i2 + X;
    }
    return 0.0;
}

template<unsigned which>
static inline double GetD(__m128d v)
{
    return _mm_cvtsd_f64(_mm_shuffle_pd(v,v, _MM_SHUFFLE2(0,which)));
}

static __m128d TwoMand(__m128d X, __m128d Y)
{
    { double r = GetD<0>(X), i = GetD<0>(Y);
      double p = sqrt((r-0.25)*(r-0.25) + i*i);
      if(r < p-2*p*p+0.25
      || (r+1)*(r+1)+i*i < 1/16.0) return _mm_set_pd(0.0, Mand(GetD<1>(X),GetD<1>(Y),GetD<1>(X),GetD<1>(Y)));
    }
    { double r = GetD<1>(X), i = GetD<1>(Y);
      double p = sqrt((r-0.25)*(r-0.25) + i*i);
      if(r < p-2*p*p+0.25
      || (r+1)*(r+1)+i*i < 1/16.0) return _mm_set_pd(Mand(GetD<0>(X),GetD<0>(Y),GetD<0>(X),GetD<0>(Y)), 0.0);
    }
    __m128d r = X, i = Y;
    
    const __m128d threshold = _mm_set_pd(4.0, 4.0);
    for(unsigned c=0; ; )
    {
        __m128d r2 = _mm_mul_pd(r, r);
        __m128d i2 = _mm_mul_pd(i, i);
        
        __m128i comparison =
            (__m128i) _mm_cmpge_pd(_mm_add_pd(r2,i2), threshold);
        unsigned a = _mm_extract_epi16(comparison, 0);
        if(__builtin_expect(a,0))
        {
            double lo_value = Smooth(c,GetD<0>(r2),GetD<0>(i2));
            if(_mm_extract_epi16(comparison, 4))
            {
                double hi_value = Smooth(c,GetD<1>(r2),GetD<1>(i2));
                return _mm_set_pd(lo_value,hi_value);
            }
            double rhi = GetD<1>(r), ihi = GetD<1>(i);
            return _mm_set_pd(lo_value, Mand(rhi,ihi, GetD<1>(X),GetD<1>(Y), c));
        }
        else if(__builtin_expect(_mm_extract_epi16(comparison, 4),0))
        {
            double hi_value = Smooth(c,GetD<1>(r2),GetD<1>(i2));
            double rlo = GetD<0>(r), ilo = GetD<0>(i);
            return _mm_set_pd(Mand(rlo,ilo, GetD<0>(X),GetD<0>(Y), c), hi_value);
        }

        if(++c >= MaxIter) break;

        __m128d ri = _mm_mul_pd(r, i);
        i = _mm_add_pd(_mm_add_pd(ri,ri), Y);
        r = _mm_add_pd(_mm_sub_pd(r2,i2), X);
    }
    return _mm_setzero_pd();
}

static int CscaleUp(double value, double mi,double ma)
    { return (int)((value-mi)*255.0/(ma-mi)); }
static int CscaleDown(double value, double mi,double ma)
    { return 255-CscaleUp(value,mi,ma); }

static void PutPix(unsigned char* target, double value)
{
    value = value*4096/MaxIter;
    if(value > 512+128) value = 512+128+(value-(512+128))/8;
    value = fmod(value, 256.0);
    if(value < 64)       target[0] = CscaleUp(value,0,64);
    else if(value < 96) target[0] = CscaleDown(value,64,96), target[2] = CscaleUp(value,64,96);
    else if(value < 128) target[1] = CscaleUp(value,96,128), target[2]=255;
    else if(value <192) target[0] = CscaleUp(value,128,192), target[2]=target[1]=255;
    else                target[2]=target[1]=target[0]=CscaleDown(value,192,256);
}

int main()
{
    const unsigned Yres = 4096*3/4;
    const unsigned Xres = 4096;
    
    SDL_Init(SDL_INIT_VIDEO);
    SDL_InitSubSystem(SDL_INIT_VIDEO);
    SDL_Surface* surface = SDL_SetVideoMode(Xres,Yres, 32,0);
    signal(SIGINT, SIG_DFL);
    
    unsigned char* target = (unsigned char*)surface->pixels;

    #pragma omp parallel for schedule(guided,1)
    for(unsigned y=0; y<Yres; ++y)
    {
        double i = Ymin+y*(Ymax-Ymin)/(double)Yres;
        __m128d twoi = _mm_set_pd(i,i);
        
        double r = Xmin;
        double rstep  = (Xmax-Xmin)    /(double)Xres;
        double rstep2 = (Xmax-Xmin)*2.0/(double)Xres;
        unsigned char* scanline = target + y*Xres*4;
        
        for(unsigned x=0; x<Xres; x += 2, r += rstep2)
        {
            __m128d res = TwoMand( _mm_set_pd(r, r+rstep), twoi );
            PutPix(scanline + 0 + x*4, GetD<0>(res));
            PutPix(scanline + 4 + x*4, GetD<1>(res));
        
            if(!(x&(511)))
            {
                #pragma omp critical(sdlflip)
                SDL_Flip(surface);
            }
        }
    }
    SDL_Flip(surface);
    
    std::cout << "P3\n" << Xres << " " << Yres << "\n255\n";
    for(unsigned n=Xres*Yres, a=0; a<n; ++a)
    {
        std::cout << (int)target[a*4+2] << ' ';
        std::cout << (int)target[a*4+1] << ' ';
        std::cout << (int)target[a*4+0] << ' ';
    }
    std::cout << "\n";
    return getchar();
}
*) The iteration count, the resolution and palette selection may differ.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
That seems to be the case. To complete the set, find where a death occurs on respawn. In Fireman stage, the room with restart point A cannot is not supposed to scroll down. (Nor the room with restart point B, but that is irrelevant).
Post subject: Re: rm1 tech
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
aglasscage wrote:
http://dehacked.2y.net/microstorage.php/info/774035805/rockmanidea.fcm
Interesting. Looks like right before dying, it triggers one of the "must scroll" flags, which will be postponed and processed in the respawning room. But that "must scroll" flag is one of the following: -- Scroll to previous room (whatever means) -- only if "down" in the dying room would have taken to the previous room, as shown here -- Scroll to next room (whatever means) -- only if "down" in the dying room would have taken to the next room -- Scroll down to previous room, as the case would have been in the dying room (regardless of how the current and next room are connected in the respawning room) -- Scroll down to next room -"- -- Scroll down, choose either previous or next room, and possibly die if neither is the case. I remind you that the maps only have a concept of "next" and "previous" room. Down / up scrollings are merely illusions intended to convey different types of transitions to next / previous rooms. Orthographic relationships between distant rooms do not exist.
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/smw-bladegash-106M.mkv (114 MiB) This is Bladegash's SECOND attempt at Super Mario World TAS -- though it is currently the first SMW TAS displayed on this site. His first attempt was not archived here, so I encoded the second one. This is from the time before most SMW trick discoveries.
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/battletoads-philandgenisto-2p-69M.mkv (214 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! (Well, aside from Famtasia's imperfect sound emulation.) Download it here: http://w-create.com/%7Ebisqwit/smb1-bisqwit-663M.mkv (27 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/castlevania-bisqwitv4-674M.mkv (91 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/rushnattack-jeffc-638M.mkv (82 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/makaimura-morimoto-nocompletedemo-607M.mkv (140 MiB) Note: This is a demonstration movie that shows what happens if you attempt to complete the game without collecting a certain item that is required to kill a certain boss properly. As a demonstration, it does some detours to show interesting things, such as being frogified. (Which may or may not have been intentional.)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! (Well, aside from Famtasia's imperfect sound emulation.) Download it here: http://w-create.com/%7Ebisqwit/smb1-michaelfried-661M.mkv (26 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/hitlernf-feitclub-619M.mkv (140 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/rockman1-morimoto-5M.mkv (155 MiB)
Post subject: HD encoding!
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Yay, old submission! I created a HD encode for this movie that is an important part of NESVideos history. Finally, you can enjoy a TAS in the manner it was originally designed for! Download it here: http://w-create.com/%7Ebisqwit/legendofzelda-superhappy-659M.mkv (153 MiB)
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Thank you ktwo for posting this information. I verified that at least level 1 can be improved with your means. (And that my robot was unable to discover the fact on its own, as expected, considering that it is guided by manually choosing its route.)
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Aktan wrote:
Here is an encode: http://www.archive.org/download/MorimotosNesRockman2In2824.65/rockman2-tas-morimoto.mp4
Impressive quality!
Aktan wrote:
HQ Stream coming soon.
Are you kidding? Also, for a reason or another, I liked this movie.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Aww, that's a nasty failure from the part of the encoder. Luckily its impact is small as it only affects the ending demo here. But it's the exact reason why I used a second screen for the N64 encodes. Unexpected popups usually occur on the first screen only. Usually. (Anyone wonder why I prefer simple desktops over complex ones like Gnome or KDE?)
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Noob Irdoh wrote:
as you can see here: <img src="C:\Dokumente und Einstellungen\Michael\Desktop\snapshot20100225152153.bmp">
I'm sorry to break this to you, but we all don't have access to your German language Windows XP installation on your computer's C drive to read the image from. The link is broken. Not to mention that linking to/embedding BMP files is a bad idea. Convert them to PNG or JPEG format first. On a more helpful tangent, try Photoshack or something like that. The Youtube version of that movie looks just fine btw.
Post subject: Hiphop PHP: Make site faster?
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
http://wiki.github.com/facebook/hiphop-php/ Nach & co., already aware of this? Already using it? Seems nice. Though it doesn't support things like eval() and create_function(), requiring mild code rewrites.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
HHS wrote:
I'm not sure if "Open the door with the door" is even a possible interpretation of "Open the door with it". The word "it" usually doesn't refer to something introduced in the sentence itself.
At least it is a valid interpretation for "open the door with itself". I'm not sure whether "itself" is one of the possible interpretation of "it". The parse trees shown earlier were produced with Link [link] btw.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Oh yes there was. It's just that nobody probably has it anymore. There exists a torrent for it, though.
-rw-r--r-- 1 bisqwit root 3249 25.3.2004 supermariobros3j-timeattack-morimoto.avi.torrent
Refers to a 40037932 byte AVI file. Oh yes, the standards and tools of nesvideos were a bit different that day.
Editor, Experienced Forum User, Published Author, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Warp wrote:
> take the golden key from the box and open the door with it
There is no golden key in the red box. You take the golden key from the blue box. You cannot open the door with the blue box. You cannot open the door with the door. You open the door with the golden key. Simple: Iterate through ambiguous choices and choose the first-match, and yank error messages. Well, simple in theory. Practice, not so much. Though these images illustrate other reasons. EDIT: By the way, I would like "open the door with the golden key in the box" better.