Jump to content
IGNORED

Automatic Color Replacement Based on Region?


Cybearg

Recommended Posts

Is there a way to either:

 

1. Have a cartridge detect whether it is on a PAL or NTSC device and adjust its colors accordingly (but retain 60Hz), i.e. so that the reds for NTSC become an appropriate PAL red equivalent automatically?

 

or...

 

2. In bB, program the cartridge to automatically replace the colors it contains based on whether you're exporting to PAL or NTSC (so I don't have to have a separate PAL and NTSC version of every project)?

Edited by Cybearg
Link to comment
Share on other sites

In answer out of order, I'll say for number 2 you should be able to do something, and not have to have two projects. In assembly we often define a switch for our constants:

NTSC                    = 1  ; PAL = 0

  IF NTSC

COL_BLUE_BALLOON         = $98
COL_BROWN_BALLOON        = $28
COL_CYAN_BALLOON         = $A8
COL_GREEN_BALLOON        = $C8
COL_PURPLE_BALLOON       = $66
COL_RED_BALLOON          = $48
COL_YELLOW_BALLOON       = $1A

  ELSE

COL_BLUE_BALLOON         = $B8
COL_BROWN_BALLOON        = $28
COL_CYAN_BALLOON         = $98
COL_GREEN_BALLOON        = $58
COL_PURPLE_BALLOON       = $A6
COL_RED_BALLOON          = $68
COL_YELLOW_BALLOON       = $3A

  ENDIF

The PAL palette is more limited then NTSC. It doesn't truly have a yellow for example. If you want to scroll through the colors then in NTSC you have one column of black --> grey --> white values at $0x. In PAL you have those colors in 4 columns ($0x,$1x,$Ex,$Fx) so it looks unoptimized to simply scroll the palette by increasing a counter.

 

I use the following for NTSC to PAL color conversions:

;NTSC $0x = PAL $0x   no change
;NTSC $1x = PAL $2x <-- ($10to$18  PAL $30to$38)  ($1Ato$1F  PAL $2Ato$2F)
;NTSC $2x = PAL $2x   no change
;NTSC $3x = PAL $4x   +$10
;NTSC $4x = PAL $6x   +$20
;NTSC $5x = PAL $8x   +$30
;NTSC $6x = PAL $Ax   +$40
;NTSC $7x = PAL $Cx   +$50
;NTSC $8x = PAL $Dx   +$50
;NTSC $9x = PAL $Bx   +$20
;NTSC $Ax = PAL $9x   -$10
;NTSC $Bx = PAL $7x   -$40
;NTSC $Cx = PAL $5x   -$70
;NTSC $Dx = PAL $3x   -$A0
;NTSC $Ex = PAL $3x <--  -$B0
;NTSC $Fx = PAL $2x <--  -$D0

I suppose you could define every color in a header file and simply include that with any project, i.e.:

; Header file, include every possible color here as COL
  IF NTSC
COL62 = $62
COL64 = $64
COL66 = $66
  ELSE
COL62 = $A2
COL64 = $A4
COL66 = $A6
  ENDIF

And then in your project include the header file and define your color constants however you do it in BB. I think you use CONST of something like that, but I'll just write it how I normally would:

 

;color switch below, use 1 for NTSC colors, and 0 for PAL colors

NTSC_COLORS = 0

include colors.h

 

COL_PURPLE_BALLOON = COL66 ; automatic color conversions done by changing switch above

COL_RED_BALLOON = COL44 ;

Link to comment
Share on other sites

I forgot to answer number 1. In short there is no way for the Atari to determine if it is playing on an NTSC or PAL TV, unfortunately.

 

 

However, if the end user has a Harmony cart set up in the regular menu mode, then you can write some code to detect whether the PAL, PAL60, or NTSC bios is being used. Circus AtariAge does this to pay the Harmony cartridge a tribute. :) If you start Circus AtariAge up on your harmony (through the menu mode) then you will see a small surprise. ;) Other cartridges should also be detectable, like the Krok cart, though I have never tried.

Link to comment
Share on other sites

Here's an idea....

 

Is there some combination of colours such that in NTSC you can't distinguish between the two?

And is there some other combination such that in PAL you can't easily distinguish between the two?

 

