Sega Genesis Dev Kit (SGDK)

SGDK only sub forum

Moderator: Stef

letoulousain
Interested
Posts: 42
Joined: Fri Sep 24, 2010 11:32 pm
Location: toulouse

Post by letoulousain »

Thanks again :)
sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post 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?
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post 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++.
Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post 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 :)
sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post 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;
}
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post 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.
Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post 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).
sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post 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.
Last edited by sega16 on Tue Nov 11, 2014 3:27 am, edited 1 time in total.
Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post 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 ;)
Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post 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.
Last edited by Stef on Thu Jun 02, 2011 5:23 pm, edited 1 time in total.
KanedaFr
Administrateur
Posts: 1154
Joined: Tue Aug 29, 2006 10:56 am
Contact:

Post by KanedaFr »

thanks for the Math tut ! ;)
sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post 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.
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post 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).
sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

getting better

Post 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
TmEE co.(TM)
Very interested
Posts: 2452
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post 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 :)
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
Post Reply