Page 17 of 57

Posted: Sun May 08, 2011 3:28 pm
by letoulousain
Thanks again :)

Posted: Sat May 21, 2011 12:55 am
by sega16
I decided to "upgrade" from basiegaxorz to c because I think it would be more valuable/useful to learn c vs some qbasic like thing and also c is "more powerful" than basic and anyway How would I make an asm c function.What I am looking for is something like this

Code: Select all

int rnd(d1)
{
;Subroutine to generate a pseudo-random number in d0
;d0 = (RNG & $FFFF0000) | ((RNG*41 & $FFFF) + ((RNG*41 & $FFFF0000) >> 16))
;RNG = ((RNG*41 + ((RNG*41 & $FFFF) << 16)) & $FFFF0000) | (RNG*41 & $FFFF)
;output: d0 = number
;------------------------------------------------------------------------------------------------------------------------------------------------------------------------
rnd:
;It would be much easier to just use d1 as the seed
	;move.l	(__LONG_RNG_seed).w,d1
        ;don't need this (below)
	;bne.s	@1
	;move.l	#$2A6D365A,d1 ; if the RNG is 0, reset it to this crazy number
    ; set the high word of d0 to be the high word of the RNG
    ; and multiply the RNG by 41
@1: move.l	d1,d0
	asl.l	#2,d1
    add.l	d0,d1
    asl.l	#3,d1
    add.l	d0,d1
    ; add the low word of the RNG to the high word of the RNG
    ; and set the low word of d0 to be the result
    move.w	d1,d0
    swap	d1
    add.w	d1,d0
    move.w	d0,d1
    swap	d1
    ;move.l	d1,(__LONG_RNG_seed).w
;    rts;not needed in a c function
;now return d0
return(d0)
}
is there anyway to do something like this above?

Posted: Sat May 21, 2011 2:41 am
by Chilly Willy
You probably want to read this:
http://en.wikipedia.org/wiki/Linear_fee ... t_register

It's a good summary of the most common (fastest) method of doing PRNs in C/C++.

Posted: Sat May 21, 2011 11:23 am
by Stef
The method that Chilly Willy gave you is quite good to generate quickly pseudo random number.
I don't know if you're using SGDK library but as you're posting in this thread i guess maybe. And in this case there is already a random() method which return you a pseudo random 16 bits integer. The method is quite fast too and does work nicely as far i tested it :)

Posted: Sat May 21, 2011 12:40 pm
by sega16
Stef wrote:The method that Chilly Willy gave you is quite good to generate quickly pseudo random number.
I don't know if you're using SGDK library but as you're posting in this thread i guess maybe. And in this case there is already a random() method which return you a pseudo random 16 bits integer. The method is quite fast too and does work nicely as far i tested it :)
Sorry I didn't notice that function,I should look in the headers more.Also,just a suggestion maybe on the wiki there should be an article explain each function that would help lot of people new to SGDK/C (like me :D).Maybe I could help,I got a Google account but since it's your wiki I don't want to flood it with a bunch of pages about the functions without you saying that I should. I have edited a wiki before but never a Google code wiki can you with just a Google account?
Edit:Now I see it was in tools.h I thought it would be in math.h
Edit 2:By looking at the code:

Code: Select all

u16 random()
{
    randbase ^= (randbase >> 1) ^ GET_HVCOUNTER;
    randbase ^= (randbase << 1);

    return randbase;
}

I don' think it supports range. Would it be bad to just do:

Code: Select all

 u16 random_number;
out_of_range:
 random_number=random();
 if (random_number < 16) //check to see if the number is out of the range
{
 goto out_of_range;
}

Posted: Sat May 21, 2011 6:05 pm
by Chilly Willy
Depending on how fast it's supposed to be, most people deal with the range by doing "val = rand % range;" as the modulo takes care of that. The LFSR limits the range to the msb of the tap. There's a table of the range (called the period for PRNs) in the article I linked.

