New 32x game in development!

Importante releases or news for the communauty

Moderator: KanedaFr

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Mon Jan 23, 2023 7:15 pm

Chilly Willy wrote:
Sun Jan 22, 2023 6:03 pm
...
The palette is stored as B, G, R, A (where alpha may be optional). You're reading it backwards and not skipping the A byte. Also, BMP data is stored bottom to top.
...
Helps that I slowed down and re-read that! I now have the palette colors looking right. Now, I have to get it to draw in the correct direction. Below is the change to the marshw.c file (which still makes me wonder....this has to be used by doom today, why is it working for doom if things were backwards and not skipping the alpha?)

Code: Select all

	for (i = 0; i < 256; i++) {
		int16_t b = br + *palette++;
		int16_t g = br + *palette++;
		int16_t r = br + *palette++;
		int16_t a = br + *palette++;

		if (r < 0) r = 0; else if (r > 255) r = 255;
		if (g < 0) g = 0; else if (g > 255) g = 255;
		if (b < 0) b = 0; else if (b > 255) b = 255;

		unsigned short b1 = ((b >> 3) & 0x1f) << 10;
		unsigned short g1 = ((g >> 3) & 0x1f) << 5;
		unsigned short r1 = ((r >> 3) & 0x1f) << 0;
		cram[i] = r1 | g1 | b1;
	}
Here's the sprite now in all its color! Just upside down still lol...working on that next.
13.png
13.png (10.68 KiB) Viewed 338 times

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Tue Jan 24, 2023 2:09 am

Success! I've got the bitmap image flipped and the palette loaded all from a simple .bmp file added. Thanks Chilly for all the help! :) Just in case anyone is interested on what I did see below. I'll keep the mirrored function for later as I may use that when handling input. So in this small example I'm going to put in some input and move the spaceship left/right/up/down and when it goes up and down and flip the draw routines to mirror it

Below is the previous code (that i've renamed to Mirrored. As it's the mirrored version of the bmp that get's loaded)

Code: Select all

void drawSpriteMirroredVertically(u32* spriteBuffer, u16 x, u16 y, u16 xWidth, u16 yWidth)
{
	vu32* frameBuffer = (vu32*)&MARS_OVERWRITE_IMG;
	// dst frame buffer pointer (X + Y offseted, need to divide by 4 as we have 32 bit pointer here)
	vu32* dst = &frameBuffer[(0x100 + (y * 320) + (x + 256)) / 4];
	// src sprite pointer
	u32* src = spriteBuffer;

	const u16 qwidth = xWidth / 4;
	const int dstStep = 80 - qwidth;

	u16 row = yWidth;

	while (row--)
	{
		u16 col = qwidth;

		while (col--) *dst++ = *src++;

		dst += dstStep;
	}
}
Now, below is the new drawsprite function with the sprite actually displaying in the correct orientation

Code: Select all

	y += yWidth;
	vu32* frameBuffer = (vu32*)&MARS_OVERWRITE_IMG;
	// dst frame buffer pointer (X + Y offseted, need to divide by 4 as we have 32 bit pointer here)
	vu32* dst = &frameBuffer[(0x100 + (y * 320) + (x + 256)) / 4];
	// src sprite pointer
	u32* src = spriteBuffer;

	const u16 qwidth = xWidth / 4;
	const int dstStep = 80 + qwidth;

	u16 row = yWidth;

	while (row--)
	{
		u16 col = qwidth;

		while (col--) *dst++ = *src++;

		dst -= dstStep;
	}
Screen shot of mirrored
13.png
13.png (10.68 KiB) Viewed 330 times
And now, screen shot of correct orientation!
9.png
9.png (10.14 KiB) Viewed 330 times
Now, i'm moving on testing out handling some basic input and making the sprite move!

Chilly Willy
Very interested
Posts: 2962
Joined: Fri Aug 17, 2007 9:33 pm

Re: New 32x game in development!

Post by Chilly Willy » Tue Jan 24, 2023 8:51 am

The palette code in Doom works because Doom stores palettes as three bytes of R, G, B. BMPs don't. Doom doesn't use BMPs. If you use BMPs, you must alter the code to use them, as you discovered. :D

And to cero, BMP format doesn't compress the data unless you select RLE compression. And outputting as C just generates a large array of data with the image data - the same data you'd have if you incbin the data file. I find including binary images easier than dealing with huge C files with tons of arrays of data. Using BMP format is easy as the structure is simple and uncompressed, and allows others to see (and maybe modify) the art assets.

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Wed Jan 25, 2023 3:53 am

Chilly Willy wrote:
Tue Jan 24, 2023 8:51 am
The palette code in Doom works because Doom stores palettes as three bytes of R, G, B. BMPs don't. Doom doesn't use BMPs. If you use BMPs, you must alter the code to use them, as you discovered. :D

And to cero, BMP format doesn't compress the data unless you select RLE compression. And outputting as C just generates a large array of data with the image data - the same data you'd have if you incbin the data file. I find including binary images easier than dealing with huge C files with tons of arrays of data. Using BMP format is easy as the structure is simple and uncompressed, and allows others to see (and maybe modify) the art assets.
As always! Thank you:)

