Jump to content
IGNORED

my start with RB+ - barbarian project- need help


F.L

Recommended Posts

hello

i have done an open-source remake in basic of "barbarian- the ultimate warrior", a classic game of 1988

http://barbarian.1987.free.fr/indexEN.htm

i'd like to port it on atari jaguar with this Raptor Basic +

since a few years i was following the rb+project but i dont become to compile a rom.

this week, its done ! :-D

i have integrated the entire code (over 5000 line) and its works !

and now i begin to add the gfx

tonight i do this :

rb+.png

you can move the player. here is a link to the rom :

 

https://www.dropbox.com/s/wrq2vcoc645cu4a/essai04.rom?dl=0

 

i need some help to understand how to do. i have read the tutorials but i'm not easy with english reading (i'm french)

if someone want to help me it would be nice !

after i have understand the basics of rb+, the port will be possible

 

for example : for my debugging i need to display values and but i dont know how to do

 

a%=100

RLOCATE 0,218

rprint a%

dont works.....

 

and there is something i dont understand with the palette. look at my sprite, he has the same palette than the background

' background
loadclut(strptr(decorFORET_clut),1,16) ' decor
'sprite
loadclut(strptr(sprite1_clut),2,16) ' sprite

thanks in advance for helping me.

Edited by F.L
  • Like 7
Link to comment
Share on other sites

for example : for my debugging i need to display values and but i dont know how to do

 

a%=100

RLOCATE 0,218

rprint a%

dont works.....

There are a couple of reasons why this doesn't work.

- Do you set basic_r_size and basic_r_indx to 0 somewhere in your code?

- The first object in your rapinit.s is the particle/text layer. Did you change this at all? It has to be the first one in the file and has to be active etc.

 

and there is something i dont understand with the palette. look at my sprite, he has the same palette than the background

' background

loadclut(strptr(decorFORET_clut),1,16) ' decor

 

'sprite

loadclut(strptr(sprite1_clut),2,16) ' sprite

 

thanks in advance for helping me.

Since you load the CLUTs it's probably your sprite object definition. In your partlist.s look for a line that has "; sprite_CLUT ; no_CLUT (8/16/24 bit) or CLUT (1/2/4 bit)". This tells the hardware which CLUT to use for this object. Just set that to 2 instead of 1 and it should work.

 

 

Good luck with your project!

Edited by ggn
  • Like 3
Link to comment
Share on other sites

you may also want to look at my object list editor, it allows you to integrate the object lists into your code very easily, it also allows you to make changes extremely quickly, this includes moving the objects up and down the list with a simple mouse drag, look at the version here on AA if you like it, there is a newer version, if you want it after testing pm me

Link to comment
Share on other sites

thanks ggn, now the color of sprite is good !

 

sorry for all those questions, rb+ doesn't seems the other langagues i had done before !

sometime it seems like asm

 

and for write a value, i do this, like in the example :

 

rlist=(RAPTOR_LIST *)strptr(RAPTOR_sprite_table) // i dont know what's that ?

dim a%
a%=10
basic_r_size=0
basic_r_indx=0
RLOCATE 150,100
RPRINT " HELLO" // it works
RLOCATE 50,100
RPRINT a% // it dont works

 

omf, i dont know where is your objet list editor ...?

Link to comment
Share on other sites

To print an integer use rprintint a%

 

 

rlist=(RAPTOR_LIST *)strptr(RAPTOR_sprite_table) // i dont know what's that ?

This allows you to use rlist commands . Instead of rsetobj and rgetobj you can directly access the object properties. It is also a bit faster. So use (for example) rlist[objectnumber].x = 100<<16

Edited by Sporadic
  • Like 1
Link to comment
Share on other sites

cool, its works ! now i can display my loops.

 

the game runs too speed because the engine is in 40 fps and the jaguar run in 60 fps, il must smow it

 

now the game runs in demo mode :

https://www.dropbox.com/s/ecns0aiwdehdi6o/essai05.rom?dl=0

and here is a pic :

rb+.png

 

i have a new question : how to flip the second sprite ? in rapinit.s i have tried "is_flipped" or "flip_x" but it dont works...

  • Like 4
Link to comment
Share on other sites

thanks ggn, now the color of sprite is good !

Great!

 

sorry for all those questions, rb+ doesn't seems the other langagues i had done before !

sometime it seems like asm

Yes, sorry about that! Sometimes I used ugly hacks to fix some things, and never went back to hide them from the user.

 

and for write a value, i do this, like in the example :

 

rlist=(RAPTOR_LIST *)strptr(RAPTOR_sprite_table) // i dont know what's that ?

That's one of those "ugly hacks" I talked about above. I could certainly explain why this is there and what it does but I'm not sure it would help people much :). Just keep it there for now and you might find it useful :).

 