Posted: Sat May 21, 2011 8:14 pm
by Stef
sega16 wrote: Sorry I didn't notice that function,I should look in the headers more.
Also,just a suggestion maybe on the wiki there should be an article explain each function that would help lot of people new to SGDK/C (like me :D).Maybe I could help,I got a Google account but since it's your wiki I don't want to flood it with a bunch of pages about the functions without you saying that I should. I have edited a wiki before but never a Google code wiki can you with just a Google account?
Yeah of course, this really need a document which explain all functions ! Unfortunately i didn't had the time (or the motivation :p) to do it yet :-/
If you want to contribute to this, free fell to do it :D It will be really appreciated ! Kaneda already helped me by writing some tutorials.
You just need a google account, then you give it to me and i can add you to the project so you can write wiki =)
Google wiki seems a bit different from classical wiki but it's similar.
Edit:Now I see it was in tools.h I thought it would be in math.h
Yeah, current location isn't the best one but as it's isolated method i don't really mind for now.

Code: Select all

 I don' think it supports range. Would it be bad to just do:
As Chilly said, you have to use % operator to range the value.
If you want to range to a power 2 value (as 16), use & operator to mask your value which is a lot faster (% need a division).

Posted: Sat May 21, 2011 11:58 pm
by sega16
This post has long since been acted upon and I should not have posted my email in plain text as web crawlers index it and spam me a bit.

Posted: Sun May 22, 2011 9:51 am
by Stef
I added you, you should be able to edit wiki :)
http://code.google.com/p/sgdk/w/list

Don't hesitate to contact me if you have some questions about methods or whatever ;)

Posted: Thu Jun 02, 2011 12:34 pm
by Stef
I saw you write a wiki tutorial about how load tiles and display them, thanks for it :)
I don't know if you get a look on Kaneda tutorials but they are quite interesting if you're interested with VDP operations.

On my side i just added a basic "How use Math in SGDK" tutorial, still quite limited right now but i plan to improve it.

Posted: Thu Jun 02, 2011 4:37 pm
by KanedaFr
thanks for the Math tut ! ;)

Posted: Sat Jun 25, 2011 3:48 am
by sega16
I have been using sgdk for awhile now and it is truly a great tool for devolving for the sega genesis and it has helped me learn c alot but just one question would it be possible to avoid pallete flickering when loading new tiles?
Image
is their anyway to fix this I have tried messing with the vsync

Code: Select all

#include "genesis.h"
#include "global.h"
#include "Tubelec.h"
const u8 even = 0;//dma will gltich without this
#include "road_tiles.h"
#include "road_palletes.h"
void VDP_waitnotVSync()
{
    vu16 *pw;
    u16 vdp_state;

    vdp_state = VDP_VBLANK_FLAG;
    pw = (u16 *) GFX_CTRL_PORT;

    while (vdp_state & VDP_VBLANK_FLAG) vdp_state = *pw;
    //while (!(vdp_state & VDP_VBLANK_FLAG)) vdp_state = *pw;
}

void robotnik_3d()
{

    stopPlay_2ADPCM(AUDIO_PCM_CH1);
    startPlay_2ADPCM((const u8 *)Tubelec, sizeof(Tubelec), AUDIO_PCM_CH1,1);
    u8 frame;
    frame=0;
    //right now all it will be doing is moving the road
    VDP_resetScreen();//clear all stuff on the screen
    //now put this in a loop
    //draw the tiles
    VDP_fillTileMapRectInc(APLAN, 1, 0, 11, 40, 17);
    while (1)
    {
        frame++;
        if (frame == 4)
        {
            frame = 0;
        }

        //VDP_setPalette(PAL0, (const u16 *)road_palletes+(frame*16));
        //VDP_loadTileData( (const u32 *)road_tiles+(frame*5440), 1, 1120, 1);
        VDP_waitnotVSync();
        VDP_doCRamDMA((const u32 *)road_palletes+(frame*8), 0,32);
        VDP_doVRamDMA((const u32 *)road_tiles+(frame*5440), 32, 21760);
        VDP_waitDMACompletion();
        VDP_waitVSync();

    }
}
thank you for your help if you have a suggestion.