Good progress past few days. I've added a background with a new "drawbackground" function (still need to work on it some as it has the same problem as my sprites did being flipped....so for the time being I've just flipped my background .bmp since its for testing purposes). I added a few more sprites on the scene as well...one sprite being a 64x32 (representing twin ships in the middle as one sprite) just to make sure that each new .bmp file does actively pull in the same palette from my master.bmp file. So all in all, i have 4 separate sprite .bmps and 1 master .bmp that they all share the same palette with. Works nicely!

Then, I hooked up the input handling (using the I_readControls() from within marsnew.c). Just simple moving my main ship up/down/left/right. I have a boolean that tells the game loop to either drawsprite or drawspritemirrored function (which flips the ship facing up or down). I can probably just rotate the sprite like Vic does in his tilemapper demo, but i'll cross that bridge later. Now, it did seem like the I_reacControls seemed to be a little jittery on the x movment...i may have to tweak that. In some of my other sandbox projects i actually have a rather smooth input handling (but thats in the old 4.5.2 toolchain version).

Below is simple input controls within the main game loop

Code: Select all

//read buttons pushed
		buttons = I_ReadControls();

		//do something when pushed
		if (buttons & BT_DOWN)
		{
			y++;
			isFoward = false;
		}
		else if (buttons & BT_UP)
		{
			y--;
			isFoward = true;
		}

		if (buttons & BT_RIGHT)
		{
			x++;
		}
		else if (buttons & BT_LEFT)
		{
			x--;
		}
Screen shot of flying ship upwoards.
14.png
14.png (238.04 KiB) Viewed 300 times
Screen shot of flying ship backwards.
15.png
15.png (237.56 KiB) Viewed 300 times
Next up! Sound, I'm going to get some basic music playing and some sound effects (maybe thruster sound when ship moves). I suspect the audio part will be a pain, but I'm hoping I'll learn more of the sound functionality that has matured within the D32xr codest that i've distilled down. After that, I'll take a stab at some tilemapping, printing text to the screen in some sort of dialog box. Then, I plan on cleaning up all my testing code and will remove things that didn't work or don't need. At that point I should have a good "starter kit" for anyone to work with using the latest of Chilly's toolchain and all the goodies from D32xr.

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Wed Jan 25, 2023 5:29 am

So another quick update...going to bed after this one though as my brain is fried...

I started down the sound/music journey. I've found some .vgm files and got a vgm player just to make sure they are legit. They all work, so no issues there. I'm still fumbling/playing around with the code and I'm guessing I probably still have to initialize some things before this works below:

