sounds good im interested......
sounds good im interested......
I have been searching a lot for examples, tutorials and articles about platform games and jumping gravity. The only examples i could find where using floating point, so i used it to test if it would work. I already knew i had to replace it with something else but i did not know what. I will look up fixed point, thanks for explaining.
In supertux the height is depending on the time you keep the jump button pressed. I want that in SupertuxMD too, and i think the only change is the initial velocity.
I know you meant the horizontal speed, on jump the speed should be half the speed. I will look into that later.
Right now i use a function from Chilly Willy that is meant for "drawing" text. And i write a single character 4 times for each drawn tile. This is where the slow drawing comes from, and i will fix it later. Jumping, gravity and acceleration ha more priority. I am working on converting the large SuperTux logo, i want to use it as an intro. Start with a black screen, let it fade in (by changing colors), and then "slide in" the playfield to start a demo. But priority is low for this.
No. I am using the example code from Chilly Willy, and expanded from there. It's a mix of Assembly startup code and some ASM libraries. The game it self is in plain C.Originally Posted by sega16
Learning the genesis one bit at a time
That's a smart trick, i am working on a function that loads the palette from a memory address that can be called from C. For now the palette's are still loaded in hw.s at the same spot and the map is loaded after that from C.
I know all of this demo and testing code has to change for a scrolling map to work smooth. For now it works and the map loading is done quick enough for me to not be bothered with it now.![]()
Learning the genesis one bit at a time
I should probably add a palette setting command to my next demo. I didn't really think of it at the time since Tic Tac Toe just needs one set palette.
Optimizing is generally saved for the end. There are times when you want to do some during the construction of a game, for example, to see if you can get the video fast enough for what you want the game to do; it may set the limits of the game. But usually you just want to get it going, then do any needed optimization.I know all of this demo and testing code has to change for a scrolling map to work smooth. For now it works and the map loading is done quick enough for me to not be bothered with it now.![]()
EDIT: Try this for setting the palette.
That's designed to be put in the hw_md.s file and be called from C using the proto in the first comment. You'd do it like this.Code:| void set_palette(short *pal, int start, int count) | copy count entries pointed to by pal into the palette starting at the index start | entry: pal = pointer to an array of words holding the colors | start = index of the first color in the palette to set | count = number of colors to copy .global set_palette set_palette: movea.l 4(sp),a0 /* pal */ move.l 8(sp),d0 /* start */ move.l 12(sp),d1 /* count */ add.w d0,d0 /* start * 2 */ swap d0 ori.l #0xC0000000,d0 /* write CRAM address (0 + index *2) */ subq.w #1,d1 /* for dbra */ lea 0xC00000,a1 move.w #0x8F02,4(a1) /* set INC to 2 */ move.l d0,4(a1) /* write CRAM */ 0: move.w (a0)+,(a1) /* copy color to palette */ dbra d1,0b rts
The start should be from 0 to 63, and count should be from 1 to 64; pal should be a pointer to words that hold the palette entry values. Note that the function doesn't wait on the vertical blank or anything... you could call it in the middle of a frame, but doing so could/may/will cause "noise" on the display while the colors are set. Also note that it doesn't use DMA. You could use DMA for faster color setting, but this is an example again meant for general usage. It's perfectly fine for most cases. I think that sometimes people get too caught up in trying to use DMA for everything they can.Code:extern void set_palette(short *pal, int start, int count); short color1[] = { 0x000, 0x111, 0x222, 0x333 }; // grays short color2[] = { 0x000, 0x100, 0x200, 0x300 }; // blues ... set_palette(color1, 0, 4); set_palette(color2, 16, 4);
Last edited by Chilly Willy; 07-25-2011 at 04:01 PM.
That's exactly what i mean, my focus is on getting the physics right. To test that i needed a map so i abused your text functions to load it, saved me from spending time on that at the beginning. When the physics are a bit more fine tuned, and replaced with fixed point numbers, i will need to update the map loading to faster routines.Originally Posted by Chilly Willy
Thanks for that function, it will be very usefull. I have been modifying your font loading routine to load the sprites, and was doing the same for the paletes.Originally Posted by Chilly Willy
I got it this far:and then load it with this, (a4) is set before with this "lea 0xC00004,a4" but you know that alreadyCode:|=============================================================================== | Not Available from C at this time | ram_copy_word(); |=============================================================================== | d0 = number of colors to load | a0 = pointer to table | a3 = pointer to VDP data |------------------------------------------------------------------------------- .align 2 .global vdp_copy_word vdp_copy_word: move.w (a0)+,(a3) dbra d0,vdp_copy_word rtsand this in an other partCode:move.l #0xC0000000,(a4) /* Load palette #0 */ lea vdp_gentile_default(pc),a0 move.w #16,d0 bsr vdp_copy_wordThis allows for a generic NON-DMA transfer of word's to the VDP. Maybe not efficient but it does work great for testing. I just needed to integrate all that to make it safe to use in CCode:.align 2 .global vdp_default_cp0 vdp_gentile_default: .word 0x0E0E .word 0x0CCC .word 0x000E .word 0x00E0 .word 0x0E00 .word 0x00EE .word 0x0EE0 .word 0x0000 .word 0x0EEE .word 0x0666 .word 0x0006 .word 0x0060 .word 0x0600 .word 0x0066 .word 0x0660 .word 0x0606
Learning the genesis one bit at a time
A generic move to vdp in C might be like
where the function is void movew_vdp(short *ptr, int count). Because of the dbra, the count cannot be more than 65536, but that's bigger than any transfer you can make in any case.Code:movew_vdp: movea.l 4(sp),a0 lea 0xC0000000,a1 move.l 8(sp),d0 subq.w #1,d0 0: move.w (a0)+,(a1) dbra d0,0b rts
Keep everything in a0, a1, d0, and d1 and you don't need to worry about saving and restoring registers. A minor speedup to the above code would be to move longs instead of words - move one word is the count is odd, then divide the count in half with a right shift and use move.l instead of move.w.
Chilly Willy: Thats i what i meant was needed for my function to be safe in C, i have to use the lower registers instead. Just like in the tutorial you made a while back. Moving in a long is faster, but i will write a second function for that so i can use both if needed. Thanks for the function anyway.
I have been reading a lot about fixed point numbers and i think i understand the basic theory behind it. What i don't get is how i get my "whole" number out of it. Examples are rare to find on google, but i will search some more.
Learning the genesis one bit at a time
you could borrow some code from sgdk i guess if you are totally out of luck
also for typesCode:#define FIX32_INT_BITS 22 #define FIX32_FRAC_BITS (32 - FIX32_INT_BITS) #define FIX32_INT_MASK (((1 << FIX32_INT_BITS) - 1) << FIX32_FRAC_BITS) #define FIX32_FRAC_MASK ((1 << FIX32_FRAC_BITS) - 1) #define FIX32(value) ((fix32) ((value) * (1 << FIX32_FRAC_BITS))) #define intToFix32(value) ((value) << FIX32_FRAC_BITS) #define fix32ToInt(value) ((value) >> FIX32_FRAC_BITS) #define fix32Frac(value) ((value) & FIX32_FRAC_MASK) #define fix32Int(value) ((value) & FIX32_INT_MASK) #define fix32Add(val1, val2) ((val1) + (val2)) #define fix32Sub(val1, val2) ((val1) - (val2)) #define fix32Neg(value) (0 - (value)) #define fix32Mul(val1, val2) (((val1) * (val2)) >> FIX32_FRAC_BITS) #define fix32Div(val1, val2) (((val1) << FIX32_FRAC_BITS) / (val2)) #define fix32Sin(value) sintab32[(value) & 1023] #define fix32Cos(value) sintab32[((value) + 256) & 1023] #define FIX16_INT_BITS 10 #define FIX16_FRAC_BITS (16 - FIX16_INT_BITS) #define FIX16_INT_MASK (((1 << FIX16_INT_BITS) - 1) << FIX16_FRAC_BITS) #define FIX16_FRAC_MASK ((1 << FIX16_FRAC_BITS) - 1) #define FIX16(value) ((fix16) ((value) * (1 << FIX16_FRAC_BITS))) #define round16(value) \ (fix16Frac(value) > FIX16(0.5))?fix16ToInt(value) + 1:fix16ToInt(value) #define intToFix16(value) ((value) << FIX16_FRAC_BITS) #define fix16ToInt(value) ((value) >> FIX16_FRAC_BITS) #define fix16Frac(value) ((value) & FIX16_FRAC_MASK) #define fix16Int(value) ((value) & FIX16_INT_MASK) #define fix16Add(val1, val2) ((val1) + (val2)) #define fix16Sub(val1, val2) ((val1) - (val2)) #define fix16Neg(value) (0 - (value)) #define fix16Mul(val1, val2) (((val1) * (val2)) >> FIX16_FRAC_BITS) #define fix16Div(val1, val2) (((val1) << FIX16_FRAC_BITS) / (val2))
DON'T FORGET TO GIVE CREDIT TO SGDK AND NOT ME! because it is NOT my workCode:#define s8 char #define s16 short #define s32 long #define u8 unsigned char #define u16 unsigned short #define u32 unsigned long typedef s16 fix16; typedef s32 fix32;
Are there any licensing issues you have to deal with to make a SuperTux port? GPL3 or anything?
There would be an "issue", if you would actually use the code from SuperTux. GNU GPL says,
you can use the code as you please, as long you distribute it at same conditions (GPL3 for example).
This is really no problem at all imo, just add the GPL3 text to the distributed package and put the
source code up somewhere or give an email address where people can mail you and ask for source.
Free software is generally much easier to deal with when it comes to licensing and legal stuff ; )
That's the whole reason it was born, to allow you the free usage and redistribution.
It helps that most of the stuff posted for working on the MD or 32X has a more permissive license; for example, all my 32X code is MIT license, which is about the same as BSD in that you can use it in closed source if you want. It's GPL v2/v3 compliant, so you can use it in GPL projects.
Where you have to careful with closed source projects is the libraries... LGPL is the library of choice there since LGPL sitpulates the LIBRARY code must remain open, but the program using it doesn't. Be wary of GPL libraries since those require the program using the library be open as well. Fortunately, most libraries are LGPL for just that reason, but a few are not. That was the problem with QT libraries - TrollTech had only two licenses for QT: commercial and GPL. Not LGPL, GPL. That's why very few commercial applications are available for KDE - KDE/QT is GPL and Gnome/gtk is LGPL.
The LGPL is somewhat useless on the Mega Drive though because there isn't dynamic linking at all. It's still different from the GPL in the sense that if your game is open source then the LGPL still won't be viral, but if the game is closed source it's gonna be difficulty to comply with the LGPL since you need to provide your own way to do dynamic linking and rebuild the ROM.
There are currently 1 users browsing this thread. (0 members and 1 guests)