For example, two colours A,B which are very close in NTSC (say, greens) and in PAL are quite different (say, green, red)

And ditto for C,D colours in PAL....

 

Then you could create a "please press this to start" button (well, two) onscreen, only one of which will be visible in NTSC, and the other only visible in PAL.

The user is clearly probably going to "press" the button which she can see.

Not quite "auto detect" but would be a bit of fun to see if it's workable :P Haven't thought this through far enough to be bothered looking up colours.... but thought I'd throw it out there.

 

Instead of buttons it could be some entry system (say, a pipe like in mario bros.)....

 

 

 

 

Link to comment
Share on other sites

You could also make it selectable from the titlescreen, and restore/save the value on boot. Alex Herbert specified the first page of AtariVox static memory as a "TV settings", and used it as such in Man Goes Down.

 

If you want to change the color values on the fly in bB, you'll need to wrap each color command with an if...then.

Link to comment
Share on other sites

If you want to change the color values on the fly in bB, you'll need to wrap each color command with an if...then.

That would be a problem. While it may work great for a larger game with space to spare, I'm tweaking my compilation, which consists of a ton of 4k games that are down to 0-20 bytes for each 4k bank. I'll have to go with Omega's style on this one, I think.

Link to comment
Share on other sites

I made a header file today for every possible color. I included every value from 0 to 255, even though only even colors count in reality (bit 0 is not used for the color registers).

 

 

colors.zip

 

 

 

Basically there is a switch inside called COL_NTSC. Make that 1 for NTSC colors, and 0 for PAL colors. You should be able to move that switch into your source so that you never have to open up the file. Just make sure it is above the include so that it will compile:

REM Inside my BB source,
REM I removed the COL_NTSC switch from colors.h and placed it here...
REM I kept the switch above the include so that there are no compile problems.

COL_NTSC  = 1
   include colors.h


REM colors are easy to change now!

const COL_SPIDER = COL_C6
const COL_HEART = COL_44
const COL_SKY = COL_AC

Finally I hope that this compile in BB, as I haven't tried it at all... :ponder:

  • Like 2
Link to comment
Share on other sites

Here's an idea....

 

Is there some combination of colours such that in NTSC you can't distinguish between the two?

And is there some other combination such that in PAL you can't easily distinguish between the two?

 

For example, two colours A,B which are very close in NTSC (say, greens) and in PAL are quite different (say, green, red)

And ditto for C,D colours in PAL....

 

Then you could create a "please press this to start" button (well, two) onscreen, only one of which will be visible in NTSC, and the other only visible in PAL.

The user is clearly probably going to "press" the button which she can see.

Not quite "auto detect" but would be a bit of fun to see if it's workable :P Haven't thought this through far enough to be bothered looking up colours.... but thought I'd throw it out there.

 

Instead of buttons it could be some entry system (say, a pipe like in mario bros.)....

 

 

 

 

 

NES games run faster or slower in PAL or NTSC, right? 50hz vs 60hz? Could some sort of game speed counter be set up on the 2600 to tell if it's running PAL or NTSC?

 

I apologize in advance for confusing platforms and concepts :)

Link to comment
Share on other sites

It doesn't seem to compile for me. I tried including colors.h right in the bB file, then right after 2600header in an includes file, but regardless of where I put it, bB had a problem with the COL_NTSC = 1 line.

 

It doesn't recognize the COL_XX colors, either.

Edited by Cybearg
Link to comment
Share on other sites

Try changing

 

COL_NTSC = 1

 

to

 

const COL_NTSC = 1

 

 

It won't recognize any of the colors until that switch is understood by the compiler.

 

 

Edit: I just tried const COL_NTSC = 1 and it worked! I also found out I needed one space preceding the word "const".

 

Edit2: now it doesn't seem to work with the COLUBK = xx unless it's right in the source.

Link to comment
Share on other sites

 

NES games run faster or slower in PAL or NTSC, right? 50hz vs 60hz? Could some sort of game speed counter be set up on the 2600 to tell if it's running PAL or NTSC?

 

I apologize in advance for confusing platforms and concepts :)