1) Added another file that i'm .incbin into my code (file is just called 1.vgm).

Code: Select all

extern uint8_t* music;
and then i'm calling this function from within Marshhw to "hopefully" start to play the file, but when i run it, nothing happens. So I'm guessing i'm missing some basic initializing. But, I also may have this simple example wrong too? It's outside of my main game loop.

Code: Select all

//testing music/sound
Mars_PlayTrack(0, 1, &music, (int)sizeof(&music), 0);
Any thoughts?

Chilly Willy
Very interested
Posts: 2962
Joined: Fri Aug 17, 2007 9:33 pm

Re: New 32x game in development!

Post by Chilly Willy » Wed Jan 25, 2023 9:04 am

Currently, VGMs need to be compressed, and cannot use the old PCM sample commands (they must use the new PCM stream commands). The current compression used is lzss with LZSS_BUF_SIZE set to 0x8000. The xgm tool can convert VGM with old PCM commands into the new form, IIRC.

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Wed Jan 25, 2023 11:29 pm

Chilly Willy wrote:
Wed Jan 25, 2023 9:04 am
Currently, VGMs need to be compressed, and cannot use the old PCM sample commands (they must use the new PCM stream commands). The current compression used is lzss with LZSS_BUF_SIZE set to 0x8000. The xgm tool can convert VGM with old PCM commands into the new form, IIRC.
I downloaded the xgmtool and ran my vgm file through that. I did both options of 1) Optimaize only so "xgmtool input.vgm output.vgm" 2) Convert to .xgm option "xgmtool input.vgm output.xgm" Both commands produces new files. In my vgm player i can still play the now compressed vgm file, but it doesn't play the xgm file. I'm assuming i should be able to use the new optimized vgm file within my code?

So after that I turned to implementing all the sound/music initialization (which essentially means just ucommenting code that I had previous commented out with marssound.c and systematically getting things to compile. But, even after (I believe its all init'd nothing plays) For a moment while i was figuring out the initialization process i actually got a buzzing sound coming out and got excited hahah; but that went away after i finished copying over all the sound init code.

Is my initial loading up the .vgm file correct? With the incbin and the extern char array and the actual call to play the music? Perhaps thats messed up?

thanks again Chilly!

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Thu Jan 26, 2023 3:26 am

I figured I'd post again with more details this time. I'll show some of the code below and were it's located.

1) The file i'm testing with i've called 1.vgm for testing purposes. Before running through the XGMTool it was 146kb and after it's 74kb. I've confirmed that it plays still compressed with my VGM player as i stated before (what I cannot confirm is if this compressed version of the file will work with Mars...would be nice if i had a simple music file already in the proper vgm format that is 100% confirmed to work)

2) Here is the music.s file where I've included the file

Code: Select all

.text
.globl _music

_music:
.incbin "1.vgm"
3) Here is the extern variable that references it

Code: Select all

extern uint8_t* music;
4) Here is the Init function being called right before my call to start the music. All right before my while(1) loop within my main method of marsonly.c file

Code: Select all

	//testing music/sound
	Mars_InitSoundDMA();
	Mars_PlayTrack(0, 1, &music, (int)sizeof(&music), 0);
5) Here's the Mars_PlayTrack function from within marshw.c

Code: Select all

void Mars_PlayTrack(char usecd, int playtrack, void *vgmptr, int vgmsize, char looping)
{
	Mars_UseCD(usecd);

	if (!usecd)
	{
		int i;
		uint16_t s[4];

		s[0] = (uintptr_t)vgmsize>>16, s[1] = (uintptr_t)vgmsize&0xffff;
		s[2] = (uintptr_t)vgmptr >>16, s[3] = (uintptr_t)vgmptr &0xffff;

		for (i = 0; i < 4; i++) {
			MARS_SYS_COMM2 = s[i];
			MARS_SYS_COMM0 = 0x0301+i;
			while (MARS_SYS_COMM0);
		}
	}
6) My void secondary() function is running the Mars_Secondary() just like D32xr ... so no change there.

