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

Sega Megadrive/Genesis development
https://gendev.spritesmind.net/forum/
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)
}
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 meStef 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
Code: Select all
u16 random()
{
randbase ^= (randbase >> 1) ^ GET_HVCOUNTER;
randbase ^= (randbase << 1);
return randbase;
}
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;
}
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 :-/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).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, current location isn't the best one but as it's isolated method i don't really mind for now.Edit:Now I see it was in tools.h I thought it would be in math.h
Code: Select all
I don' think it supports range. Would it be bad to just do:
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();
}
}
this is what you meant right?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).
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++;
}
}