Short Answer: No. The refresh speed is determined by the number of scanlines. On the Atari this is independent of the console region. Playing a standard PAL game on an NTSC Atari will output an NTSC formatted signal at 50Hz with wrong color palette, causing most NTSC tube TVs to roll when playing a PAL game. Most HDTVs don't roll on "NTSC50" but since the picture is taller they will generally just cut off the bottom portion of the screen. Playing NTSC titles on a PAL Atari will also yield wrong colors and a PAL60 formatted signal which most modern Euro TVs can handle assuming they accept a proper RF signal.

 

This behavior is different to most later consoles where the PPU is locked into exactly 50 or 60 Hz. For NES, assuming there is no region lock, it will play any region games at the console's default speed, slowing NTSC games played on PAL systems, and speeding up PAL games played on NTSC systems, with occasional glitches or incompatability due to timing issues. Color palettes are the same for both regions fortunately although the hue/contrast may differ slightly. Many PAL games were ported unoptimized and play slower than their NTSC counterparts, although a few PAL games contained corrections to the music and physics to account for the difference in frame rate. Those optimized games will often be slightly sharper pitch audio and play at a faster pace. Some multiregion NES homebrews can detect the region of the NES by counting CPU clock cycles.

 

Unfortunately, it is impossible to detect the region of an Atari console through software. Most hombrews that support multiregion run either NTSC or PAL 60 and use the B/W switch to set the region. Color setting for NTSC; B/W for PAL is the standard convention, however including two sets of color indexes will generally bloat the code. Many games opt for separate NTSC and PAL60 releases.

  • Like 1
Link to comment
Share on other sites

Try changing

 

COL_NTSC = 1

 

to

 

const COL_NTSC = 1

 

 

It won't recognize any of the colors until that switch is understood by the compiler.

 

 

Edit: I just tried const COL_NTSC = 1 and it worked! I also found out I needed one space preceding the word "const".

 

Edit2: now it doesn't seem to work with the COLUBK = xx unless it's right in the source.

Yes, I get it to compile as well if I define it as const COL_NTSC = 1 and then include the colors.h, but it doesn't seem to allow me to use any of the COL_XX definitions for anything. If I try to define something, it claims it doesn't know what COL_40 means.

 

EDIT:

 

Ah-ha! If I include colors.h like this:

 

 

 const COL_NTSC  = 1
 asm
 include colors.h
end

 

... THEN it works and I can use the COL_XX definitions all I like. It just doesn't work if I include directly into bB, probably because then it's trying to read that ASM code in BASIC.

 

Thanks for the awesome include, Omega!

Edited by Cybearg
  • Like 1
Link to comment
Share on other sites

You know, a long time ago I suggested a list of pre-made constants for colors. All you had to do was cut-and-paste either the NTSC or PAL set into your bB code at the beginning. No inline assembly.

 

Maybe a combination of Mr Davies "make the player choose which notice is visible" and my constants would work.

 

 

The problem with my suggestion is that the screen sizes are different for different TV systems.

Are there resolutions/refresh rates compatible with both? PAL50 is 312 lines, NTSC60 is 262. It's a gotcha I didn't realise till after I made the suggestion.

You'd need some sort of display which would work on both a NTSC and PAL TV without changes.

Link to comment
Share on other sites

Yes, I get it to compile as well if I define it as const COL_NTSC = 1 and then include the colors.h, but it doesn't seem to allow me to use any of the COL_XX definitions for anything. If I try to define something, it claims it doesn't know what COL_40 means.

 

EDIT:

 

Ah-ha! If I include colors.h like this:

 const COL_NTSC  = 1
 asm
 include colors.h
end

... THEN it works and I can use the COL_XX definitions all I like. It just doesn't work if I include directly into bB, probably because then it's trying to read that ASM code in BASIC.

 

Thanks for the awesome include, Omega!

Tested and confirmed as working here too. :) It looks like a very clean solution now.

Link to comment
Share on other sites

Hm... It seems to have some problems sometimes. For instance, this works:

 

 

 temp6 = (counter & 7) * 2
 if !scoreshow then scorecolor = COL_40 + temp6 else scorecolor = COL_90 + temp6

 