So, i'm not entirely sure what's not working right. Feels like i'm missing something? Perhaps i'm not getting the size right on the Mars_PlayTrack call when using (int)sizeof(&music)? I just not sure how to get the size any other way if that's not correct.

Thanks again for any help chilly!

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Thu Jan 26, 2023 3:40 am

LOL...well i'm an idiot. I looked inside the D32xr content/VGM folder and found some .zgm files. I tried one and it worked!!! I got sound working (now i need to figure out how to compress my VGM's to ZGM's like with these examples. Chilly, you said i can use the Lzss library that's in the D32r project? or is there another tool that allows me to compress them...thought the xgmtool was compressing them, but I guess it was only "optimizing" them.

Chilly Willy
Very interested
Posts: 2962
Joined: Fri Aug 17, 2007 9:33 pm

Re: New 32x game in development!

Post by Chilly Willy » Thu Jan 26, 2023 9:22 am

You can't use xgm format, only vgm, so don't convert into xgm. Just optimize and leave as vgm. You should be able to use any lzss compressor as long as the window is set to 32KB. The lzss code with d32xr is a decompressor - it doesn't compress. I'm not sure which compressor Vic used on the music. There's lots of lzss compressors out there on the internet.

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Thu Jan 26, 2023 11:19 pm

Chilly Willy wrote:
Thu Jan 26, 2023 9:22 am
You can't use xgm format, only vgm, so don't convert into xgm. Just optimize and leave as vgm. You should be able to use any lzss compressor as long as the window is set to 32KB. The lzss code with d32xr is a decompressor - it doesn't compress. I'm not sure which compressor Vic used on the music. There's lots of lzss compressors out there on the internet.
As always your breadcrumbs got me where I needed to go! You mentioned Vic, so I asked him on discord what he used. He told me it was xgmtool...and then i was confused. Long story short, the newest xgmtool wasn't compiled and added to the latest tools with the latest SGDK build. the newest version (as of righting this post) has Vic's changes implemented within it! These changes allow for vgm to zgm compression. So now i was able to compress some music and test that out. works well!

So now my next challenge of sound effects. I'm sure i'm missing something but below I'll describe the situation as many laugh at my stupidity :)

1) Followed the code and I believe that S_StartSound() initializes a call to a sfx. it ultimately looks like the actual "Playing" of the sound effect only occurs within the S_StartSoundReal(). Both functions are within the marssound.c (which makes sense). I also noticed that within the StartSoundReal function it seems to be pulling the lump data from the rom for the sound effect. So this is where I want to make some changes for testing purposes

2) I added a simple wave file called 1.wav to the project. then within my new sounds.s file I've added the appropriate .incbin entry like i've done with other assets (music and graphics).

3) As I mentioned earlier, for testing purposes only, i'm pretty much just going to hardcode the sound effect whenever the StartSoundReal function get's called. So within that method I've made the below changes. The &sound is declared up above in marssound.c as "extern uint16_t* sound;" NOTE: I don't quite understand how the original code W_POINTLUMPNUM(sfx->lump) produces the sfx_t struct that is assigned to md_data...so i'm guessing magic lol or some sort of casting going on. i suspect the &sound assignment is probably wrong.

Code: Select all

static void S_StartSoundReal(mobj_t* mobj, unsigned sound_id, int vol, getsoundpos_t getpos)
{
	sfxchannel_t* channel, * newchannel;
	int i;
	int length, loop_length;
	sfxinfo_t* sfx;
	sfx_t* md_data;

	//test only
	sfx->singularity = false;
	sfx->priority = 64;
	md_data = &sound;

	newchannel = NULL;
	//sfx = &S_sfx[sound_id]; //TODO:  Build a new way of loading up game sounds
	//md_data = W_POINTLUMPNUM(sfx->lump); //TODO:  Build a new way of loading up game sounds
4) Then in my main loop i'm just simply calling a helper function Test_Sound that calls StartSoundReal() whenever the A button is pressed

