Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - BlockQuest - towards Knights of the Round for the SMS

Reply to topic Goto page Previous  1, 2
Author Message
  • Site Admin
  • Joined: 08 Jul 2001
  • Posts: 8663
  • Location: Paris, France
Reply with quote
Post Posted: Sun Oct 05, 2014 8:55 am
Starting to feel like the martial art games with the rhythm of characters coming. If you reduce the enemy life points and increasing their frequency it would feel like Black Belt :)
  View user's profile Send private message Visit poster's website
  • Joined: 13 Nov 2007
  • Posts: 93
  • Location: New York, NY, USA
Reply with quote
Post Posted: Sun Oct 05, 2014 9:38 am
hang-on wrote
(screenshot of title screen)


I would change that title font from Arial to something GOOD. That's the only real criticism I have right now :)
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sun Oct 05, 2014 12:37 pm
Thanks for the feedback!

In theory, I have built my code around a vblank handler that takes care of only the VDP and PSG stuff, with minimum calculations. Not quite so in practice. Anyway, that is why I'm going for a vblank handler that finishes in time...

Actually, I'm looking at games like Black Belt, Vigilante and Rastan for inspiration. Then it gets mixed up with the hammer-hammer-hammer combat mechanics of LEGO Minifigures Online (another occasional father and son activity), which, like Capcom's game, sports stronger enemies with energy meters. I'll admit that it feels a little bit like "between two chairs " with regards to gameplay at the moment. But then again, I never thought that this project would come to the point where we could discuss actual gameplay elements!

The titlescreen font... Yeah, you are right Neo :) consider it a placeholder. I'm going for something more blocky eventually
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3859
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Oct 05, 2014 6:01 pm
I personally prefer the approach where vblank hanlder is just raising a flag and a main loop in my code waits for the flag, as in
main:
call waitForVBlank
call updateVRAM
call gameLogic
call updateScreen ; populates the queues of everything that needs to be updated in VRAM later
call waitForSpecificScanline ; 192-30 for instance
call handleAudio
jp main

as long as updateVRAM takes less than VBlank duration everything is fine :)
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sun Oct 05, 2014 6:18 pm
Thanks for sharing! I've only recently exposed myself to the happy world of raster line coding. I can see how it holds a lot of promise.

Charles MacDonald:
 
NTSC, 256x192 -------------
Lines  Description

192    Active display
24     Bottom border
3      Bottom blanking
3      Vertical blanking
13     Top blanking
27     Top border

Some cycles to make good use of below the active display...

Edit: but why wait for vblank? We could safely start screen stuff from 193+, right?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14759
  • Location: London
Reply with quote
Post Posted: Sun Oct 05, 2014 7:31 pm
You get the VBlank interrupt on line 192 (if you count the first displayed line as 0). The actual video blanking signal is not relevant to code, except to say that you can try to time your palette changes to coincide to avoid any noise in the borders.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sun Oct 05, 2014 8:02 pm
Oh yes - I confused myself there. We have even already discussed this stuff in another thread. Every line after, and including, line 192 is blanked and thus safe for VDP activity. From line 0-191 the screen is drawn, line by line.

NTSC:
000 - 191   Active display  (192 lines in total)
192 - 262   Borders and blanking (70 VDP safe lines in total)


This is correct, yes? But I don't get the terminology, though. I thought that VBlank was when the beam was retracting, after the bottom border etc, and just before the top border, etc.? But if VBlank interrupt starts right below the visible display, then it is not technically a VBlank? But of course it is the start of the total blanking period. Even though the beam on the TV is not 'really' retracting yet....? Sorry for not being able to explain it properly :(

