Jump to content
IGNORED

bkcolors Kernel Hack


CurtisP

Recommended Posts

What I still yearn for, that would be almost universally useful, is a command that splits the background color on a specific line. So that I can use the background for ie the sky and the ground, or the sky and the ocean, and still have a multicolored playfield in front of it. I would be able to use that in pretty much every project I have.

 

I found 7 cycles free when using player1colors but not playercolors. I couldn't fit a simple split in there, but what I could fit was a seperate background color for each playfield line.

 

I replaced the line

	sleep 7

with

 
lda bkcolor-84,x;4
sta COLUBK;3

 

The value 84 is valid only if pfres is not being used.

 

Now the complicated part. At the end of your program, put

  asm
 if (<*) > (<(*+84))
 repeat ($100-<*+84)
 .byte 0
 repend
 endif
bkcolor
 byte 0, 0, 0, 0 
 byte 2, 0, 0, 0
 byte 4, 0, 0, 0
 byte 6, 0, 0, 0
 byte 8, 0, 0, 0
 byte 10, 0, 0, 0
 byte 12, 0, 0, 0
 byte 14, 0, 0, 0
 byte 16, 0, 0, 0
 byte 18, 0, 0, 0
 byte 20, 0, 0, 0
end

 

replacing the number after each byte with the background color for that line.

 

Remember you must be using kernel_option player1colors, but not playercolors. This should slso work fine with pfcolors.

bkcolors.bas

std_kernel.txt

Link to comment
Share on other sites

What I still yearn for, that would be almost universally useful, is a command that splits the background color on a specific line. So that I can use the background for ie the sky and the ground, or the sky and the ocean, and still have a multicolored playfield in front of it. I would be able to use that in pretty much every project I have.

 

I found 7 cycles free when using player1colors but not playercolors. I couldn't fit a simple split in there, but what I could fit was a seperate background color for each playfield line.

I tried it with pfcolors. Neato! :)

 

Michael

post-7456-1189141631_thumb.png

Link to comment
Share on other sites

I tried it with pfcolors. Neato! :)

 

I'm thinking that since this uses the same technique as pfheights and pfcolor together, and there are two bytes left in each entry of the table for those, that this should be incorporated into the standard compiler and kernel. I know what changes to make to the kernel, but the compiler code just scares me.

Link to comment
Share on other sites

Why do you have have to use the player1colors option? I generally don't use colored sprites because those missiles come in handy.

 

It's specifically because missile1 is not available. Usually all the cycles available to the kernel have been used up. The code for missile1 uses 15 cycles, if playercolors are used, then the missile1 code is disabled and the playercolors code takes it's place, the code for each player taking 7 cycles each. When just player1colors is used and not playercolors, then there is 8 cycles of NOPS replacing the player1 color code. This is where I stuffed the bkcolor code.

 

By the way, anytime using one option causes another option to no longer be usable, it may be possible to swap that second option with another one you don't need with a kernel hack.

Link to comment
Share on other sites

How does this code work with a' const pfres = 32' or 'const pfres = 24' command?

It was designed around the standard playfield resolution, so I have no idea what it will do. It might even crash. In any case. I'm pretty sure the background stripes will not match the foreground stripes.

I tried it last night with "const pfres = 32," but I couldn't get it to work. Basically, the playfield colors changed as desired, but the background color didn't change at all. However, it may be that I was doing something wrong, because it seems to me that it *ought* to work.

 

Michael

Link to comment
Share on other sites

I tried it last night with "const pfres = 32," but I couldn't get it to work. Basically, the playfield colors changed as desired, but the background color didn't change at all. However, it may be that I was doing something wrong, because it seems to me that it *ought* to work.

 

Actually it really shouldn't work. I remember now what the deal with pfres is. The code references a specific offset from the value in the X register, which I found through trial and error. When using a pfres other than default, the offset varies by the pfres. I couldn't figure out the exact formula for figuring out the offset, so I just left it unimplemented for different playfield resolutions. It's entirely possible to make it work with different pfres, but I'll leave that to someone else.

 

This is really just a proof of concept hack more than anything else. The right way to do this would be to include it in the pfheights+pfcolors routine as I mentioned before. Then the calculations are already done, and it's not using up any more space.

Link to comment
Share on other sites

I like this mod, but I still find 32x11 to be pretty useless.

 

I can't believe that a mod that allows me to change the value of COLUBK once, on a specific scanline would be more difficult.

 