dim a%

a%=10

basic_r_size=0

basic_r_indx=0

RLOCATE 150,100

RPRINT " HELLO" // it works

 

RLOCATE 50,100

RPRINT a% // it dont works

RPRINT only works when printing text strings, like RPRINT "HELLO!". For a generic print just use PRINT, for example PRINT "Hello",1,"there!". Finally RPRINTINT is a fast version of print that only prints integer values.

 

Ass for your flipped spite problems: There are 2 ways to flip a sprite. One is to put the value is_flipped (or -1) to the object in the "sprite_flip" line in rapint.s. The other is to set the field inside your game:

 

rlist[your_sprite_object_number].flip=R_is_flipped 'Flip sprite
rlist[your_sprite_object_number].flip=R_is_normal 'Back to normal
Hope this helps! Edited by ggn
  • Like 3
Link to comment
Share on other sites

ggn, yes it help me, now the second sprite is flipped :thumbsup:

now i will add the animation changes

can i display 2 sprite 64x64 at screen or its too big ?

what are are the limitations ?

can i change the gfx of sprite "on the fly" with rb+

 

hello gemintronic, i dont think one compiler is better, because the hardware is different.

and its cool to have a new basic compiler !

Edited by F.L
Link to comment
Share on other sites

Look at the scroller example source code. That changes the gfxbase location of the sprites to point to different graphics. I'm sure the 2 64px sprites will be fine. There's only one way to find out :)

 

ggn, yes it help me, now the second sprite is flipped :thumbsup:

now i will add the animation changes

can i display 2 sprite 64x64 at screen or its too big ?

what are are the limitations ?

can i change the gfx of sprite "on the fly" with rb+

 

hello gemintronic, i dont think one compiler is better, because the hardware is different.

and its cool to have a new basic compiler !

  • Like 3
Link to comment
Share on other sites

hello gemintronic, i dont think one compiler is better, because the hardware is different.

Well - challenge accepted ;). Of course I do agree that the hardware between the megadrive and the jaguar is very different so you can't really compare performance. But all the same we could compare pure basic performance!

 

So I downloaded BasiEgaXorz and took a quick look at the examples bundled until I found an easy and suitable case:

 

 dim a(24) as integer
 for b=1 to 24
  a(b)=b
 next
 for b=1 to 24
  print a(b)
 next
Ok, that's not really an amazing piece of code but it'll do for illustration purposes. So I told the IDE (BTW very nice and clean IDE, if only rb+ had such a nice IDE like that - anyway :D) to compile and generate the assembly output. This is what it gave me:

 

	include	basicasm.cni

	move.l	#1,d0
	move.w	d0,(__INTEGER_b)
__FOR_JUMP_0
	clr.l	d0
	move.w	(__INTEGER_b),d0
	move.w	d0,-(a7)
	clr.l	d0
	move.w	(__INTEGER_b),d0
	lsl.l	#1,d0
	move.l	#__INTEGER_a,a0
	move.w	(a7)+,0(a0,d0.l)
__FOR_JUMP3_0:
	move.l	#24,d0
	cmp.w	(__INTEGER_b),d0
	beq	__FOR_JUMP2_0
	move.l	#1,d0
	add.w	d0,(__INTEGER_b)
	jmp	__FOR_JUMP_0
__FOR_JUMP2_0:
	move.l	#1,d0
	move.w	d0,(__INTEGER_b)
__FOR_JUMP_1
	movem.l	d0/d1/d4,-(a7)
	clr.l	d0
	move.w	(__INTEGER_b),d0
	lsl.l	#1,d0
	move.l	#__INTEGER_a,a0
	clr.l	d2
	move.w	0(a0,d0.l),d2
	movem.l	(a7)+,d0/d1/d4
	clr.l	d0
	move.w	d2,d0
	jsr	print_w
	jsr	print_cr
__FOR_JUMP3_1:
	move.l	#24,d0
	cmp.w	(__INTEGER_b),d0
	beq	__FOR_JUMP2_1
	move.l	#1,d0
	add.w	d0,(__INTEGER_b)
	jmp	__FOR_JUMP_1
__FOR_JUMP2_1:
forever:
	bra	forever


	EVEN


	include	basicstr.s
	EVEN

	include	basicdat.s
	EVEN




__INTEGER_A	EQU	$FF004C
__INTEGER_B	EQU	$FF007E
HEAPSTART	EQU	$FF0080
__DATA_Pendcode:
	END
Okay, so it assumes type "integer" is 16 bits. That's fine. Also, it seems to only use A0 and D0 from the 68000 registers regardless of being 16 available on the CPU. Also it writes every result to RAM, even for the FOR variable and then fetches it back. Which is not super great but it does the job of course. One last thing I notice is that it uses jmp instad of bra which is a bit more costly.

 

