1

Ok, here is the theory of the chunky-mode I use in our demo 'DIFF'.
it's quiet simple - abuse the palette-ram with some special sprites! grin

some ideas for use this in a game:
- raycasting (wolf3d, doom...)
- mode7 (snes) racing game like mariokart or f-zero
- semi 3d tunnel-shooter like stardust
- simple voxel-engine (go to '1:00')

chunkyex_0_o.png

Examples - precompiled (check mame/roms/puzzledp), needs mame & vasmm68k

there are to examples:
- simple (like the image above)
- advanced, different mappings (used in 'DIFF')

'DIFF' uses the advanced one but copy is done in VBLANK-routine with some doublebuffering.

Youtube

pro:
- very flexible (75x50, 60x60, 90x42...)
- mix different pixelsizes (3, 3, 3, 4...) to stetch

con:
- only 30fps (some tearing) -> write only to palette-ram during VBLANK, only ~130 palettes can by copied without random pixels on screen (snow) - frame #1 => copy upper screen half, frame #2 => copy lower screen half
- need 40 sprites (75x50)
- need a lot of palette-ram

2

-

3

That is truly amazing and a very creative way to use the hardware and bypass its limitations top - thanks a lot for sharing the details and code.
When my Hypernoid project is finished, I think that I will focus on learning ASM and doing something in 3D with your render method.
Would it be maybe possible to increase the resolution with bankswitching? According to the wiki the hardware seems to have 2 banks of 256 palettes https://wiki.neogeodev.org/index.php?title=Palette_RAM

4

Clever smile

I don't know much about the NeoGeo, but could you use the HBLANK as well to update palettes?
Is your palette-writing code optimized?
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

5

-

6

NeoHomeBrew, doing all the 3d-math-stuff in ASM ist not that easy, it's better to use C instead.

Zerosquare, maybe there is a faster way to copy all the palettes but I unrolled the complete loop so it's already fast.
It's possible to update 2 colors during hblank, enough to create a rainbow screen or c64-style-rasterbars but will not help that much.

7

You can win some time moving the vram update code inside vblank interrupt, before BIOSF_SYSTEM_IO (this thing is slow).

Will still need 2 frames to process whole colors, but will free some time for other sprites stuff. Probably ~190 palettes on frame A, then ~60 palettes + other updates on frame B.

8

Orion_ > really? This seems strange ; if movem was slower than move, nobody would use it smile

blastar > on an Atari ST (8 MHz 68000) it is possible to update 16 colors during HBLANK. It requires agressive optimizations but it can be done smile
So it's a bit surprising that only 2 colors can be updated on the NeoGeo.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

9