If you only want to change it on a particular line, I found a hack to do that in early versions of Insane Painter. I think I was setting the one of the TIA registers in bB with a wierd value (0x - I have no idea what bB converted the x into). Then the ball would change the playfield color.

Link to comment
Share on other sites

Ok, I just spent the last four hours creating a new bkcolor kernel hack.

 

This one does not require playercolors, etc. In fact it will only work if playercolors are all off.

 

Now the background color is changed on every horizontal line. All you need to do is create a data table names bkcolor.

 

The only downside is that you lose missile1.

bkcolor.zip

bkcolor.bas.bin

Link to comment
Share on other sites

I can't believe that a mod that allows me to change the value of COLUBK once, on a specific scanline would be more difficult.

 

Then go ahead and do it.

 

If I could I definately would have already. I was hoping you would explain why one is more difficult than the other. Since you quoted me in the post i figured you would be ok with feedback and questions. So far this hack is useless to me because I don't use 32x11 resolution for anything, but I'm still impressed.

 

I do almost always use the player colors option though. I really like the new mod except for that reason, and that I can't think of any background that I would want to display for an entire game including title screen. Is there a way to turn this off and on, or use it more than once per game?

Also, a table that includes values for every horizontal line takes up a lot of space. Can you give me any tips on how to alter this mod so that the table only contains four values, with the first and third being color values, and the second and fourth being the scanline on which they start?

Edited by MausBoy
Link to comment
Share on other sites

I was hoping you would explain why one is more difficult than the other.

 

In a nutshell. The kernel has to write to the TIA registers everytime it wants something in the scanline to change. This includes, the data for both sprites, turning the missiles on and off and the playfield bits. In fact, in order to draw different patterns into the playfield, it has to write the playfield pattern twice every line. Each scan line lasts for 76 machine cycles and the average machine instruction (which can manipulate one byte of data) takes an average of 3 seconds. So you only have 25 instructions per scan line. In fact, there isn't enough time to manipulate the players and missiles in 1 line, so missles are done in one and players in another, so each screen line in a bAtari Basic program is actually two scanlines. this is also why missiles appear to be offset by a half line from players.

 

So, if we want the kernel to be able to do anything else each scan line, we have to swap out one of the existing functions for the new one. Also, timing is critical - every isntruction must happen at the same time. Thus a routine that decrements a counter, then does a lookup can be easily implemented, but one that does an if (like what you are suggesting) can take a variable number of cycles, and will break the following code, which is wait makes it nigh-impossible.

Link to comment
Share on other sites

So, if we want the kernel to be able to do anything else each scan line, we have to swap out one of the existing functions for the new one. Also, timing is critical - every isntruction must happen at the same time. Thus a routine that decrements a counter, then does a lookup can be easily implemented, but one that does an if (like what you are suggesting) can take a variable number of cycles, and will break the following code, which is wait makes it nigh-impossible.

 

Timing isn't always critical; for some parts of the kernel it is, while for others it isn't. On the other hand, conditional code tends to take more cycles than unconditional code. For example, if Y is a scan-line counter that runs 0-95 and we want all scan lines black except for one that's supposed to be green, one could use code like:

  lda #0  ; Black
 cpy #47 ; The line we want green
 bne not_green
 lda #$C8 ; Green
not_green:
 sta COLUBK

That will take eleven cycles if the color is supposed to be green, or ten if it isn't. Equalizing the delay may or may not be necessary; if it is necessary it will increase code size. On the other hand, suppose there's a table that lists the color for every scan line. Then the code becomes:

  lda line_colors,y
 sta COLUBK

That will take seven cycles, unconditionally. It's now necessary to add a 96-byte table, but there are four more cycles available on the line to perform other functions.

 

Note that if you wanted to color a range of lines, the comparison-based code would take even longer to execute, but the table-based approach would still take seven cycles. But even more impressively, even if you need to have the colors change based upon various conditions, if you can afford the space for the tables and two bytes of RAM for a pointer, you can handle even many tricky situations in only eight cycles.

Link to comment
Share on other sites

  • 2 months later...
If you only want to change it on a particular line, I found a hack to do that in early versions of Insane Painter. I think I was setting the one of the TIA registers in bB with a wierd value (0x - I have no idea what bB converted the x into). Then the ball would change the playfield color.

 

 

Do you remember how you did it? I would still find that really useful.

Edited by MausGames
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...