Edit: vblank is really a 'display file end' interrupt (http://oldmachinery.blogspot.dk/2014/04/zx-sprites.html)? At some point (Charles' numbers) after this interrupt occurs, the beam on a real tv does retract. Not at the start of the interrupt... Or this is in fact the definition of a VBlank, and I just got it wrong linking it to the TV beam in the first place..?!

Edit2: I think I got confused by the Vertical Blanking in Charles' list (beam retracting), and Vertical Blanking as a concept referring to the interrupt (end of active display). That name is a little misleading, then?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 08 Jul 2001
  • Posts: 8663
  • Location: Paris, France
Reply with quote
Post Posted: Sun Oct 05, 2014 8:27 pm
The "Bottom border" region correspond to a region below the 192 pixels where the border color is being displayed. During this time the VDP keeps accessing palette memory to "get" the border color. Because of that, write to palette (CRAM) will show a little "noise" in the form of individual colored pixels. A lot of games actually exhibit this noise but it is possible to avoid it if you make sure that your CRAM write are performed outside of it.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sun Oct 05, 2014 9:21 pm
Bock wrote
A lot of games actually exhibit this noise but it is possible to avoid it if you make sure that your CRAM write are performed outside of it.
Oh, I thought that occasional noise below was a result of my poor wiring/soldering skills at the homemade old school SMS-arcade table. Can't rule that out yet, but I think this VBlank stuff is finally sinking in the right way.

But what Charles MacDonald describes as the "Vertical Blanking" (VDP documentation, chap. 11), the phenomenon that is 3 lines 'wide', and happens below both bottom border and bottom blanking, THAT is when the beam retracts, right?
  View user's profile Send private message Visit poster's website
  • Joined: 28 Sep 1999
  • Posts: 1197
Reply with quote
Post Posted: Mon Oct 06, 2014 12:38 am
Oops, if I said vertical blanking I meant vertical sync. But yes, that's the period when the beam moves back. Regardless the entire area (top border, sync, bottom border) constitute vertical blanking and that's when you have less VRAM/CRAM access restrictions.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Mon Oct 06, 2014 4:50 am
Thanks! I think I got it now :)
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Size does matter...
Post Posted: Thu May 28, 2015 9:09 pm
In an attempt to further develop Knights of the Square, I have explored the opposite pole of zoomed 8x8 sprites, namely arcade quality sprites consisting of up to 36 hardware sprites. Actually the sprites used in the demo is from the SNES port (http://www.spriters-resource.com/snes/knightsround/sheet/39235/), but they are pretty close to the arcade anyway.

The Arthur sprite in the attached SMS-demo has two vram slots. The active bank is used by the hwsprites for char code references, while the passive bank is silently being loaded with tiles for the next frame of animation. 18 tiles per frame, so Arthur can be graphically refreshed every other frame, but we can - in theory - control him at every frame.

Having outiblocks for fastloading half of Arthur and the sprite attribute table takes up a significant portion of vblank, but still there is time for tricks. VRAM loading finishes at line 244/262 (demo is coded for NTSC).

This might be enough for rendering at least a portion of one enemy sprite. Background rendering tricks is a must here, or we will have instant flicker hell.

I'm not going to continue this exploration. I have learned a lot about handling big sprites, optimizing vram business, hand-processing the graphical assets, etc. I'm looking at Rastan for the final form of Knights of the Square.
KOR-01.png (9.51 KB)
SMS
KOR-01.png
Arcade.gif (22.78 KB)
Arcade
Arcade.gif
KOR.zip (10.67 KB)
SMS-Demo

  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3859
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri May 29, 2015 8:22 am
Nice indeed! :)
You said you're using up to 36 sprites... any chance that there aren't more than 4 on each scanline?
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Fri May 29, 2015 10:08 am
Thanks, sverx! :)

Regarding sprites pr. scanline: Yeah man - I have a grid system for arranging the hwsprites that makes up each of the frames of the animation (see below). The 36 sprites can be placed freely within a 8x16 tile rectangle. I thought this would be safe, but yesterday - as I worked with the slashing animation - I realized that it wasn't wide enough (I think the slashing frames are about 9-11 tiles wide!).

I think that there is space/time for 1 enemy at a time, being rendered to the background (Mortal Kombat, Street Fighter II, etc.). Then Arthur can have all the sprites (except for status etc.), and flicker could be avoided totally (I second your remark on the Gradius thread.)


/*
Frame data block format
   Offset  y,x is the coordinate pair used to determine where the top left
           corner of the layout grid will be placed, relative to the object
           (i.e. the player).

           Offset values of 0,0 will make the top left corner of the
           frame layout grid = object (y,x). It is named "Offset" because
           every time the sprite is drawn, it is drawn at some offset to the
           actual game object  it represents. This enables fine per pixel
           control over where the sprite is drawn. Frames of a sequence
           can be aligned to each other, even though the sprite in each frame
           is placed differently.

           The values of Offset x,y will be *subtracted* from the object's
           x,y, in order to determine where to put the grid's top left corner.

           If the sprite is representing the player object...
           By adjusting the offset, you can fine tune where the sprite will be
           drawn in relation to the player (y,x). This way the sprite center
           can be aligned to player y,x, if desired.

   Layout  is an 8 byte (64 bit) table/grid. Each byte corresponds to a row of
           possible hwsprite positions, and each bit corresponds to a column
           of a given row. The layout thus maps out how the individual
           hwsprites, that make up the total sprite, are positioned on the
           grid which is offset from the object (y,x) by Sprites_Offset (y,x).

           The layout is also referred to as the grid, or the layout grid.

   TileBlock is the BMP2Tile-processed block of tiles. The tiles are organized
           so that the top leftmost hwsprite (in the layout) will get tile 0,
           the next hwsprite to the right will get tile 1, and so on,
           downwards, from left to right.... If i.e. four bits are set in the
           layout, you must make sure to also have 4 tiles in the tileblock.
*/


; Arthur standing data block -----------------------------------------------
           ArthurStanding_Offset:
           .db 6 12*8+4
           ArthurStanding_Layout:
           .db %01000000
           .db %01000000
           .db %01000000
           .db %01000000
           .db %01110000
           .db %11110000
           .db %01110000
           .db %01110000
           .db %01110000
           .db %11111000
           .db %11010000
           .db %11111000
           .db %00000000
           .db %00000000
           .db %00000000
           .db %00000111   ; Unused tiles to wipe the SAT buffer.

           ; FrameExpireValue:
           .db $7c

           ArthurStanding_Tiles:
           .include "1\ArthurTiles.inc"

ArthurStandingRawTileblock.png (1.24 KB)
The total sprite broken down into a sequence of tiles
ArthurStandingRawTileblock.png

  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3859
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri May 29, 2015 10:56 am
It's interesting, and given that you might have slightly smaller characters which won't (most of times) be wider than 4 sprites, I guess such a system is very suitable for these 1-vs-1 fighting games ala StreetFighter having both characters made up with (hardware) sprites and very little to no flicker at all...
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2



Back to the top of this page

Back to SMS Power!