Code: Select all

void Test_Sound(mobj_t* mobj, unsigned sound_id, int vol, getsoundpos_t getpos) {
	S_StartSoundReal(mobj, sound_id, vol, getpos);
}
call within main looop

Code: Select all

//Test sound with hitting a button
		if (buttons & BT_A)
		{
			//S_StartSound(NULL, 1);
			Test_Sound(NULL,1,64,NULL);
		}
So, the verdict...no sound haha. So, i'm guessing something is off but not quite sure where. Any thoughts? I'll keep testing/trying things.

Thanks again,

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Fri Jan 27, 2023 6:56 pm

Nevermind Chilly! Got it working :) Thanks for Vic for sharing that wave format of mono 8-bit PCM or ADPCM will only work with the mixer. I think the waves i was testing with were 16 bit. So i opened one up with Audacity and exported to 8-bit and it worked!

So anyone that is following this

md_data (which is the sfx_t struct) when referenced back to a wave file will work!

Now on to tilemapping (i'm sure this will be a journey as well) My hope here is that i can create a tilemap within a tool like Tiled and produce my overworld/towns/etc with that. As stated earlier i'm going to review Vic's tilemapper and see what I can learn:)

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Tue Jan 31, 2023 5:33 am

Hey everyone! Don't worry, I haven't given up my quest. Got bogged down with work and honey do lists :) Also, integrating Vic's Tilemapper into the solution has taken a little bit longer, but I've finally got it in there.

I brought in the functionality that was within the Hw_32x files into the marshw files...just to keep the file counts down. I created a separate folder structure just for yatssd so in the future when/if Vic makes adjustsments I "should" be able to add/update files as things change with little issue.

i will say by implementing his new function i had to use the initializing from within his tilemapper project over the mars_init as things just didn't look right. So, i'll take some time to see what some of the difference are between the two. Also, none of my previous draw functions work correctly after plugging in the tilemapper....however, Vic's sprite draw routines work VERY nice. so i may just abandon my old ones for these new ones.

My sound and music seem to be uneffected ... so that's a plus. Furthermore, my ability to use the pallette and bitmap info from bitmaps still work well (even passing to VIc's draw routines). His scaling effect will come in handy for some plans I have in my game.

Now, with that said, I do happen to have a few questions.

Chilly (or anyone else that may know):

1) Vic has this section of code that is called during his draw sprite functions. I'm actually rather lost on what it's doing. Any words of wisdom/clarity?

Code: Select all

void draw_handle_drawspritecmd(drawsprcmd_t *cmd)
{
    void* fb = (void *)((uint16_t *)(cmd->flags & DRAWSPR_OVERWRITE ? &MARS_OVERWRITE_IMG : &MARS_FRAMEBUFFER) + 0x100);
    draw_spritefn_t fn = draw_spritefn(cmd->flags);
    fn(fb, cmd);
}
2) What is the difference between the two framebuffers MARS_OVERWRITE_IMG and MARS_FRAMEBUFFER? When to use one over the other?

Thanks again everyone! Still some cleaning up to do after the integration. I'm also seeing how to work with the Object Layer from Tiled within Vic's Tilemapper. My hope is that I can: a) put in some collision, events, etc within the object map. b) find some way of having sprite AI running even when off camera but draw whenever the camera has the sprite in screen within Vic's Tilemapper. Currently when you draw a sprite it follows the camera around no matter were the x/y coordinates are.

Chilly Willy
Very interested
Posts: 2962
Joined: Fri Aug 17, 2007 9:33 pm

Re: New 32x game in development!

Post by Chilly Willy » Tue Jan 31, 2023 10:14 pm