Overall impression: it's okay all things considered - it's typical output of what C compilers in the 80s and late 90s would emit.

 

Now let's try the listing modified a tiny bit for rb+:

 

dim b as short
 dim a[24] as short
 for b=1 to 24
  a[b]=b
 next
 for b=1 to 24
  print a[b]
 next
Now, let's give it a spin (note that I removed all irrelevant rb+ and assembly code and focused on the routine only):

 

	lea __ZL1a+2,%a0
	moveq #1,%d0
.L2:
	move.w %d0,(%a0)+
	addq.w #1,%d0
	cmp.w #25,%d0
	jne .L2
	move.w #1,__ZL1b
	move.b #1,%d0
	lea __ZL1a,%a4
	lea ee_printf,%a3
.L3:
	ext.l %d0
	add.l %d0,%d0
	move.w (%a4,%d0.l),%a0
	move.l %a0,-(%sp)
	pea .LC2
	jsr (%a3)
	move.l %d0,_basic_r_buffer
	addq.l #8,%sp
	jsr (%a2)
	move.w __ZL1b,%d0
	addq.w #1,%d0
	move.w %d0,__ZL1b
	cmp.w #24,%d0
	jle .L3
.L7:
	jra .L7
	.globl	rlist
	.bss
	.even
.lcomm __ZL1b,2
.lcomm __ZL1a,48
Because rb+ uses gcc 4.6.4 as its compiler backend and turns optimisations on it has a couple of decades of compiler optimisation knowledge in it. So it's not afraid to use more 68000 registers to cache addresses or values. Also it can detect that the intermediate results don't have to be written back to ram so it writes and reads only when necessary, making the two loops tighter. Finally it uses short branches that are slightly faster but matter in big loops.

 

But: can we do better? Let's rewrite the code a bit.

 

dim b as short
 dim a[24] as short
 for b=24 to 1 step -1
  a[b]=b
 next
 for b=24 to 1 step -1
  print a[b]
 next
Nothing fancy, just rewrite the loops to use a decreasing counter. Which gives us...

 

	lea __ZL1a+50,%a0
	moveq #24,%d0
.L2:
	move.w %d0,-(%a0)
	subq.w #1,%d0
	jne .L2
	move.w #24,__ZL1b
	move.b #24,%d0
	lea __ZL1a,%a4
	lea ee_printf,%a3
.L3:
	ext.l %d0
	add.l %d0,%d0
	move.w (%a4,%d0.l),%a0
	move.l %a0,-(%sp)
	pea .LC2
	jsr (%a3)
	move.l %d0,_basic_r_buffer
	addq.l #8,%sp
	jsr (%a2)
	move.w __ZL1b,%d0
	subq.w #1,%d0
	move.w %d0,__ZL1b
	jgt .L3
.L7:
	jra .L7
	.globl	rlist
	.bss
	.even
.lcomm __ZL1b,2
.lcomm __ZL1a,48
...wheee! One instruction less in the first loop! Which means it can take advantage of CPU state of the previous instruction and can eliminate the need of comparison. That's pretty neat!

 

So that's pretty fun. But: can we do better? Well, yes, provided that we change the problem ever so slightly:

 

dim b as short
 dim a[25] as short
 for b=24 to 0 step -1
  a[b]=b
 next
 for b=24 to 0 step -1
  print a[b]
 next
So now our table is 25 indices long instead of 24, but we decrease the loop counters down to 0. Let's see what happens now...

 

	lea __ZL1a+50,%a0
	moveq #24,%d0
.L2:
	move.w %d0,-(%a0)
	dbra %d0,.L2
	move.w #24,__ZL1b
	moveq #24,%d0
	lea __ZL1a,%a4
	lea ee_printf,%a3
.L3:
	ext.l %d0
	add.l %d0,%d0
	move.w (%a4,%d0.l),%a0
	move.l %a0,-(%sp)
	pea .LC2
	jsr (%a3)
	move.l %d0,_basic_r_buffer
	addq.l #8,%sp
	jsr (%a2)
	move.w __ZL1b,%d0
	subq.w #1,%d0
	move.w %d0,__ZL1b
	jge .L3
.L7:
	jra .L7
	.globl	rlist
	.bss
	.even
.lcomm __ZL1b,2
.lcomm __ZL1a,50
...the hell? We now have a friggin' dbra in there - hardware loops baby! We managed to convince the compiler that our loop case can be expressed using hardware loops! Of course we didn't have such luck with the second loop, but this can probably be done with a bit more iterations and tinkering.

 

