Jump to content
IGNORED

How to change some sprite colors to black


Descolado

Recommended Posts

Hi, sorry my english.

I'm working in a homebrew and I have some questions.

I need change the sprite color ("PI" sprite only) from RED to BLACK. My program have a COLISION DETECTION algorith (COLISION procedure).

I found some routines in this forum to change background color (CHANGECOLORTERRAIN procedure). It's work fine, but... If I run CHANGECOLORTERRAIN procedure, my MOB can't detect PI sprite and will fall.

I believe that its happen because when BACKTAB(I) change color sprite to black, it "replace" card values to other value and my "PI" cards desapear, right?

 

INCLUDE CONSTANTS.BAS

 

'MOB
CONST M1 = $0807 + 0 * 8 'MOB stopped

 

'OBJETOS
CONST OO = 0

CONST PI = $0802 + 1 * 8 'Terrain
CONST OB = $0807 + 2 * 8 'Objects

CLS
MODE 0,0,0,0,0

WAIT
DEFINE 0,1, player
WAIT
DEFINE 1,2, Objetos

 

X = 75
Y = 72

 

SCREEN Tela1

 

LOOP:
SaveY = Y
WAIT
SPRITE 0, X + HIT + VISIBLE, Y + ZOOMY2, M1

GOSUB Colision
IF Terrain = 0 THEN Y = Y + 1 ELSE Y = SaveY

IF CONT1.right THEN X = X + 1
IF CONT1.LEFT THEN X = X - 1

'REM GOSUB ChangeColorTerrain

GOTO LOOP

COLISION: Procedure
'Low Right Botton
#LRB = (X-1)/8 + (Y)/8 * 20
'Low Left Botton
#LLB = (X-8)/8 + (Y)/8 * 20

#CS5 = PEEK($0200 + #LRB)
#CS6 = PEEK($0200 + #LLB)