... But this transforms the colors into 4 and 0 (decimal), respectively:

 

 

 if !scoreshow then scorecolor = COL_44: sc1 = p0sc1: sc2 = p0sc2: sc3 = p0sc3 else scorecolor = COL_9C: sc1 = p1sc1: sc2 = p1sc2: sc3 = p1sc3

 

For whatever reason, it's misreading COL_44 and COL_9C. Same if I change them to, say, COL_40 and COL_90, but they DO work if I just put $44 and $9C. Any idea what's wrong, there?

 

 

.L0196 ;  if !scoreshow then scorecolor  =  COL_44 :  sc1  =  p0sc1 :  sc2  =  p0sc2 :  sc3  =  p0sc3 else scorecolor  =  COL_9C :  sc1  =  p1sc1 :  sc2  =  p1sc2 :  sc3  =  p1sc3
 
LDA keepbits
AND #8
BNE .skipL0196
.condpart76
LDA COL_44
STA scorecolor
LDA p0sc1
STA sc1
LDA p0sc2
STA sc2
LDA p0sc3
STA sc3
 jmp .skipelse10
.skipL0196
LDA COL_9C
STA scorecolor
LDA p1sc1
STA sc1
LDA p1sc2
STA sc2
LDA p1sc3
STA sc3
.skipelse10
Link to comment
Share on other sites

Alright, I found a way around this problem.

 

Unfortunately, it seems that a lot of direct uses of the included constants don't work. I'm not sure what the pattern is, but something causes things like colorvar = COL_44: COLUP0 = colorvar to, more often than not, result in an incorrect color.

 

I've managed to reliably fix this by assigning the included constant to another, in-code constant, then using THAT, like so:

 

const RED = COL_44

colorvar = ReD: COLUP0 = colorvar

 

This seems to work every time.

 

Using the included constants in data sets/arrays has never caused any problems for me yet, so that's fine:

 

data colorlist

COL_44, COL_54, COL_64

end

 

player1colors:

COL_44

COL_54

COL_64

end

 

... etc. This all works fine.

Link to comment
Share on other sites

The bB interpreter is seeing a non-numeric value and assuming its a variable/memory location. This is reasonable behavior if you stick to bB constructs, instead of trying to mix dasm symbols into the brew.

 

Even in assembly language, its ambiguous whether "COL_44 = $44" is a zero page memory location or value, until the assembly programmer specifies which it is when they try to access it.

 

Anyway, bB uses "const" to track symbols that should be interpreted as values. To trick bB into always taking your dasm symbols as values, you can also define them all as bB constants:

 

const COL_00 = COL_00

const COL_08 = COL_08

...

Link to comment
Share on other sites


.L0196 ; if !scoreshow then scorecolor = COL_44 : sc1 = p0sc1 : sc2 = p0sc2 : sc3 = p0sc3 else scorecolor = COL_9C : sc1 = p1sc1 : sc2 = p1sc2 : sc3 = p1sc3

LDA keepbits
AND #8
BNE .skipL0196
.condpart76
LDA COL_44
STA scorecolor
LDA p0sc1
STA sc1
LDA p0sc2
STA sc2
LDA p0sc3
STA sc3
jmp .skipelse10
.skipL0196
LDA COL_9C
STA scorecolor
LDA p1sc1
STA sc1
LDA p1sc2
STA sc2
LDA p1sc3
STA sc3
.skipelse10

Is this your assembly code? It looks like you missed the pound sign for loading immediate.

Try like this:

LDA #COL_9C

 

Link to comment
Share on other sites

The bB interpreter is seeing a non-numeric value and assuming its a variable/memory location. This is reasonable behavior if you stick to bB constructs, instead of trying to mix dasm symbols into the brew.

 

Even in assembly language, its ambiguous whether "COL_44 = $44" is a zero page memory location or value, until the assembly programmer specifies which it is when they try to access it.

 

Anyway, bB uses "const" to track symbols that should be interpreted as values. To trick bB into always taking your dasm symbols as values, you can also define them all as bB constants:

 

const COL_00 = COL_00

const COL_08 = COL_08

...

Ah, yes. That's basically what I did, though I didn't think to re-define it as its own name.

 

 

Is this your assembly code? It looks like you missed the pound sign for loading immediate.

 

Try like this:

LDA #COL_9C

 

That's the auto-generated code that bB spits out, yeah.

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