So from this small example we can deduce that rb+ is using a more mature compiler than BasiEgaXorz. Now I should mention that I have no clue if BasiEgaXorz has any compiler switches to turn optimisation on but I couldn't find anything looking around. Please correct me if I am wrong here. Also I should say again that comparing the 2 basics is comparing apples to oranges because of the much different hardware. I just did it because I was curious myself and it was a fun thing to do :).

  • Like 6
Link to comment
Share on other sites

i want to change at-the fly the gfx of my sprite 2, because i don't want to use a sprite sheet if possible

 

i have readed the scroller example and i do this for putting the gfx of sprite3 in sprite2 :

 

DIM stars_gfx_loc%
DIM stars%
stars=3;
stars_gfx_loc=RGETOBJ(stars,R_sprite_gfxbase)

rsetobj(2,R_sprite_gfxbase,stars_gfx_loc)

 

it works, but i want to know if i must create a sprite in rapinit for each gfx i want to use to swap in sprite2......

(i have over 200 gfx to swap in the game)

Link to comment
Share on other sites

Well you could define all the sprites as raptor objects but as you say it'll be a LOT of work! Also it will slow down raptor processing a bit, and we can't have that!

One way to slow down your animations is to change the sprite_animspd property (either in rapinit.s or at runtime). This will make the animation slow down by frames. So if your screen displays at 60fps then you can make your animation run at 30fps, 15fps and so on. But that won't work if you want your animation to update at, say, 40fps.

So here's another way of doing this. Here's a spritesheet from nyandodge, zoomed up x4:

post-10979-0-99571200-1509906691.png


Each frame is 32 pixels wide by 11 pixels high. We can use this to our advantage! If you know the address of the first frame it's very easy to find the address of the second. Basically you need to add height * ( width * no_of_bits_per_pixel ) / 8 to your address. So in the above example our picture is 4 bits per pixel so we need to add 11*(32*4)/8=176 bytes. The third frame is then 176*2 bytes from the start, etc etc. So you can keep a frame counter and when it reaches 40 calculate and set the sprite's gfxbase and set it using rsetobj (or rlist which is recommended).

Hope I didn't screw up the maths above and that it helps you :)

Edited by ggn
  • Like 3
Link to comment
Share on other sites

yes, thanks for your explanation, this is clear. i will try it

if i have understand , if each frame of my spritesheet is 64 wide by 64 high, the size of each frame is 64*(64*4)/8= 2048

my spritesheet will have 60 frames, so 60x64 pixel height. it's not too big to load in rapinit ?

Edited by F.L
Link to comment
Share on other sites

hello

update of the rom :

https://www.dropbox.com/s/vglohty2qi4kgu6/barbarianBETA.rom?dl=0

now i will give only this link for the rom, it will be more simply

 

what's new : the two player's sprites are entire (64*64) and go behind the two sprites of trees (48*64)

it runs well at 60 fps

you can move the players but i have a problem with pad : i can't do diagonals

i do this :

 

pad1=getpad(1)

IF pad1=PAD_LEFT THEN x1 = x1 - 1
IF pad1=PAD_RIGHT THEN x1 = x1 + 1
IF pad1=PAD_DOWN THEN y1 = y1 + 1
IF pad1=PAD_UP THEN y1 = y1 - 1
it works but not in diagonals, why ?
Link to comment
Share on other sites

you can move the players but i have a problem with pad : i can't do diagonals

i do this :

 

pad1=getpad(1)

IF pad1=PAD_LEFT THEN x1 = x1 - 1

IF pad1=PAD_RIGHT THEN x1 = x1 + 1

IF pad1=PAD_DOWN THEN y1 = y1 + 1

IF pad1=PAD_UP THEN y1 = y1 - 1

it works but not in diagonals, why ?

            pad1=getpad(1)
            IF pad1 band PAD_LEFT THEN x1 = x1 - 1
            IF pad1 band PAD_RIGHT THEN x1 = x1 + 1
            IF pad1 band PAD_DOWN THEN y1 = y1 + 1
            IF pad1 band PAD_UP THEN y1 = y1 - 1
Should work. Basically pad1 is a bitfield with the status of all jagpad buttons. For example jagpad left status is bit 2, right is bit 3 etc. So you can't check that value with a simple =. You first have to mask out all other bits.

 

Also, if you want to check for up+left in one line you can do something like

if pad1 band (PAD_LEFT bor PAD_UP) THEN ...
Hope this makes things more clear!
  • Like 2
Link to comment
Share on other sites

cool, its works with "band"

thanks again ggn ! each time you help me, the game reach one step :thumbsup:

now with option button you can change the mode game solo/vs/demo

and all the moves and attack of the players are enabled (but animations not yet ! :-D )

see ya for the next step :)

rb+.png

  • Like 5
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...