'If the foots touch the Terrain, the fall stop
IF (#CS5 = PI) OR (#CS6 = PI) THEN Terrain = 1 ELSE Terrain = 0
END

 

ChangeColorTerrain: PROCEDURE
FOR I = 0 TO 239
#MCard = PEEK($200 + I)
IF #Mcard = PI THEN
#BACKTAB(I)=(#BACKTAB(I) AND $07f8) + $3e00
END IF
NEXT I
END

Tela1:

DATA PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI
DATA PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI
DATA PI,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,PI
DATA PI,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,PI
DATA PI,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,PI
DATA PI,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,PI
DATA PI,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OB,OO,PI
DATA PI,OO,OO,OB,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OB,OO,OO,PI
DATA PI,OO,OB,OB,OB,OO,OO,OO,OO,OO,OO,OO,OO,OO,OO,OB,OO,OO,OO,PI
DATA PI,PI,PI,PI,PI,OO,OO,PI,PI,PI,PI,PI,PI,OO,OO,PI,PI,PI,PI,PI
DATA PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI
DATA PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI,PI

player:

BITMAP "...##..."
BITMAP "...#...."
BITMAP ".#####.."
BITMAP "...#...."
BITMAP "...#...."
BITMAP "...###.."
BITMAP "..#...#."
BITMAP ".#....#."

Objetos:

BITMAP "########"
BITMAP "##....##"
BITMAP "#.#..#.#"
BITMAP "#..##..#"
BITMAP "#..##..#"
BITMAP "#.#..#.#"
BITMAP "##....##"
BITMAP "########"

BITMAP "########"
BITMAP "##....##"
BITMAP "#......#"
BITMAP "#......#"
BITMAP "#......#"
BITMAP "#......#"
BITMAP "##....##"
BITMAP "########"

 

I know that I can create a new "PI" sprite using BLACKCOLOR and use the two sprites in my Colision procedure:

 

CONST PB = $0800 + 2 * 8 'Terrain black
IF (#CS5 = PI) OR (#CS6 = PI) OR (#CS5 = PB) OR (#CS6 =PB) THEN Terrain = 1 ELSE Terrain = 0

 

But I have a LOT of sprites that I need change color to BLACK.

 

Sorry if I was not very clear.

 

DATA command only use CONSTANTS? Can I use DATA with VARIABLES?
How change the color from "PI" sprite with no change my MOB behavior?

Edited by Descolado
Link to comment
Share on other sites

Hi, Descolado,

 

I will read your question with more care to fully understand what you are asking. In the meantime, may I ask, what is your native language? I noticed the use of the word "objetos"... ¿Hablas español?

 

Pues si es así, puedes hacer tu pregunta en castellano si deseas. Somos varios acá que hablamos esa lengua.

 

-dZ.

Link to comment
Share on other sites

It's because you're comparing the cards read with PI value, but if you change the background color, you must compare against the new value.

 

Just make sure to compare with both values.

 

DZ, I'm BRAZILIAN. I don't speak spanish. Google translate help me to write in english.

 

Nano, thanks. Your tip worked fine (for while!!!).

 

I use this routine to change sprites color:

 

FOR I=0 TO 239

#BlackCard= PEEK ($200+I) 'get the backtab card information

IF #BlackCard = PI1 THEN

#BlackCard = #BlackCard/8 'delete the first 3 bits

#BlackCard= #BlackCard*8 'add the 3 zero to the first 3 bits

POKE $200 + I,BlackCard 'write the result back to the backtab

END IF

NEXT I

 

In my COLISION procedure I used:

 

IF (#CS5 = PI1) OR (#CS6 = PI1) OR (#CS5 = #BlackCard) OR (#CS6 = #BlackCard) THEN Terrain = 1

 

Nano, I'm using your (amazing) INTELLIVISION PROGRAMMING BOOK to create a platform Game. I loved the MONKEY MOON program example and I'm using this algorithm.

 

Untitled 3

 

I will post a GIF to show as the program soon (surprise! rsrsrsrs).

  • Like 2
Link to comment
Share on other sites

DZ, I'm BRAZILIAN. I don't speak spanish. Google translate help me to write in english.

 

Aha! Well, the translation was fine and it worked. :)

 

I use this routine to change sprites color:

 

FOR I=0 TO 239

#BlackCard= PEEK ($200+I) 'get the backtab card information

IF #BlackCard = PI1 THEN

#BlackCard = #BlackCard/8 'delete the first 3 bits

#BlackCard= #BlackCard*8 'add the 3 zero to the first 3 bits

POKE $200 + I,BlackCard 'write the result back to the backtab

END IF

NEXT I

 

First, those are not sprite cards, those are background cards (the Background Table or BACKTAB exists at location $200).

 

Second, that seems like a very inefficient way to clear the first three bits. Internally, the Intellivision divides and multiplies by powers of two using bit-shifting instructions. However, these can only shift one or two bits at a time. Shifting three bits right (divide) then shifting them back to the left (multiply) will take four shifting instructions, which is a bit expensive.

 

Not only that, but it also discards the upper three bits. The BACKTAB words only use 14 bits, but you still run the risk of discarding bit #13 which may be important.

 

Third, in Color Stack mode (MODE 0), which you are using, the foreground color of BACKTAB words is stored in four bits, not three: it includes the rightmost three bits and bit #12:

    13   12    11   10    9    8    7    6    5    4    3    2    1    0   
  +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ 
  |Adv.|FG   |GRAM|           GRAM/GROM Card #            |   FG Color   | 
  |col |Bit3/|GROM|    (0-255 for GROM, 0-63 for GRAM)    |   Bits 0-2   | 
  |stck|     |    |                                       |              | 
  +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ 

To address all this, I recommend using a mask instead to clear the foreground color. It is not only a lot faster, it is also a lot safer.

  #BlackCard = #BlackCard AND $EFF8 ' clear foreground color bits

That will set the foreground color to black, which is color value $00, by clearing all the bits used for the foreground.

 

If you decide to change to a different color later, you can just add it afterwards, since the mask will take care of clearing the color bits first.

  #BlackCard = (#BlackCard AND $EFF8) + $02 ' clear foreground color bits and add Red

Let us know if you have questions. :)

 

-dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

Oh man, I have A LOT of questions [rsrsrsr], but at moment all is working (thanks to Nanochess and your great book).

I'm using this game to LEARN programming in INTYBASIC. After follow the Atariage forum for several years I create courage to start my first game.

 

I spent weeks studying the STIC (registers X, Y and A). I don't understand many things but I learned how it work, using binary codes to change "flags" and change the sprites behavior, positioning cards in GRAM or using GROM. It's fun.

 

I created a (very) complex colision detection system (the game require), I don't make idea if is the best way but all is working fine at moment. My PLAYER can detect colision agains a lot of static cards with no use COL0 and HITSPRITE, can divert, get around, grab and others things. Now, I will drawing the screens and test my player against other cards.

 

Thanks for his feedback, is very important have support from the masters of assembler (man, how can you understand all this? [rsrsrss])

Link to comment
Share on other sites

To help you understand the STIC a little better, checkout Color Stack Fiddler. It's intended for new developers to play with the STIC chip in color stack mode. There is ROM as well as IntyBASIC source code.

http://atariage.com/forums/topic/285618-color-stack-fiddler

Thanks Lathe! I will look.

 

I have one question to Nanochess: How many screens I can put in my BAS file using the Monkey Moon system? My game will have a lot of screens. PITFALL had 255 screens, can I put 50 or 100 screens in my code or I need create other file and use "include"?

Link to comment
Share on other sites

Thanks Lathe! I will look.

 

I have one question to Nanochess: How many screens I can put in my BAS file using the Monkey Moon system? My game will have a lot of screens. PITFALL had 255 screens, can I put 50 or 100 screens in my code or I need create other file and use "include"?

Four full screens use 2K of memory (1K of words), so your limit without paging and not counting game code would be 84 screens (84kbyte ROM file)

 

I would suggest to compress screens as byte, so two bytes fit in a word, duplicating your maximum to 168 screens. (this is the method I've used in Sydney Hunter and the Sacred Tribe to fit 100 screens)

Link to comment
Share on other sites

If you need more screens, consider how much they have in common and if you can develop procedural routines to draw screens based on coordinates, length, type of character etc instead of restoring an entire screenful of cards. Perhaps you'll come up with some golden middle, where you have a few basic screens to work with, and then procedural routines to draw the details that differ. If you think this sounds complicated, perhaps aim at fewer screens to start with.

  • Like 1
Link to comment
Share on other sites

Four full screens use 2K of memory (1K of words), so your limit without paging and not counting game code would be 84 screens (84kbyte ROM file)

 

I would suggest to compress screens as byte, so two bytes fit in a word, duplicating your maximum to 168 screens. (this is the method I've used in Sydney Hunter and the Sacred Tribe to fit 100 screens)

 

Sorry but I didn't understood exactly what you mean. When you say "word" you are talking about "variable type"? I know that when I use "A = 0" is diferent than "#A = 0" because the char "#" means 16 bits (can store a big value).

But I think that's not what you meant.

Link to comment
Share on other sites

Sorry but I didn't understood exactly what you mean. When you say "word" you are talking about "variable type"? I know that when I use "A = 0" is diferent than "#A = 0" because the char "#" means 16 bits (can store a big value).

But I think that's not what you meant.

I'm talking about memory used. One byte is 8 bits, but Intellivision works with words (16 bits = two bytes)

 

Every value inside a DATA statement uses one word = 16 bits. If you want to save space, you need to fit two bytes inside a word and use a table to translate the byte value to the card value for screen.

Link to comment
Share on other sites

I'm talking about memory used. One byte is 8 bits, but Intellivision works with words (16 bits = two bytes)

 

Every value inside a DATA statement uses one word = 16 bits. If you want to save space, you need to fit two bytes inside a word and use a table to translate the byte value to the card value for screen.

 

By his question, I think he is also asking if there is a limit to the size of a particular module file in IntyBASIC, and if so, if he needs to break his code into multiple include files.

 

I believe there is no such limit in IntyBASIC, but even if there were, since it injects include files in-line, I wouldn't expect that splitting them would make any difference.

 

In any case, I do not think anybody should worry about the size of their source files. You are bound to run out of variables, memory, or ROM space before that happens. ;)

 

-dZ.

Link to comment
Share on other sites

  • 2 weeks later...

I'm talking about memory used. One byte is 8 bits, but Intellivision works with words (16 bits = two bytes)

 

Every value inside a DATA statement uses one word = 16 bits. If you want to save space, you need to fit two bytes inside a word and use a table to translate the byte value to the card value for screen.

 

If I will call ONE TABLE (one screen) per time, why I need save space converting WORD to BYTE? (I don't know how do it). I can have 100 tables in my code, if I will call this tables using GOSUB or SCREEN I shouldn't need save space because I don't will use all screen in same time.

 

I replicated 100 TABLES inside my code to simulate the 100 screens from my game. The Intybasic compiles but the JZINTV show a black screen. I don't understand. Is Intybasic loading to memory all tables in run-time?

Link to comment
Share on other sites

If I will call ONE TABLE (one screen) per time, why I need save space converting WORD to BYTE? (I don't know how do it). I can have 100 tables in my code, if I will call this tables using GOSUB or SCREEN I shouldn't need save space because I don't will use all screen in same time.

 

It doesn't matter if you only use one screen at a time, if you store a table in ROM using DATA statements, they all take up space because they are all stored in ROM at the same time.

 

What nanochess is suggesting is to "compress" your screen data by packing two bytes (2 x 8-bits) on each DATA statement (16-bits), so that you conserve ROM space. A modern Intellivision cartridge can hold up to 42K words (16-bit words) of ROM, which is a lot, but it is still not an unlimited resource.

 

100 screens at about 500 words each comes to about 50K words -- half of which is empty (since only half of each 16-bit word is used per DATA statement).

 

If you don't know how to do this, we can help, just ask. :)

 

I replicated 100 TABLES inside my code to simulate the 100 screens from my game. The Intybasic compiles but the JZINTV show a black screen. I don't understand. Is Intybasic loading to memory all tables in run-time?

 

That's probably because your data tables are larger than the default ROM segment. Those 42K words of ROM I mentioned above are splintered into multiple segments, which are not contiguous in memory. Unfortunately, IntyBASIC does not do this automatically for you.

 

I will leave it to others to provide additional assistance and sample code to deal with this situation.

 

-dZ.

Link to comment
Share on other sites

I wonder if using some compression routine like the ones newcoleco has developed over at the Colecovision forum (DAN1, DAN2, DAN3), would be reasonable here. That means unpacking data on the fly and storing into the BACKTAB. Not sure if it would be efficient in compiled BASIC or some CP-1610 guru would have to write that routine in machine code. It probably would be slower than the lookup table Nanochess is suggesting, but possibly it could save more space and one wouldn't have to convert 100+ levels, just compress them. The beauty with using SCREEN on data already stored as screen cards is that is the fastest way we can do it from BASIC, any sort of processing of data will make it slower.

Link to comment
Share on other sites

I wonder if using some compression routine like the ones newcoleco has developed over at the Colecovision forum (DAN1, DAN2, DAN3), would be reasonable here. That means unpacking data on the fly and storing into the BACKTAB. Not sure if it would be efficient in compiled BASIC or some CP-1610 guru would have to write that routine in machine code. It probably would be slower than the lookup table Nanochess is suggesting, but possibly it could save more space and one wouldn't have to convert 100+ levels, just compress them. The beauty with using SCREEN on data already stored as screen cards is that is the fastest way we can do it from BASIC, any sort of processing of data will make it slower.

 

I discussed it with him once, and it seems like for Intellivision screen data it would be much better to come up with a custom algorithm based on DAN2. We also agreed that it may help to start with something simple, like Run Length Encoding (RLE) and see how far it takes you.

 

-dZ.

  • Like 1
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...