HBLANK is 128 cycles Best case scenario would be moving out 10 or 11 colors, if you time things perfectly. (protip: you won't. IRQ timing is variable).

Not enough to cover a display line, so that's not happening.

10

Hmmm, bit of theory crafting:

VBLANK, load in the top ~190palettes.
Then you have to load remaining colors during HBLANKs before the raster catches up to the lower section. ~6 colors/HBLANK could maybe fit (didn't do the exact math).

Have to find a very efficient setup scheme for data to be processed during HBLANK, or you'll end up wasting way too much cpu time on this.

11

You can't use it to prepare a whole display line, but you could use it in addition to the VBLANK code to set more palette entries (at the bottom of the screen). As long as you write the palette entries before they're used by the display, it should work.

I don't know if that's worth it, it's just an idea smile

EDIT : ah, I see you figured it out smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

12

-

13

HPMAN, you are right, BIOSF_SYSTEM_IO is slow, I did not recognize that fact. in DIFF is used the copy-routine after BIOSF_SYSTEM_IO but that makes no difference (for me), without any other tricks it's not possible to copy 250 palettes within one frame. a complete update within one frame would be nice, no more tearing! smile

14

Nice to see the tech behind the demo explained, and even with source code! Thanks blastar!
avatar

15

freem, I think this is only fair, your released code helped me alot to restart with all this stuff - take something - give something! wink

some other hint:
switch pal-bank in the half of screen to double resolution... I did this with 20fps but did not use it in DIFF because even MAME was not able to emultate this without any flaws... maybe i did something wrong.

16

blastar (./15) :
switch pal-bank in the half of screen to double resolution... I did this with 20fps but did not use it in DIFF because even MAME was not able to emultate this without any flaws... maybe i did something wrong.
Does it work on the real system?

17

yes, it's possible to switch pal-bank during HBLANK without any random pixels. It works on real hardware but in MAME there is a small line with wrong colors visible... some sort of delay?

18

Mame rasters are line based.
My guess is you need to trigger the switch earlier for timing to be ok in mame.

19

Hi, I just joined to take part in this discussion, as I'm also interested in improving this chunky mode. smile

Is there a way to switch off sprite or general gfx rendering on a per-line basis? As I've seen for chained sprites setting the height to 0 would disable it. Would changing height a rasterline later show it again? And would palette writes cause no color noise during scanlines not displaying any sprite?

If that's the case, we could simply switch off the sprite rendering every other scanline and write the palette data instead. If not, there would still be some scanlines left between the different sprite blocks (e.g. in a non-vertically-interleaved pixel mapping). Higher res would lower pixel mapping requirements anyway.

20

There should be pixel noise whichever the sprite setup is.

Maybe it can be avoided on CD systems by turning off display, never tested.

21

Hello, welcome. smile
I have tested this on real hardware - no sprites on screen but random pixels. sad

22

blastar (./21) :
Hello, welcome. smile
I have tested this on real hardware - no sprites on screen but random pixels. sad
Thanks for testing. That's bad. What about the following registers?
REG_DISBLSPR equ $FF0111 ;byte: 0/1 disable sprites
REG_DISBLFIX equ $FF0115 ;byte: 0/1 disable fix layer
REG_ENVIDEO equ $FF0119 ;byte: 0/1 enable video output

23

on real hardware:

move.b #1,REG_DISBLSPR
move.b #1,REG_DISBLFIX
=> black screen with random pixels

move.b #0,REG_ENVIDEO
=> black screen without random pixels confus

maybe its possible to disable screen in every 2nd line... this will look like scanlines sad but we can update & use more colors. I will this tomorrow on real hardware..

another idea: (needs REG_LSPCMODE timer)
- disable screen at bottom of chunky-screen
- copy all 250 palettes (dont wait for VBL)
- enable screen at top of chunky-screen

24

I think disabling spr and fix layer issues the background color (can be any color, not only black), hence random pixels because system reads BG color value.

Disabling whole video output forces black regardless of BG color, video ram isn't read, so no pixels?

25

Not 100% sure how the CD video chip works, but yeah I guess REG_ENVIDEO still allows CPU access to palette RAM and sets the video output to all zeros.
Random pixels appear because CPU has priority over rendering, so if they don't appear but the writes do work, then there's something forcing output to zero after the palette RAM.
avatar
Je fais des trucs. Des fois ça marche, des fois ça marche pas.

26

As long as your in NTSC mode you have 16 lines off the bottom of the screen before vblank you can also use to update the palettes without snow. Using REG_LSPCMODE you can make a wait loop and wait for the first scanline off the bottom of the visable screen (0x01F0). Now start updating the palettes before vblank triggers. You might just have enough this way.

I would suggest it may be more of an advantage to disable vblank interrupts for this kind of thing and always use a REG_LSPCMODE check to keep sync with video timing by waiting for scanline 0x01F0 for this demo (or 0x00F8 for standard vsync) . Like HPMAN says BIOSF_SYSTEM_IO is slow, if you require this call move it into the visable screen area after the palette updates have completed.

I am not sure what the exact timing is when in PAL mode because the dev wiki states 2 different things. On the timings page it states 16 lines more at the top and bottom of screen (https://wiki.neogeodev.org/index.php?title=Display_timing) while on the FIX page (https://wiki.neogeodev.org/index.php?title=Fix_layer) it kind of suggests 8 lines more only. There is no mention of an 8 line border at the top and bottom of the screen.


swapw1 move.w REG_LSPCMODE,d1
move.b d0,REG_DIPSW ; Kick watchdog
lsr.w #7,d1
sub.w #$1f0,d1
bne.s swapw1 ; Wait for bottom border
www.universebios.com

27

Razoola, thanks for suggestion.
updating 250 palettes takes more time than expected - i have to disable screen while updating... works very well and it's pal-save! smile
(re)moving BIOSF_SYSTEM_IO saves some rasterlines but not enough.
with this code it's possible to update all palettes within one frame... this small multicolor-effect runs now with 60fps! top

old:
        jsr     WaitVBlank		; wait for the vblank
        jsr     CHUNKY_UPDATE           ; write 125 palettes

new:
swapw1  move.w  REG_LSPCMODE,d1
        lsr.w   #7,d1
        sub.w   #$1e5,d1                ; first black line after chunkyscreen
        bne.s   swapw1			; Wait

        move.b  #0,REG_ENVIDEO          ; disable screen
        jsr     CHUNKY_UPDATE           ; write 250 palette !!!
        move.b  #1,REG_ENVIDEO          ; enable screen

I implemented this update into DIFF.... works very nice, no more tearing grin ... but I lose some frames because of the wait-loop. I will check this with a timer & trigger!

28

Noïce grin

I still have to update the fix page, I think I was confused with the cropping of some TVs.
Have to check but I think it's 40x28 in NTSC and 40x32 (not 30) in PAL. So 16 pixels more top and bottom.
avatar
Je fais des trucs. Des fois ça marche, des fois ça marche pas.

29

blastar (./27) :
Razoola, thanks for suggestion.
updating 250 palettes takes more time than expected - i have to disable screen while updating... works very well and it's pal-save! smile
(re)moving BIOSF_SYSTEM_IO saves some rasterlines but not enough.
with this code it's possible to update all palettes within one frame... this small multicolor-effect runs now with 60fps! top

Nice to hear that! oui

Could you change the circle colors of the multicolor effect to be modulated by a sine of different length (e.g. sin(radius*2) for blue, etc.)? boing This should give nice smooth concentric circles for some contrasts and help investigating the pixel modes regarding their effect on the perceived resolution.

30

Ohh, this is great news. Glad my suggestion was helpful.
www.universebios.com