Posted: Sat Jun 25, 2011 5:17 am
by Chilly Willy
The simplest way is to use two palettes - set one palette for one set of tiles and the other for the other. When you flip/scroll to the new tile names, the palette will point to the other palette. So you're double-buffering not just the tile names, but also the palette. The downside is you're using two palettes, leaving just two for anything else (sprites).

getting better

Posted: Sat Jun 25, 2011 2:46 pm
by sega16
Chilly Willy wrote:The simplest way is to use two palettes - set one palette for one set of tiles and the other for the other. When you flip/scroll to the new tile names, the palette will point to the other palette. So you're double-buffering not just the tile names, but also the palette. The downside is you're using two palettes, leaving just two for anything else (sprites).
this is what you meant right?

Code: Select all

#include "genesis.h"
#include "global.h"
#include "Tubelec.h"
const u8 even = 0;//dma will gltich without this (somehow the program got un-aligned)
#include "road_tiles.h"
#include "road_palletes.h"
void VDP_waitnotVSync()
{
    vu16 *pw;
    u16 vdp_state;

    vdp_state = VDP_VBLANK_FLAG;
    pw = (u16 *) GFX_CTRL_PORT;
    while (!(vdp_state & VDP_VBLANK_FLAG)) vdp_state = *pw;
    while (vdp_state & VDP_VBLANK_FLAG) vdp_state = *pw;

}

void robotnik_3d()
{

    stopPlay_2ADPCM(AUDIO_PCM_CH1);
    startPlay_2ADPCM((const u8 *)Tubelec, sizeof(Tubelec), AUDIO_PCM_CH1,1);
    u8 frame;
    frame=0;
    //right now all it will be doing is moving the road
    VDP_resetScreen();//clear all stuff on the screen
    //now put this in a loop
    //draw the tiles

    while (1)
    {

        if (frame == 4)
        {
            frame = 0;
        }
        //VDP_setPalette(PAL0, (const u16 *)road_palletes+(frame*16));
        //VDP_loadTileData( (const u32 *)road_tiles+(frame*5440), 1, 1120, 1);
        VDP_waitnotVSync();//dma is faster during vblank I think wait for the vblank (i just edited the vysnc code)
        //
        switch (frame)
        {
            case 0:
            VDP_doCRamDMA((const u32 *)road_palletes, 0,32);
            break;
            case 1:
            VDP_doCRamDMA((const u32 *)road_palletes+8, 32,32);
            break;
            case 2:
            VDP_doCRamDMA((const u32 *)road_palletes+16,0,32);
            break;
            case 3:
            VDP_doCRamDMA((const u32 *)road_palletes+24, 32,32);
            break;
        }
        VDP_doVRamDMA((const u32 *)road_tiles+(frame*5440), 32, 21760);
        switch (frame)// looks slightly better when I put this after dmaing the tiles
        {
            case 0:
            VDP_fillTileMapRectInc(APLAN, TILE_ATTR_FULL(0,0,0,0,1), 0, 11, 40, 17);
            break;
            case 1:
            VDP_fillTileMapRectInc(APLAN, TILE_ATTR_FULL(1,0,0,0,1), 0, 11, 40, 17);
            break;
            case 2:
            VDP_fillTileMapRectInc(APLAN, TILE_ATTR_FULL(0,0,0,0,1), 0, 11, 40, 17);
            break;
            case 3:
            VDP_fillTileMapRectInc(APLAN, TILE_ATTR_FULL(1,0,0,0,1), 0, 11, 40, 17);
            break;
        }
        //#define TILE_ATTR_FULL(pal, pri, flipV, flipH, index)
        //VDP_fillTileMapRectInc(APLAN, 1, 0, 11, 40, 17);
        VDP_waitVSync();
        VDP_waitDMACompletion();
        frame++;
    }
}
it did improve the blinking but it is still visible.I am not looking for 60fps or anything in fact 10 would be fine.Thank you for your help chilly willy!
Image

Posted: Sat Jun 25, 2011 4:54 pm
by TmEE co.(TM)
One thing that I did was to have 2 tile buffers, each with its own palette, and both held on their own BG layer. When I load one set of tiles I show the other already loaded set, and when loading is done I will scroll out the current layer and scroll in new layer. That way I avoid tearing and palette glitches :)