The frame buffer always writes the data to the dram, except when a single byte of 0x00 is written. Byte writes of 0x00 are ignored. So in a sense, the plain frame buffer is an overwrite buffer when considered at a byte level. To clear the frame buffer, you have to write WORDS of 0x0000 instead of bytes of 0x00.

The overwrite buffer is like the frame buffer, but ignores all bytes of 0x00, even if written as a word. So writing 0xNN00 writes the NN, but ignores the 00. Likewise, 0x00NN ignores the 00 and writes the NN. 0x0000 means the entire word write is ignored. So the overwrite buffer is a true overwrite buffer.

The purpose of an overwrite buffer is to have transparent areas of the sprite not draw into the frame buffer. If you copy the sprite using byte writes, either the frame buffer or the overwrite buffer can be used as they will act the same. If you copy the sprite using words for better performance, 0 bytes WILL be written, not leaving transparent areas in the sprite. For sprite drawing with words, use the overwrite buffer to get transparent areas, even with word writes.

matthewnimmo
Very interested
Posts: 52
Joined: Thu Jan 07, 2021 8:04 pm

Re: New 32x game in development!

Post by matthewnimmo » Thu Feb 02, 2023 4:29 am

Chilly Willy wrote:
Tue Jan 31, 2023 10:14 pm
The frame buffer always writes the data to the dram, except when a single byte of 0x00 is written. Byte writes of 0x00 are ignored. So in a sense, the plain frame buffer is an overwrite buffer when considered at a byte level. To clear the frame buffer, you have to write WORDS of 0x0000 instead of bytes of 0x00.

The overwrite buffer is like the frame buffer, but ignores all bytes of 0x00, even if written as a word. So writing 0xNN00 writes the NN, but ignores the 00. Likewise, 0x00NN ignores the 00 and writes the NN. 0x0000 means the entire word write is ignored. So the overwrite buffer is a true overwrite buffer.

The purpose of an overwrite buffer is to have transparent areas of the sprite not draw into the frame buffer. If you copy the sprite using byte writes, either the frame buffer or the overwrite buffer can be used as they will act the same. If you copy the sprite using words for better performance, 0 bytes WILL be written, not leaving transparent areas in the sprite. For sprite drawing with words, use the overwrite buffer to get transparent areas, even with word writes.
Thanks Chilly! I'm still going to wrestle with this to learn more. Maybe this is a dumb question but where can I find resources for learning how to program for the SH2 and or in general the 32x? I'm thinking for assembly mainly i guess, since assembly can be different with each processor. Some of the links that used to be the "golden sources" are no longer available.

I'm also still wrapping my head around bit operations in general. In reviewing Vic's Tilemapper project in his description he mentioned he uses bit shifting for smoother scrolling. And i'm thinking, how does that work!? And why is that better than say each tick increment x/y coordinates by specified amount.


Now as for updates on my progress :)

1) Distilled version of the latest/greatest toolchain from D32xr code base - CHECK
2) Sprite Drawing functions that are not tied to Doom - CHECK
3) Ability to pull bitmap and palette data from a single .bmp - CHECK
4) Sound and Music working - CHECK
5) Knowledge of how to create Sound and Music formats that work with the toolchain - CHECK
6) Yatssd integrated into project - CHECK
7) Sprite placement within the map/world even when camera isn't at that location - CHECK
8) Basic AI - CHECK
9) Printing text for dialogs/menus/etc - CHECK (This seemed to be more challenging than i thought! Had to use Yatssd Hw32 Initilization before Text would even show up. Couldn't really use Doom method since it seemed pretty tethered to the Doom rom)

What's next?

1) More cleaning up to do
2) Build animated sprite functionality
3) Build out collision detection
4) Build out framework for game workflow (Game Start, Start/Options menu, Play, In Game Menus, Map transitions, Map to Battle and Battle to Map transitions, Story line, etc)

Hoping at that point I'll have a nice framework that: A) I can share with the community to tinker with. B) Start building my game from

Post Reply