💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › Demos › SMB.GS.STUFF › though… captured on 2024-02-05 at 13:58:27.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-


Plan for Super Mario GS
________________________________________

All shapes are executable code (working)


Here are the primitive routines:

extern pascal void MarioInit(void);
	-Initializes the system.  The application must make this call
	 first. (Ob
solete)

extern pascal void MarioShutDown(void);
	-Releases all memory and shuts down tools,

extern pascal void InitScreen(void);
	-Clears the graphics screen, sets the pallette

extern pascal void SetBgndPnt(int pnt);
	-Set the background point to a par
ticular offset into the level

extern pascal int GetBgndPnt(void);
	-Returns the current background point

extern pascal void DrawDisplay(void);
	-Erases the old display and draws the new one

extern pascal void DrawBkgnd(void);
	-Draws the background fro
m the Level definition
	-Objects in the background should have bits 6 & 7 clear.
	-Extrude objects should have bit 6 set and 7 clear.

extern pascal void DrawFrgnd(void);
	-Draws the foreground from the LevelFore definition
	-Foreground objects should hav
e bits 6 & 7 set.
	-background objects may be placed in the foreground
  	 definition.  They will be draw in 'front' of the active
	 sprites.

extern pascal void DrawQueue(void);
	-Draws the shapes that have been added to the Drawing
 	 queue.  This is us
ed for active objects usually

extern pascal void AddShapeToQueue(int X, int Y, int shape);
	-Adds a shape to the Draw queue to be draws the next time
 	 DrawDisplay() is called.  Max 31 sprites
	-setting the high bit of SHAPE identifies it as a
	 compoun
d shape

extern pascal int GetLevelItem(int X, int Y);
	-returns the shape value (low 6 bits) of a block on the Level
	 data block.

extern pascal void DrawShape(int X, int Y, int shape);
	-Draws a particular shape onto the screen

extern pascal void Shad
ow_On(void);
extern pascal void Shadow_Off(void);

extern pascal ContRecPtr ReadControl(void);
	-reads the keyboard and maps stuff to A,B,up,down,left,right

extern pascal int GetShapeHeight(int shape);
	-returns the height in pixels of a shape

extern pa
scal int GetShapeWidth(int shape);
	returns the width in pixel of a shape

extern pascal BOOLEAN IsBlockLegal(int x, int y);
	-checks to see if an 8x8 bloack drawn at the given X,Y
	 will collide with either a foreground or extrude block.

