Jump to content
IGNORED

Stackable Display Kernels


ZackAttack

Recommended Posts

I am building a stackable kernel framework that will make it easier to take advantage of the new elf file support in the UCA based carts. The idea is to have a json file that specifies how to parse all the asset files. Each asset can specify 2600 and 7800 variations. A python script will parse the json file, then parse the png files and generate all the asset code for you. Then you simply pass the asset id to the various display kernel functions. Each game can have one or more frames. Each frame can be composed of one or more display kernels. Frames and kernels would be created once at the start. Each kernel will have a set of functions that can be used to change its appearance. For example, you can call a function to change the text displayed by the text kernel. The kernels would stack vertically to produce a full 192+ lines of visible screen.

 

Here is some pseudocode to demonstrate what it would look like. Is this easy enough to read and understand? Is this a good approach?

game()
{
	// puts atari in known state and configures display kernels for the current system type (2600,7800, NTSC, PAL)
	init_display_kernels();

	// Set the type of controller we want to use
	set_controller_type(controller_type_joystick);

	// make some display kernels
	char36 status_line = create_char36(lines, color_blue, color_white);
	asym_pf play_area = create_asym_pf(height, color_wall, color_black, color_monkey, color_banana);
	asym_pf_blit_p0(play_area, asset_tree, 0, x, y); // Set this now since it doesn't change

	// make a frame composed of the display kernels
	display_kernel frame_lv1[2] = { status_line, play_area };

	// define some variables for our game to use
	input_joystick joystick_state;
	int p0_score = 0;
	int p1_score = 0;
	char score[5];

	while (1) {
		// *** Update display kernels based on game state ***
		// Update the text that char36 will display for both player scores
		int_to_str(p0_score, score, 5);
		char36_write(status_line, 0, 0, 5, score);
		int_to_str(p1_score, score, 5);
		char36_write(status_line, 31, 0, 5, score);

		// Move and animate sprites
		asym_pf_blit_pf(play_area, asset_clouds, frame_index, x, y);
		asym_pf_blit_p1(play_area, asset_monkey_jumping, frame_index, x, y);

		// *** Feed instructions and/or DMA data to Atari during visible screen ***
		// Draw a single frame and capture user input
		draw_frame(frame_lv1);

		// *** Update game state based on user inputs and previous state
		// Handle user input
		move_player(prev_joy0, joy0, p0);
		move_player(prev_joy1, joy1, p1);

		// Time based stuff
		if ((frame_count & 0xf) == 0) {
			frame_index++;
		}
	}
}

 

Edit:

2023-01-25 Incorporated some of the changes suggested by @splendidnut

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

I would decouple the frame drawing from the input gathering.  They are two different things.  I know that's probably a convenient way of doing it due to switching between the 6507 and the ARM, but there's got to be a better way to handle that.

 

I'm probably being a bit overly critical here, but the naming conventions don't read nicely:

 

Original:  dk_asym_pf_blit_pf          ->  Display kernel, asymmetric playfield, blit playfield
  
Example:   blit_pf_into_dk_asym_pf     -> Blit playfield into a display kernel asymmetric playfield

   OR, better yet

Example:   dk_blit_asym_pf             ->  Display kernel: blit into asymmetric playfield

 

 

On a side note, while reading the comments, I felt the use of the word 'make' doesn't provide enough clarity.  I see it more as creating a bunch of display kernel definitions and then building a display list with them.

 

 

Overall, I think the approach looks good.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

39 minutes ago, splendidnut said:

I would decouple the frame drawing from the input gathering.  They are two different things.  I know that's probably a convenient way of doing it due to switching between the 6507 and the ARM, but there's got to be a better way to handle that.

 

Yeah, that's why I combined them. That way the game code never puts itself in a position where it can get the two out of sync. However, I could add set_input_type() and get_last_input() functions and implement them so they don't directly interface with the 6507.

 

45 minutes ago, splendidnut said:

I'm probably being a bit overly critical here, but the naming conventions don't read nicely:

 

Original:  dk_asym_pf_blit_pf          ->  Display kernel, asymmetric playfield, blit playfield
  
Example:   blit_pf_into_dk_asym_pf     -> Blit playfield into a display kernel asymmetric playfield

   OR, better yet

Example:   dk_blit_asym_pf             ->  Display kernel: blit into asymmetric playfield

 

No, it's a valid point. I was thinking it would be useful to prefix everything in a way that it makes auto-completion work well.  blit_pf_into_asym_pf() is more readable. If we assume each kernel will reside in its own header/source files, then it should be easy enough to find the available functions for a specific kernel. It's probably better to favor more readable names.

 

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...