Archive for September, 2008

First big optimisation in sprite functions.

Tuesday, September 16th, 2008

It’s been a while that I’m working on various optimisation to some functions to copy tables of data. I found out that the C compiler wasnt optimizing it at all. Here is the original piece of code :

    counter = data[frame].spriteNum;
    for(i=0; i<counter; i++) {
        //x = data[frame].data[i].nameLow & 0x0f;
        //y = data[frame].data[i].nameLow >> 4;

        spriteData.data[i+offset].HPos =
            data[frame].data[i].HPos + 0x76;
        spriteData.data[i+offset].VPos =
            data[frame].data[i].VPos + 0x80;
        spriteData.data[i+offset].nameLow =
            data[frame].data[i].nameLow;
        spriteData.data[i+offset].priority =
            data[frame].data[i].priority;
        spriteData.data[i+offset].color =
            data[frame].data[i].color;
    }

    // set big sprite
    spriteData.prop[offset].properties = 0xaa;
    spriteData.prop[offset+1].properties = 0xaa;

This was consuming almost 25% of the cpu time between each Vblank. The new code is going about 30 times faster :

    heroPreparedSpriteData *myData;
    OBJECTData *myObjectData;
    OBJECTData *currentSpriteData
    OBJECTProp *currentSpriteProp;

    // init with base address
    myData = data;
    // set to current frame
    for(i=0; i<frame; i++) {
        myData++;
    }

    // init with base address
    currentSpriteData = (OBJECTData*) &spriteData.data;
    currentSpriteProp = (OBJECTProp*) &spriteData.prop;
    // set to current frame
    for(i=0; i<offset; i++) {
        currentSpriteData ++;
    }

    counter = myData->spriteNum;

    // init start of the data array
    // we assume we always starts at 0 index
    myObjectData = (OBJECTData*) &(myData->data);

    for(i=0; i<counter; i++) {
        currentSpriteData->HPos = myObjectData->HPos + 0x76;
	currentSpriteData->VPos = myObjectData->VPos + 0x80;
	currentSpriteData->nameLow = myObjectData->nameLow;
	currentSpriteData->priority = myObjectData->priority;
	currentSpriteData->color = myObjectData->color;

	// update myObjectData Adress
	myObjectData++;
	currentSpriteData ++;
    }

    // set big sprite for the 8 first sprites
    currentSpriteProp->properties = 0xaa;
    currentSpriteProp++;
    currentSpriteProp->properties = 0xaa;

C compilers seems to something really handle the table really badly.

So now I’m going to finish writing the sprite routines since now I have acceptable performance going on. Why acceptable ? Because I’m sure there is a relly more effecient way to perform all this. It’s basically just copying data, so I should get myDta in ROM and DMA it to RAM and from there just updating some values like HPos and VPos.

I keep you updated anyway …

See ya, Lint

Source code of a commercial SNES game leaked …

Monday, September 15th, 2008

I have found yesterday a site that give a link to the source code of a commercial SNES game. I hadn’t have a close look yet but me for me I thinks it’s the first time that the source code of a full game is available on the net. If I’m wrong don’t hesitate to contact me …

Here is the link the the blog.

++ Lint

F-Zero VS

Sunday, September 14th, 2008

I discovered a few days ago a blog explaining how to play a multiplayer mode in F-Zero running in a modified version of snes9x.

I hope that one day such feature will be possible on hardware with a action replay like device to patch the game and a way to communicate between two SNES.

Here is the F-Zero VS blog.

++ Lint

Back from vacation …

Wednesday, September 3rd, 2008

It’s been almost 5 days that I’m back from vacation.I have almost no time for myself …

Hard time at work since we have a major release on next wednesday. I’m still able to find some time while on the train. So I’m still optimising sprite stuff. I dicovered that the WDC Compiler is very bad at handling structure and tables. It’s don’t optimize the code at all and it’s a real loss of CPU cycle for nothing and finally always recalcaulating the exact same memory offsets.

I’m in the process to completely rewrite that code in pure ASM.

++ Lint