extern pascal v
oid DrawCompound(int x, int y, int Cshape);
	-draws a compound shape at a particular point.
	- NOTE: CShape does NOT have the high bit set.`

	defn:	A compound shape is a data block containing a variable
		number of three word records.
		The first word co
ntains the X offset relative to the
		point of drawing.  The second contains the Y offset.  The
		last is the shape block (standard shape) number. An end
		is defined by an $FFFF in the shape field.

	example:   CompoundShape dc	i2'0,0,block1'
				 dc	i2'
8,0,block2'
				 dc	i2'8,8,block3'
				 dc	i2'0,8,block4'
			         dc	i2'0,0,$ffff'    (obsolete)

extern pascal BOOLEAN IsCompoundLegal(int X, int Y, int CShape)
	-check to see if all the blocks in a compound shape can
	 be legally drawn.  NOTE: CShap
e does NOT have the high bit set.

extern pascal void DeleteLevelItem(int x, int y)
	-removes the block at the specified point in the background
	 by setting it to 0

extern pascal void SetBackItem(int x, int y, int shape)
	-set the specified block in the
 background to shape

extern pascal void SetForeItem(int x, int y, int shape)
	-sets the specified block in the foreground to shape

-------------------------------------------------------------------------
How to implement the Active shapes

Primitives:
   void AddActiveObject(ObjectRecPtr object)
      -Add an object to the Active Table.

   void DeleteActiveObject(int ObjectPos)
      -Deletes the object at the specified slot.

   ObjectRecPtr GetActiveObject(int ObjectPos)
      -Returns the record of
 the Object in a particular slot.

   SetActiveObject(ObjectRecPtr object, int ObjectPos)
      -Sets the specified slot to object.

-------------------------------------------------------------------------

Notes:

   Once the Active objects have been im
plemented correctly, the game will
be close to finished.  The plan right now is to have each Active Shape
have it's own action procedure.  A generic action is defined and an
Object Record is passed to it.  All manipulation is done, and a new Object
Record
 is returned.  The shapes should be drawn according to the Xpos and
Ypos fields in the record.

WARNING--- All the routines use LOCAL coordinates.

   It seems that the Update_Screen routine is lacking in speed, once I deactivated it, the game runs ~twice
 as fast.  Obviously, something needs to be done.  A fast block routine may be OK, or a PEI based update.  We'll see.

   The PEI Update is done.  Performance is OK (20 fps @ 8Mhz).  I will look
into performing a PEI Block by Block Update.

   All shapes 
are now 16x13 and the playing field is 256x156

   The Score and Clock are done and functioning.  BUG:  For some reason,
the clock will randomly stop after a certain interval from 10 - 60 seconds.
Hmmmmm.......maybe disabling interrupts during the clock r
ead......Nope

   For enemy characters to be available, a message passing system will be set
up.  I need to figure out the particulars, but I think that setting aside a
16 - 32 block of the shape def'n table will be adequate.  The shapes will be
either Si
mple or Compound, so a lookup table will be neccessary.
   The routines needed will be:
	DrawForeground: Modified to detect the active objects.
	SendActiveMessage: Tells the program "Hey!! Check me out!"
	ActiveMessage: Returns a struct.  If first parm is
 NULL, no active
			object, one 1 can be passed at once.

   The modified routines will need to delete the object from the foreground
after sending the message, otherwise, they will ignore it.

   I NEED to get all the shapes compiled. >200K of source so 
far :-(

   Well, the revision to SuperFX is coming along, the concept is sound and
it should just need some minor debugging when finished.  Too bad I couldn't
use the old routines by passing a pointer to the vector tables to use, but
that would be a HUGE
 mess.  Better to get it working first. :)

   I still have no idea why the clock stops, maybe I should start up the
tools with StartUpTools(ref ptr);..........Yeah, that's the ticket.

   Oh yea, the game is slowing down.......probably due to C code andm
ultiple segments, of course no optimization has been done yet save the
screen update to PEIs which was a nessesity.  BTW, I think I can speed that up
a bit by unrolling the loop once.  ~10-20 cycles per line.

   New note *** IMPORTANT ***.  I have decide
d that compound mario shapes
will be designated by 0x4--- to differentiate them from standard compound
shapes which will be designated 0x8---.  This is to save me from doing too
much redundent code!!

   The new mods are taking place.........

   The prog
ram now runs as before.  I'm starting to implement the passing
of active shapes to the program.  When this is fininshed, the program will
be in Alpha stage.  Any shape >= 0x60 that is in the foreground is treated
as an active shape, that number minus 0x60
 will be uses as an offset into
a list of shapes that are 'Active' shapes, either simple or compound.  The
shapes must be revelant to the normal shapes and Compound tables, Mario cannot
be used as a valid shape number, i.e. no 0x4--- numbers.

   An odd b
ug has come up, while messing with the mushroom location, it
seems that a big mario crashes the system.  I must investigate.  Oh yes,
the message passing sort of works.  A message gets across, but I can't
get anything to appear.

   Found the bug, it was 
a major one, too.  I don't know how things worked
as well as they have.  When I grabbed 4 bytes from the stack, I was adding
instead of subtracting from the stack pointer.  I can see how that worked,
but it was luck.

   More big problems.  Whenever a new
 object is added, anything on screen
vanishes.  I traced the bug to the fact that I was using the same object
record for everything, so each object pointer was pointing to the same spot
in memory, that way, whever a new object was added, it was automatica
lly
duplicated.  I've decided to rewrite the routines in ASM to make it more
understandable. :)

   Writing stuff in ASM was not necessary.  I redefined the C code to use
an array of Object RECORDS instead of POINTERS.  the pointers did nothing
since I di
dn't know what they were pointing at!  Probably was causing some
crashes.

   All the message passing works and new stuff is getting drawn, the mushrooms
seem to work for now.  The only big stuff left to do is get all the shapes in.
Ughhhhh!!!!  Also, the
 game has REALLY slowed down.  I kinda want to find out
why first, but I still need to add invisible blocks, coins, vines, etc.  I
think I'll go work on the shapes right now.
-------------------------------------------------------------------------------A
 few months later.....

Some quick thoughts of the SMB ressurection:

1) This engine will be MUCH faster for several reasons
	
	a) The screen will actually scroll.  No Draw/erase/update loop
	b) Background stuff can be drawn in bank 1, but moving shapes
	
	will need do be done in Bank $E1


I've done all the changes I think I need for now.  I used a pla/DP sta for
scrolling, it appears to be only slightly faster than a DP lda/sta.  I'll
forget that for now.  Time to go through and clean out the code, trim 
it
down, etc.

Tomorrow I'll start to redefine the level so that a 16-bit val is used.

2) Well, the initial changes are made.  I must say that I am impressed by
the speed of the new version.  At 2.8Mhz the screen moves about 24 FPS and
over 40 FPS at 7Mh
z.  In fact, this will have a few speed ups not present
in the old version because whole shapes can be used instead of just blocks.

3) A new thought just came into my head.  I don't need to keep the erase
routines.  Why, you ask.  Because the shapes are 
AUTOMATICALLY erased when
the background is scrolled.
   To solve the problem of 'hiding' behind objects...since the screen
does not scroll at that time, I can just selectively update the area that
mario is on.  Happy day.
   One other thing, to facilitat
e a smooth screen update, I may sort the
foreground objects by their Y-postition.  That way, as each scan line is
updated, a shape a can be draw also.  That would make the whole update one
clean 'wipe' of the screen.
   Quick thought.  Since there won't b
e any automatic clipping done by the
screen update, I need to black out all the palettes above and below the
min and max values.  That should do it.
   If I wanted to, I could eliminate the separate fore/background screens.
Yes, I think I may, because the
 way this engine is working, there is no
advantage to keeping them in their current incarnation.

   Well, the foreground is eliminated along with LOTS of code that delt
with back/foregrounds, erasing, drawingQueues, etc.  This is almost a
complete rewrit
e.  I finished a scroll routine that scrolls to the right.
It uses PEI's and is over twice as fast as the PLA/STA version.  I wish
I knew a way to implement left scrolling using PEI's.  I should ask around.

   I've been working on a level editor.  Things
 were going great until I
suddenly started to get mysterious crashes.  That will be investigated very
soon.  I think my array indexing is screwed up.

   I need to start re-compiling the shapes to use Bank $E1 for writing.
This is really a pain in the Ass
!!  I'm just going to get Mario walking
around and breaking brick and screw anything else for now.  I wish I
knew the best way to do this Scrolling/screen updating.  I'm not sure if
I should switch to a draw/erase/update or keep the draw/draw.  I think
th
e d/e/u could be have less tearing, but the draw/draw rips along about
twice as fast.  Arrrgggghhhhhh.........I hate decision making.


...3 months later

   I just decided to do some work on this stuff again.  I can't even remember
what any of this code 
does anymore.  Time to relearn.

   I'm beginning to recode the Queue, Update, and scroll routines to
integrate scrolling and updating of sprites.  This should make screen updates
smoother, but I don't think I'll ever be able to do a 1/60 second wipe beca
use
of the additional overhead.

   The changes are made but untested yet.  I really don't want to test it
because it'll probably not work and I'll have to debug this unstable crap.
Oh, the AddShapeToQueue is incomplete.  whatever shape is given, the heig
ht
needs to be loaded and added on to the Y-coord so that the shape is drawn
_after_ the lines it resides on are drawn.  The initialize screen routine needs
updating too so that all lines above and below the playing field are black.

   Well, it's all don
e and debugged and I must say the results aren't too
bad.  I am still getting a bit of flicker, but I'm planning to do some
syncing later on that should eliminate a good chunk of it.  I may add
a flag in that will allow the person playing to choose whethe
r the program
will run faster w/flicker or slower w/o flicker.  The non flicker version
will probably run at 12-15fps tops as the scroll/update loop is sooper fast but
takes ~3 vbl cycles + 2 VBLs for sync.  When I get around to doing this I may
set the s
ystem to 50Hz and see what that does for me.

(Note: 5 months later-  Flicker is taken care of by eliminating the integrated
 scroll/draw routine.  However the old draw/scroll/erase loop is back :( )

   Maybe for shits & giggles I'll make a quarter scree
n version of the game
when I'm done and see how fast it runs :) (60 fps)

   I'm planning to make the ScrollR routine work with a page-aligned DP
so it will run as fast as possible.  The only way to make it effective
is to make a precomputed table with th
e DP for each line and offset.  Since
not all lines will be able to use a page-aligned DP.  if the value is >$8000
then the DP should be set to $2000+(val-$8000).

   Well, the page alignment will probably work, but that's an end-of-the-
road optimization
.  Right now I need to get the game to the point it
_was_ at 1 year ago.  Things are progressing once I have mario moving well,
it should only take a few hours of work to get the rest up-to-date.

   Later I think I might triple-buffer the game to get it 
to scroll
smoother, the background shapes will need to be recompiled so that
the background can be in (for example) Bank $02, then the screen is scrolled
onto Bank 1, the foreground shapes are drawn, then the screen is updated
1/60 sec update :)
  The scr
olling will take ~twice as long plus the time to copy screen
  scroll via abs indexed:
	lda	$2000,x
	sta	$2000,y
	sta	$00,x => 7 cycles/byte  (same as MVN or MVP)

   Well, it's been a while since I wrote anything here.  I am happy to say that it looks li
ke the game might actually be finished.  Mario is moving smoothly
and I just need to re-implement the message passing functions from last year. There are 2 MAJOR things that must be done before I will really feel that the
project could be released:
	1)	A 
good level format.  Having the level just be a raw bunch
		of data is not satisfactory.  I need to work in the concepts
		of warp tubes and multi-segment level and the link between
		them.

	2)	After a level format has been decided on, making the level
		
editor.


Level format: (obsoleted)
note - 	levels may be a max of 64K
	The first segment reference (SegOff1) will be where the player
	initially starts

Offset		type	Identifier	Description
-----------------------------------------------------------------
--------------
HEADER:         String	"SMBIIGS"	Identifier string for a level file
		CString			Level name i.e. "World 1-1"
		byte	NumSeg		Number of segments
		word	SegOff1		Offset into file of first segment
		word	SegOff2		Offset to second segment
		.
		.

		.
		word	SegOffN		Offset to Nth segment

		byte	NumExtSeg	Number of external segment references
		CString	ExtSeg1		filename of first external ref
		CString	ExtSeg2		filename of second external ref
		.
		.
		.
		CString	ExtSegN		filename of Nth external
 ref

SEGMENT:        string	"SMBSEG"	Identifier string
		word	BgndClr		Color of the "sky" (RGB)
		word	SegWidth	Width of segment in blocks
		word	PlayerX		Block where player begins
		word	PlayerBase	Baseblock where the player begins
		byte[32] SpriteTabl
e	Enemy sprites to be used in this seg.
		byte[32] Palette	Palette to be used for this seg.
		word	NumRef		Number of segment references
	
		word	RefOff1		Blocknumber ofsegment ref
		word	SegRef1		Segment to link to

		word	RefOff2		Blocknumber
		word	SegR
ef2		Segment to link to
		.
		.
		.
		word	RefOffN		Blocknumber
		word	SegRefN		segment to link to

		data	LevelData	13*SegWidth bytes
--------------------------------------------------------------------------------

NOTE:	If a segment reference in a give
n segment is >0x00FF, then the low
	order byte should be ignored and the high order byte used as an index
	into the list of external references.

ex.	RefNum 0x0300

ExtRefList	"World11"
		"World31"
		"Bonus"
		"World71"

In this case, the next segment loa
ded would be the main segment of the SMB
world file "Bonus".

I'm doing a quick modification to the scroll routines.  I've been adding in
same zero to buffer the data, but that shouldn't be necessary.  The screen
is 16 blocks wide _PLUS_ 2 column that get
 scrolled in.  So when calling
DrawDisplay, the valid range of values would be 0-17 (18 total)  with 1-16
being the visible on screen blocks.

(Note: The scroll problem was caused by DrawDisplay not drawing background
       blocks (ID = 0))

Fixed scroll
ing, all I had to do was put the call to DrawDisplay before
Scroll.  Ignore the above paragraph.  It was the ramblings of a madman.

Done with finals, so I'm dedicating today to getting stuff done.  I found
out that turning on compiler optimizations REALL
Y sped things up.  I'm running
smack into the 64K limit that I set for myself.  Oh well, 50K of that code is
compiled sprites.

I put one-ups and power stars in.  They work very well.  Also, the pointsProc
was ported in.  I think I'll add invisible blocks
 too.  I still really need
to implement the message passing mechanism.

Found a REALLY nasty bug.  For some reason, I couldn't get the Big and Small Mario's to agree on where they wanted to stand.  Spent 2 hours looking for
something subtle.  Finally chan
ged the Height value of jumping mario on a whim
and it worked.  This is a bug that needs to be corrected.  I'll track it
down later. But for now just making a note that BigMarJumpL & R are 1 shorter
in height than theu should be.

Found the problem.....I 
wasn't recomputing the height of a sprite when it
needed to land.  If the jumping and standing sprite were different heights, then
there was an error in the calculations.  Stupid, stupid, stupid.

Invisible Blocks are in and so is the message passing syst
em.  The message
passing may be eliminated later and a direct call to AddActiveObject made
from DrawBkgnd.  But for now it works, and I'll work with it.

Everything is fine.  I've got a lot of things done.  The Question blocks
are in, fireballs work, mess
age passing is OK.  I found out that I need
to generalize out the routines for handling mario's collisions with background
objects.  I think I may make coins their own sprites, rather than mess with
a lot of special cases.

Coins are done and they work we
ll.  I wrote a routine that any sprite can call
to find out if it has run into Mario.  This made it really easy to add
collision detection to the enemies.  I'm in the process of changing the
routines that access the LevelArray.  I'm setting the array to a
 pointer that
can be accessed.  LevelPtr and LevelHeight are global variables and are all that
are needed to generalize the level stuff.  Also modified InitLevel, it now sets
LevelPtr and LevelWidth instead of copying a block of data to LevelArray.
		
One
 quick note:  With compiler ooptimizations on, the game runs ~33 frames per second @ 7MHz.  17 fps @ 2.5 MHz
		
Working on little things that need to be done, invisible support is almost done,
I just need to find a way for it to be triggered ONLY when the
 block immediately
above the player is the invis. block.

Soon I'll add in the final mario shapes, fix the mushroom shapes and add more
backgrounds.

Invisible blocks are now handled properly.  I also broke mario.cc into several
files so compiles are fast
er.

I spent a few hours going through and cleaning up the objprocs source.  What a
mess!!  I can;t believe I wrote that crap.  I had 2 routines to handle the
Koopas, one for left, one for right.  99% of the code was identical!!  Needless
to say, they are
 now happily combined.

I'm going to add fireball collision support so that I can kill things with them.
Right now they look cool and all, but are pretty much worthless.

Oh, I bagan a conversation with David Ong Tat-Wee (?) anyway, the guy who did
DOTW. 
 Cool game, great animation. I hope he can help me finish this up.  I
really need someone to do some sort of intro screen and such.

WOW!  David is a cool guy.  Pointed me toward some other IIgs people.  Hope they're as friendly. :)

Oh, what did I do tod
ay?  Well, the fireballs are working quite well and I
fixed a couple of cosmetic things.  All I really need to do now to make the
thing releasable is draw 8 more mario shapes (big/small skid,climb) and add
support for the turtle shells to knock stuff down
.  Just gotta do it.

Though on DOTW stuff:  Using the new sprite compiler to redo the shapes could
theoretically save me 1 cycles/word over a PEI based update which comes out
to a time savings of 21632 cycles/frame which is around 7.7 ms.  Right now
the 
thing runs at ~15fps => 66.6 ms/frame.  This savings would push me to
17 fps.  An increase yes, but combined with the fact that not all of the
screen would have to be redraw every frame, the speed could bumped up to
....Holy $!#@.....40fps for just scroll
ing.  I could make it smooth using the
1/30s VBL trick.  This could work out well.  And that 40fps is assuming the
screen is 75% full.  Throwing DP LDA/STA sprites on top could make it slower by
about 5fps, but who cares.

I've decided to redesign the low
-level stuff again so that I can make use of
David's techniques.  Also, I'm simplifying things a bit.  UpdateScreen is gone
as it will no longer serve and purpose.  Also, I'm going to eliminate PassMsg
and ChkMsg.  Eventually, the enemies for a level will
 be help in a separate
data struct, but for now, DrawScreen will call AddActiveObject itself.

Just looked at all my background sprites.  They are all masked.  Arrrgggghhh!!
Now I need to recompile them any way.  Oh well, good excuse to use DSC.

Been doi
ng a lot of work.  I changed some major stuff and got an extra 5fps at 2.5MHz. :)  Just some minor fixes to what's there and it'll be good to go.  All I need to do now is figure out a good may to clip stuff.  Maybe disabling shadowing and the drawing only
 the edge block, then updating the edge.

The thing is fast >17fps @ 2.5MHz.

OK, I've got a way to do the scrolling and stuff that I'll stick to (maybe)
   Maintain 2 different update arrays, one for drawing blocks, the other for
   scrolling.
The one fo
r blocks will only draw the blocks which change (i.e. right-side,
blocks under sprites).  The PEI array will tell which block sections need to
be scrolled.  Redundent sky blocks don't need it.

This will make other things a bit faster, too.  There will be
 less overhead in
the Scroll routine and DrawQueue and AddShapeToQueue can just fill the Queue
up without having to link it to the scrollarray.  In fact scrollarray can
be done away with!!

To get an idea of the speed up, right now, worst case, the whole 
screen is
done using pla/sta = 8 cycles * 64 * 169 = 86000 cycles + sprites.  Each sprite
is about 800 cycles(?) so for 16 sprites = ~100000 cycles just for screen
drawing.

For the new method, lets assume 5 blocks per sprite and each block is 390
cycles.
 So for sprites 800*16 + 5*16*390 = 44000 cycles and for a 75% full
screen = 48*169*8 = 64000.  So the new method will be about the same as the
old in the worst case.  In the typical case we have now with only mario plus
one sprite on screen, old way = 88
000.  New way = 70000.  And if I do it in
Bank 00 eventually, I save 2 cycles/word fo screen update so new way is now
only 55000 cycles in a moderate load and in worst case (Full screen, 16
sprites) = ~100000, So we get 30 fps :)  @ 2.8 MHz

Adding in req
uired stuff.  Pipe warping is coming along.  No effects, but the
basic mechanism is working.  Also, I redid the I/O routines to use GS/OS
instead of the built-in C functions.  It's a lot faster now.  Also fixed a bug
in the goombaProc.  The goombas weren'
t falling, just floating off in
mid-air.  Weird.

OK, I've fixed the fireball and goomba float bug.  Transition effects are in
and I'm ready to begin the graphics redesign.

The sequencer to do each frame should be:
	1) Add the shapes
	2) Draw the display

	3) Scroll things in (max 5 bytes)

I'm back after about a month and a half off.  Good Lord I didn't want to deal
with this stuff.  I've had time to think about the graphics, and I think my
best intermediate option is to clean up the clipping, then worry
 about
absolute speed.

What I plan to do is do an erase/draw/scroll type thing.  This way, I can
do proper clipping, but still get most of the speed out.  It'll be just as
if the number of sprites on-screen doubled.  There should be no flicker
anymore as
 well.

It works!! No flicker and sprites are clipped.  I just need to work out
problems with the erase part.  I tried a couple of approaches, but I think
I'm going to modify DrawScreen to take a variable X and Y range and use that.

Done and looking good
!!

I'm going to pull the enemy shapes out of the level data and make a new
struct for them in the file.  It's just too limiting forcing enemies
to be where there is no background and also, it broke in the new stuff. :)
Oh yeah, World 1-1 in completed, th
e flagpole isn't working, but it's all there
I _Really_ need an editor.  Hand coding in about 2000 hex values is not fun.

Oh yeah, I found a glitch in my AddActiveShapes routine.  Seems it was not
skipping non-entries in the ObjectTOC Table.  Fixing this
 gave me a few
extra FPS.  Probably was causing some crashes, too.  Which reminds me, the
program crashed upon exit if optimizations are turned on.  Humph!

Sprites are back and better than ever! The new method of includeing them in
a separate part of the
 Segment is really nice.  No limit of 16 baddies/segment.
Now the full (256) range of sprites is possible.  This can be kicked up to
65536 easily. I've been doing a bit of tweaking and bug fixing.  Coins are
_finally_ implemented.  They are Background sha
pes.  Period.  No more changes.
It would have been too much of a slow down to force them to be sprites.  The
erase/draw per frame was too high of a price to pay.  Now any number of coins
can be on a segment without slowdown.  I'm having a bit of trouble a
llowing
the coins to be detected.  But, I never finished the HitWhileFalling, Right
and Left. So......

Next on the agenda.  Covering up mushrooms and stars coming out of blocks and
working on Mario's transitions (Up/Down pipes).  Also need to finish the 
Pipe
shapes.  Thing are shaping up!!

Sidenote: The ideas about doing a selective update are still hanging around,
but the current incarnation is that it'll be done 1 line at a time with
each line divided into 4 secons each 32 bytes wides.  If a block sho
uld be
updated, then that section is marked.  I will have to do 5 different scroll
routines to handle all 16 permutations.  i.e. 1000,0100,0010,0001 can be
handled by the same routine, just different starting address. 1010 and 0101
are the same.  1100,011
0,0011 same and 1110,0111 same then 1111 and 1001 to
clean up.  Of course the game will slow down with more blocks, but I think
it'll be worth it.

Coins are done, nice effect, too. :)

I think I'll try profiling.

OK, time to speed things up.  First, alg
orithmically.  I'm going to go through
and change all the while(IsShapeLegal()) ++val  stuff.  This is waaayyyyy too
inefficient.  It can be rounded to the nearest block I think.  Should remove
potentially a lot of computations.

Well, that was changed.  
A few problems crept up, but they're squashed.
The next big thing will be doing the selective scrolling.  Shouldn't be too
hard, but need a lot of special case code.

Selective scrolling sucked!  I couldn't get it to work, so it's on the back
burner for n
ow.  Time to get mario coming _up_ pipes and doing the flagpole
thing.  Oh yes, I can now compile with optimizations on. I had forgotten to put
an rtl after my ClearScreen routine, don't ask how.  Dumb, dumb, stupidhead.

OK, back to work after taking a m
onth off.  I'm finally getting around to
doing things that need to be done.  I just finished implementing the flagpole.
I decided to make it a virtual sprite; height and width defined, but no drawing
It worked well.  I think I may do this for invisible bl
ack, too.  That could
eliminate a lot of special case code in my jump routines.

Thinking about the level format.  I need a way to determine where a pipe leads
to.  All I can do now is restart the destination segment over again.  This is
no good.  Also, l
ater I will need to know if it is a vine or a pipe destination
So, I think I'll extend the level format and add an identifier to each segment
reference as well as an X and Y block parameters.  For vines, only the X block
is important, but for pipes, these
 coordinates will determine the left-hand
edge of the exiting pipe. This will allow for correct transitions.

On second though, I don't need an identifier.  Since the program checks for the
presence of a pipe block below the player, I can just add a check
 for onVine()
and then do the transition if the player is above the screen (playerY < 0)

NOTE:  To pull most of the stuff above together I'll review where I'm at in
the coding of the game.
   1) The 'substance' of the game engine is done.  The last 5% ne
eds to be done
      which, of course, is the hardest to finish.
   2) My method of scrolling and updating is frozen.  I _may_ come back to it
      after everything is done, but probably not.  I experimented with only
      updating every other line, and
 that worked.  I may add that as a command
      line option for people with stock machines.
   3) The level format is almost frozen.  Just need to flesh it out for
      supporting a few special cases.
   4) Most background shapes and enemies are drawn, 
but not compiled.
   5) No thought to water worlds has been given, but shouldn't be _too_ hard.
      It's mainly a matter of adding a inWater() predicate and some special
      case code in the jump routine.

Eureka!! - Just had an idea that'll save me 1
 cycle/word on the scroll routine.
Instead of operating on 1 word at a time, I can cache 3 words of data in the
Acc, X and Y reg.  Then I can push them on the stack to scroll and still
stay ahead of the data.  This only work because I've limited scrolling
 to
5 bytes (10 pixels) at a time.  The max I could do here is 12 pixels at a time.
This will save me a little over 10000 cycles per frame. Which at 15fps gives an
extra 1-2 fps.  Yeah.

Note: I might be able to use the D reg as well with an LDA/TCD as an
 effective
      LDD instruction

Just implemented it and it gave the expected results: a 10% boost from
15fps to 17fps @ 2.8MHz.  Who knows, maybe I can optimize it a bit further
on. :)  I think 20fps is definitly possible since most of the code is in C.

Once the routines that are called most often (MovePlayer, FindShape, etc.)
are assemblized, that should give me a little boost.  I may try to do some
DP aligned code later on and handle certain lines as a special case.  I think
I only need 5 cases to han
dle all the lines.  Since they'd be special cased, I
could DP align all of them and give myself another 10+% boot up to 19fps.
Hmmmmm......4 cycles/DP load, 4 cycles/ph<axy>.  That's getting close to a
naive PEI solution (7 cycles/word vs. 8).  Of could a
 DP aligned PEI scroll
could pull 6 cycles/word and beat out my code by 25%.  You know, if I hammer off another cycle/word, that's a greater than 10% boost.  I just went from
10 cycles to 9 cycles which is 10%, +/- 1% for the rest of the code.  Going from

9 to 8 is a 11% boost which at 17fps gives me 19-20fps. I'll do the DP aligned
stuff tomorrow. :)   NOTE: going to a DP PEI would give 21-22 fps.

Well, I just compile a few more shapes.  I think I'll work on getting the
rest of Mario's actions down.  (D
ying, invinsible for 3 sec., etc.)

Allignment bug creeping up again in SpawnObject.  I don't know why, but I
cannot get spawned sprites to allign to the block boundaries.  I used the
same formula as for static objects like breaking bricks.  Maybe it's wh
ere
I'm calling SpawnObject.  Because the problems directly correlate to the
players X velocity.

Well, some finish is done.  Mario now 'dies' correctly, popping up and down.
I cleaned up the pipe transitions a bit by inserting a 1/2 sec pause between
scr
eens.  Looks better.  The next big thing to do is add support for water
and then finish coding object procedures.  After than it'll just be a matter
of tuning performance to the point where I can add sound.

Speaking of which.  At first I'm only going to 
have sound effects for jumping,
skidding, growing, explosions, etc.  Later on when I add the music track, I'm
planning to use VBL interrupts to time my music.  So it'll have a resolution
of 1/60th sec.  This should be OK and provide me with a low-overhead
 solution
rather than sucking up a lot of interrupt time processing the
sound registers.

W
ent in and removed 2 CLC intructions from the Scroll code.  I don't think I
can really speed it up anymore without using tables.  I only saved 4
cycles/line which is 676 cycles/frame.  quite a bit less than 10,000+, but a
savings.  At 17fps, this gives 11
,000+ cycles saved.  Good for 1/8 of a frame.
FPS boosted by .13

Now I need to give thought on how to 'bounce' blocks when they're hit.

Did some math earlier.  60% of the CPU time is given to the scroll procedure.
Even with a PEI update, I could only ge
t about 25fps.  So, this means I need
to trim down the rest of the code.  I'll have to do that later after everything
is working (famous last words).  If I can keep the game logic under 15000
cycles per frame, I'll have a good chance at hitting 30fps.

We
ll, I can't speed up the scroll code anymore, so a lock down of <30fps is in
effect.  Shooting for 25.

Bouncing bricks are in.  Not too hard, really.  Also added in the coins that
pop out of the ?-blocks.

I've got a new idead about handling collision de
tection as well.  Right now,
every time a sprite check for collision with fireballs or shells, etc. it
searches through the whole sprite list.  I think I should just go thought the
sprite list once and do the collisions by type.  That should help speed up
 the
object procedures.  Right now, getting a lot of sprites on screen slows things
down quite a bit, but only when they're goombas or koopas.

Found a _real_ good spot to optimize.  Every time ISLEGAL is invokes, it makes
calls to GetLevelItem for each b
lock a sprite is on to check for collisions.
Well, GetLevelItem calls Mult320 which really multiplies by the levelwidth,
so the program is doing several dozen multiplications per frame.  We can do
better.  Since the only values passed to Mult320 are 0-12,
 we can precompute
a table for them.  Should help out a bit.

Well, the framerate doesn't seem to drop _quite_ as much when there are 3
goombas on screen.  Didn't hurt any.

Need to get in and recompile a bunch of shapes.  A lot of shapes are still
drawn 
using Absolute Addressing when they should use DP.  This is a holdover
from the good 'ol days of drawing directly to Bank $E1.  Of course, I _should_
get all the shapes in first.  The swimming and climbing pictures are draw, I
just haven't gotten them in 
yet.  Of course I've still got spineys, squid,
cheep-cheeps, bowser, bullet bill to compile as well.  The only pictures
I don;t have drawn yet are the second frames of buzzy beetle and spiney eggs
and the hammer bros.  Oh year, Bowser's fireballs and the 
fireballs-on-a-stick.
Quite a few backgrounds from later levels as well.

Took some time and cleaned up a bit of code.  Little changes that made it a
bit samller and I also added in multi-coin blocks.  They work reasonably well,
but the framerate drops if
 there are > 6 sprites on screen.  Oh well.  I'd be
really nice to be able to start over and use my new no erase architecture.
Maybe in the future...

Thinking of re-doing the MovePlayer routines.  I'm pretty sure that the 'stuck-
in-the-brick' bug is bec
ause I'm doing separate colision checks for horizontal
and vertical movement.  I need to check on both and get rid of the table math
for jumping.  It's too hard to stop the player from other routines.

Did some work tonight.  Things bouncing off of bricks
 when hit from below works.
Also, the power-up bricks bounce before delivering their goodies.  I Think I can
put 1 PEI intruction in my scroll code.  This will save 2 cycles/line or only
320 cycles/frame.  At 17fps = ~5400 cycles/second.  Yawn.  I'll do i
t anyway.

Tomorrow if time permits, I'll make background versions of the mushrooms and
one-ups and power stars.  I'll also redo all of the routines that control
the player's movement.  They're too complicated.  Too many calls to isLegal
are made.  This r
outine takes up a lot of time.  Less now that the multiply
was optimized out, but it is still horrible. I'm going to make the routines
more reactionary.  instead of carrying information from frame to frame, it'll
just look at the current position and X & 
YVel to see what to do.

Went in a made the scrolling code more interrupt friendly.  It not re-enables
interrupts after each scan line.  This slows things down a bit, but I think
it's the Right Thing to do.  Anyway, I'll need this when I add music later.A
lso, I'm cleaning up the way to move that character under computer control.
Fleshed out FindShape to handle climbing.

FadeIn works now, also fixed when the fireflower comes out - adjusted its
starting Ypos.

TODO: 	Finish flagpole anim.  Fix color discre
pencies. Clean up some shapes.
	Then World 1-1 is done!  Oh wait, add intro animation.  Easy.

Well, I was going to DP align my scroll code, but I forgot that I changed the
DP depending on how far I wanted to scroll.  I could still do it, but I'd need
to 
write 40 different scroll routined to handle all the case. (8 address
allignments and 1-5 byte scrolls; 5*8 = 40). I'll probably still do it.

OK, I only need to do 32 special cases, 'cause the cache technique only works
for scrolls of 4 bytes or less.

A
lso, I got the marquee thing done and fixed my scoring problems.  I'll compile
in the marquee and make the intro scrolling code.  And I'll clean a bunch of
other things up.  It's getting there.  I'll also probably do the DP aligned
stuff tomorrow as well.