Closed FredYeye closed 4 months ago
This footage confirms the effect is in the arcade version https://youtu.be/ZkoQj_f0ato
The F3 video is very complex (and probably needs a rewrite at some point) so I don't really blame you for having a hard time with it; Taito really pushed the boat out with the design.
Almost everything on the system can be controlled per-line, there are often other registers which control the behavior of the registers you're looking at etc.
Of course highlighting specific cases like this, with video evidence, and notes on the register use is a good way of working out how things should really work.
Gekirindan appears to use this effect as well.
Glowing logo: https://youtu.be/1HOTZ9BAjiA?t=22 The orange ship gets brighter as it fades away: https://youtu.be/1HOTZ9BAjiA?t=65
Edit: Puchi carat also uses this. At the very least it's used to brighten the intro text. There is a dimmed area during gameplay that could be a candidate as well, but not 100% about that one, as the entire line array is the same value at that time. Haven't really looked closer there.
I've slowly been looking at this issue with one of the FB Neo devs. FB Neo has a hack that makes the lights almost work, which gave me some clues about where in the code I should look.
I can now see that the 0x6200 area values are in fact being read, but are not being used in some cases in MAME. 0xB000 (labelled Playfield priority) has a blend mode field, and no blending is being done (afaict) if it's set to 0x3000 = Normal blending mode.
Clearly blending is still supposed to happen though, so maybe there's some misunderstanding about how these blend modes are supposed to work. This is where we're currently at.
Potentially a duplicate of MT bug reports, pick your poison:
Additional acknowledged stuff here:
Last but not least, this:
TL;DR: you are trying to describe TC0650FDA (the scanline priority & palette mixer) from the wrong perspective here.
Not entirely sure what you're trying to say but I can see that this driver needs some love, haha.
I'm saying that there must be a reason about each one of these bugs happening, trying to analyze from the perspective of one game only isn't the right approach. List of things that comes on top of my head atm, without even digging the reports:
Note: I've already tried a couple times to come up with something for a couple of these bugs above to no avail, I find the code to be kinda hard to follow in places and I've converted the whole thing to 16-bit accessors some years ago.
brightness:
puchi carat was a good one to find, shows that 7400 ("sprite clipping") high bits are related
during gameplay, sets 6200 brightness/alpha A7FF
over all lines,
then sets 7400: 8310
on lines with the darkened sprite panels (0310
otherwise)
possibly a/b select by priority(? like alpha control). something like
0x7400: Sprite clipping
<...
0x0100 = Affects interpretation of inverse mode bits. If on, 1 = invert. if off, 0 = invert.
0x0200 = unknown - maybe analogous to xb000 0x2000 ("0x3000")?
0x0c00 = seems analogous to xb000 0xc000 blend mode select?
0x1000 = brightness mode for sprites with pri value 0x00 ?
0x2000 = brightness mode for sprites with pri value 0x40 ?
0x4000 = brightness mode for sprites with pri value 0x80 ?
0x8000 = brightness mode for sprites with pri value 0xc0 ?
gekirindan
elevator action returns
this time all playfields' pri values are 300x
[001_]
playfield 3, which is the only one that should be affected, has the alpha blend mode set on tiles here too.
original post has better notes about the value transition, but copying a few here for relevant reference material
value | output |
---|---|
BB[B]B | ![]() |
BB[F]B | ![]() |
7B[7]B | ![]() |
(from https://youtu.be/7WD-ftK-Dgk?t=6728)
most likely: add and clamp, steps of 32
789A B
FEDC
color + (256/8)*(4−(n-7))
from these cases, my guess would be that each word in 6200 (currently called alpha_level
) is split like
[B][A][B][A]
B = brightness, 7 (lighter) to F (darker)
A = alpha, 7 (transparent) to F (opaque)
but scanline_draw
reads them like this:
[a][b][c][d]
and seems to consider the b,d set alpha 'a' and c,a 'b'? so there might be a misunderstanding there
if (alpha_mode[i] == 2) { if (alpha_type == 1) { /* if ([b] == 0 && [d] == 255) * alpha_mode[i]=3; alpha_mode_flag[i] |= 0x80; } * will display continue screen in gseeker (mt 00026) */ if ([b] == 0 && [d] == 255) alpha_mode[i] = 0; else if ([b] == 255 && [d] == 0) alpha_mode[i] = 1; } else if (alpha_type == 2) { if ([a] == 0 && [c] == 255) alpha_mode[i] = 0; else if ([b] == 255 && [d] == 0 && [a] == 255 && [c] == 0) alpha_mode[i] = 1; } else if (alpha_type == 3) { if ([b] == 0 && [d] == 255 && [a] == 0 && [c] == 255) alpha_mode[i] = 0; else if ([b] == 255 && [d] == 0 && [a] == 255 && [c] == 0) alpha_mode[i] = 1; } } else if (alpha_mode[i] == 3) { if (alpha_type == 1) { if ([d] == 0 && [b] == 255) alpha_mode[i] = 0; else if ([d] == 255 && [b] == 0) alpha_mode[i] = 1; } else if (alpha_type == 2) { if ([c] == 0 && [a] == 255) alpha_mode[i] = 0; else if ([d] == 255 && [b] == 0 && [c] == 255 && [a] == 0) alpha_mode[i] = 1; } else if (alpha_type == 3) { if ([d] == 0 && [b] == 255 && [c] == 0 && [a] == 255) alpha_mode[i] = 0; else if ([d] == 255 && [b] == 0 && [c] == 255 && [a] == 0) alpha_mode[i] = 1; } }y still has no idea what `::dpix_*_*` are trying to do at this point... one other thing worth mentioning, arabianm, all pfs `7xxx` [011_] except misbehaving text layer (vram) `b00f` [101_] so alpha mode 3 and alpha type 1, i think? and then since 6200 is `000F`, `else if ([d] == 255 && [b] == 0) alpha_mode[i] = 1;` triggers? so i have a kind of suspicion that the alpha blending code might be responsible for that ---
Wow, good stuff! It's been a while since I looked at this, so I don't have any new insights for you... busy with life stuff, heh.
from these cases, my guess would be that each word in 6200 (currently called alpha_level) is split like [B][A][B][A] B = brightness, 7 (lighter) to F (darker) A = alpha, 7 (transparent) to F (opaque)
This sounds like a good theory to me. It does seem to be grouped into 4-bit values at least.
I don't know if i ever posted this anywhere (on fb-neo, maybe), but I made a similar data table for gekirindan. I guess you already have the values but I'll post it here anyway.
gekirindan
hex | binary | effect / time
------------------------------------------
0BFB | 0000 1011 1111 1011 | default
77FF | 0111 0111 1111 1111 | 3f ship fade effect
87EF | 1000 0111 1110 1111 | 4f
97DF | 1001 0111 1101 1111 | 4f
A7CF | 1010 0111 1100 1111 | 4f
B7BF | 1011 0111 1011 1111 | 4f
C7AF | 1100 0111 1010 1111 | 4f
D79F | 1101 0111 1001 1111 | 4f
E78F | 1110 0111 1000 1111 | 4f
F77F | 1111 0111 0111 1111 | 3f
F87E | 1111 1000 0111 1110 | 4f
F97D | 1111 1001 0111 1101 | 4f
FA7C | 1111 1010 0111 1100 | 3f
FB7B | 1111 1011 0111 1011 | 4f
FC7A | 1111 1100 0111 1010 | 4f
FD79 | 1111 1101 0111 1001 | 4f
FE78 | 1111 1110 0111 1000 | 24f ship fade effect end (goes back to default after this)
same data but different view (easier to see ramping effect)
column 1: 0 | 789ABCDEFFFFFFFF
column 2: B | 77777777789ABCDE
column 3: F | FEDCBA9877777777
column 4: B | FFFFFFFFFEDCBA98
layer 1: ?
layer 2: orange ship (inside)
layer 3: orange ship (outside)
layer 4: star field?
hm, starting to reconsider these values being cleanly split into brightness and alpha after reading more.
i'm not entirely sure, but the specific way m_alpha_s
combines the values seems like (if correct) a way to trade more line-level alpha channels for increased resolution, which doesn't sound implausible... the implication being that the 6200 'channels' are also shared, sort of generic parameters?
...regardless, i'm starting to think that considering brightness as completely separate from alpha might be the wrong way to approach this...
probably have to look at some alpha blending examples/value transitions the same way to re-verify everything in here, at this point... gseeker continue screen is another good case to check.
Bubble Memories may be also a good test case:
Bubble Memories may be also a good test case:
that effect seems to use 6a00 (not 6200), possibly multiply/addition blend modes...? not described in mame.
maybe not a good test case so much as the only test case for an entirely different set of blend modes.
edit: oh hey, and kaiserkn uses 5800 during the clipped intro animation. also, i think all of the "Where bit 0 of x enables effect on playfield 1" etc. documentation is misleading, because they're probably subsection enables.
I don't really have anything substantial to add right now, but I guess this is the best place to dump various F3 things for now?
At the end of elvactr stage 5, the brightness should increase before the screen goes completely white. These are the 0x62xxxx writes that happens in the setup function for this effect:
addr | old -> new | PC
626030 | 00FF -> 00FF | 1436AA
626230 | BBBB -> 77FF | 1436DE // increase brightness
626430 | 7000 -> 7000 | 143712
620432 .. 6205FE | 180F -> 1800 | 143746 // 620430 remains 180F
627230 | 300F -> 300F | 14377A
627430 | 0300 -> F300 | 1437AE
627630 | 26AE -> 16AE | 1437E2
620632 .. 6207FE | 1C0F -> 1C00 | 143816 // 620630 remains 1C0F
// increase brightness over the next frames
77EE to 626230 (PC=14386A)
77DD to 626230
77CC to 626230
77BB to 626230
77AA to 626230
7799 to 626230
7788 to 626230
7777 to 626230
Another thing. Many F3 games have a ram/rom check function. These are the names that function uses for the 0x62xxxx area:
620000 - 620FFF: "line set ram"
621000 - 621FFF: "pivot port"
622000 - 62FFFF: "line data ram"
The pivot port name would suggest it's related to pivot ram (0x630000). The pivot port & ram checks are right next to each other as well.
taito_f3_v
has this to say about 0x621000 currently:
0x1000: Unknown control word?
(usually 0x00f0; gseeker, spcinvdj, twinqix, puchicar set 0x0000)
I don't really have anything substantial to add right now, but I guess this is the best place to dump various F3 things for now?
It is yeah, also the OP can be edited to tasks given this is a pretty big user story.
621000 - 621FFF: "pivot port"
note that this area is still rw, see e.g. tcobra2 POST @ 0x000b48. i wouldn't be surprised if this only omits 'ram' for brevity, or something.
622000 - 62FFFF: "line data ram"
regarding line data ram starting at 622000 (as opposed to the known start in 624000), one hypothesis is that the line data sections can be entirely remapped:
(MAP_BYTE - 0x10) * 0x400
0x620000 + MAP_BYTE * 0x400
gives address of the data sections cleanlyof course, it doesn't really affect existing emulation cases whether or not line ram can be remapped, and it sure doesn't seem like a very useful feature to have. but it would be a good test to have in a hw test regardless.
i hesitate to write down assumptions like this because there's already so much incorrect guessing about this machine out there, some of which i've already contributed to this very thread, but this one at least adds meaning to previously meaningless bits and gaps ...
i'm still around, just busy.
after my previous work i've [also] come to the conclusion that the future of taito f3 emulation in mame requires a proper rewrite of at least the drawing routines.
maybe there's low-hanging fruit still like what i did before but the current code is not maintainable... some things are just bad and some things don't map conceptually and some things are so convoluted in the name of optimization that correctness is unobtainable.
i intend to begin to address this in a draft pr this weekend, but will probably be late december to conclude it.
the future of taito f3 emulation in mame requires a proper rewrite of at least the drawing routines.
Sounds about right! I look forward to your draft. 👀
I think updating the "line ram memory map" documentation would do a lot as well. Making it easier to see where each region starts and ends, and what each group of bits in each region do would be nice.
Edit: I think something in this style could look good for documentation:
0400 - 05FF: Line control for 6000 section (256 * 16-bit values)
???? ???? ???? ??ts
s: latch sprite alpha value
t: latch tilemap alpha value
0600 - 07FF: Sprite control (256 * 16-bit values)
???? ???? ???? ????
0800 - 09FF: Zoom line control (256 * 16-bit values)
???? ???? ???? pppp
p: effect on/off toggles for playfields 1-4
Though preferably this would also be done by someone with a better understanding than me! Haha.
one hypothesis is that the line data sections can be entirely remapped
Right, i see what you mean by this. If none of the known games use this feature we'd have to run tests on real hw to verify. Arabianm
actually writes 0x040F to line set ram on boot... but immediately clears it. 😂
Regarding bubble memories... the data in 6800-6FFF looks suspiciously similar to what's in 6000-67FF, or is it just me? Is it really just a second set of data...? Not sure how probable or useful that would be... I can't tell if that effect could be done with just 6000-67FF.
Amazing! Many people I know like the F3 games and they'd sometimes mention the video bugs, so it's cool to get to see these changes actually happen.
Fantastic work, ywy & 12Me21!!
While they have more changes in the works, this issue is essentially resolved (or at the very least outdated), so I'll go ahead and close it now.
Elevator Action Returns has a visual effect that currently isn't emulated in mame: upon shooting the lamps hanging from the ceiling, the lights on that floor are supposed to go out.
I disassembled some of the code for the lamps and figured out that it's writing to 0x626200: line ram, offset 0x6200. _taito_f3v.cpp labels this area as "Alpha blending control", but it seems to go unused (to me, who is unfamiliar with the code, anyway). I don't know what that is supposed to mean, but it appears to be 256 16-bit values (one u16 per line).
I looked at the effect in the saturn port to have some kind of reference as to what it's supposed to look like. Not the best as it could differ, but it seems identical. These are the values that gets written to line ram -
Looking at the values makes me think that each nibble is some kind of control per layer. For now I'll just call it brightness control, as that is the effect they achieve. Two columns stay the same throughout this effect and two change. Layers 1 & 4 are not supposed to be affected. Layer 3 should change brightness. I don't know what layer 2 is, it's not used in stage 1. Might be something that changes brightness in later stages.
I guess my question here is, should I keep going with this? For now I've at least documented my findings, but I obviously can't know what the real PCB does with these values. I'm tempted to play around with the source code and attempt to apply the brightness control, but I'm at a loss as where to start. _taito_f3v.cpp is not a crazy long file but I'm having a hard time following the code, never having looked at mame's codebase before.
Any help or comments are appreciated! If this data isn't enough try anything yet, let me know too.
-Fred