Ludum Dare

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Ludum Dare
by on (#183869)
Ludum Dare is coming up next weekend. Who's game? There have been some good looking NES entries in the past. http://ludumdare.com/compo/2015/05/03/banana-nana-nes-game-postmortem/

My girlfriend and I are intending on entering with a NES Rom.

Anyone else keen?
Re: Ludum Dare
by on (#183899)
I'll be participating but not with an NES game. I use Ludum Dare as an excuse to take a break from my main project.
Re: Ludum Dare
by on (#183954)
Awesome - well, good luck. I'll definitely check out whatever you submit.
Re: Ludum Dare
by on (#184056)
can you do a rom hack instead of a homebrew?
Re: Ludum Dare
by on (#184065)
From the rules of Ludum Dare: "We strongly recommend you only use assets that you have the legal right to use (Public Domain, things you licensed/created, etc). If you don’t have the right to use something, it is your responsibility." This rules out what comes to mind when most people think of "ROM hacks".
Re: Ludum Dare
by on (#184129)
Yes, it's mostly just an endless sea of homebrew. Check it out if you haven't before - it's awesome.

Some of the past competition winners are a good place to start:

http://ludumdare.com/compo/ludum-dare-35/
Re: Ludum Dare
by on (#184344)
So the theme for Ludum Dare has been announced and it is.....


One Room.

So I guess I won't be desperately trying to implement a scrolling engine over the weekend then, which is good!

Right now I'm thinking something (relatively) simple - maybe a micro-platformer, or something similar. The very first thing that came to mind was an interactive musical based around Tom Wiseau's infamous The Room https://en.wikipedia.org/wiki/The_Room_(film), but I'm thinking that's a bit ambitious.

Let's see where we get!
Re: Ludum Dare
by on (#184348)
I've now got a very simple ASM and C nes structure file, that is writing tiles and sprites to the screen. YEAH!

We've been discussing ideas and we considered game ideas:

    - Something like Picnic, the first game I ever made, in which zombies try and steal your cutlery
    - A stealth game in which you have to hide - something like the boardgame I made a few years ago, Chainsaw Maniac Cordially Invites you to Dinner http://www.crunchpress.co.uk - the logic involved in that seems a bit tricky for a weekend, however.
    - A ramping up series of boss fights - again, this seems like it could be a bit much for a weekend
    - The microplatformer - I'm thinking something like "You are insignificant".

Here is the shell of the game loading the sprite from the compo entry I'm working on with our super basic metasprite system:
Re: Ludum Dare
by on (#184350)
I've got gamestates and nametable loading working.

Other then that, I think the current title screen illustrates best where I am up to.

Attachment:
idonotyetknow.gif
idonotyetknow.gif [ 2.63 KiB | Viewed 4173 times ]
Re: Ludum Dare
by on (#184354)
Hehe, I've had a busy day today so I haven't had the chance to start yet. Though this theme doesn't really conjure many ideas for me.

Anyway, I'm looking forward to see what you produce using this theme. Good luck!
Re: Ludum Dare
by on (#184356)
I took a break for a couple of hours myself. I think I have a plan now, and a name.

I've had some bigger ideas, but I'm sticking with something pretty simple. The theme reminds me very strongly of an excellent book, House of Leaves. I would recommend it to anyone, it is an excellent piece of literature, in which (without giving to much away) the rooms of a house warp and twist.

It also reminds me of the movie Videodrome, as most of the movie involves the characters trying to puzzle out what exactly is happening in a room in Pittsburgh (it's one of my favourite movies, we screened it for our film club)

The game will be like none of these, however. Ladies and Gentleman, I present to you the first enemy sprite, he's come a long way and he's very happy to be here, he is, THE DUCK.

Attachment:
quack.gif
quack.gif [ 18.76 KiB | Viewed 4154 times ]
Re: Ludum Dare
by on (#184362)
I can't tell if that post is an elaborate joke...like

"hey, were going to film the best movie, ever. Think Gattaca meets ET, but with more explosions! Now, we only have a budget of $300...so the entire film will take place in one room, with a handheld Steadicam, in one take. And no dialogue. It'll be great!"

Anyway. Good luck. Have fun.
Re: Ludum Dare
by on (#184404)
Deadly serious.

We now have collision detection and lots of other fancy bits.

Here's the current (and currently only) level. The pipes are a temporary fixture.

Attachment:
winteriscoming.gif
winteriscoming.gif [ 6.83 KiB | Viewed 4102 times ]
Re: Ludum Dare
by on (#184456)
Rudimentary duck AI.

I call him Quacking Jack.

Attachment:
Quacking_Jack.gif
Quacking_Jack.gif [ 127.05 KiB | Viewed 4084 times ]
Re: Ludum Dare
by on (#184461)
Is the duck throwing a ... lute? How delightfully surreal!
Re: Ludum Dare
by on (#184467)
Nice duck.

(o)< QUACK
Re: Ludum Dare
by on (#184496)
That's actually a poorly drawn fireball - I had originally seen them as moving down-left, hence the angle!

For surrealism, have you seen the games by my former selves (link to one of their old kickstarters)? I believe I backed one or two on kickstarter. They're RPGmaker so the interactivity is rather limited, but the aesthetics are quite wonderful - they're like moving Hieronymus Bosch paintings.
Re: Ludum Dare
by on (#184501)
Getting closer:

Attachment:
shenzenminiclassic.gif
shenzenminiclassic.gif [ 286.68 KiB | Viewed 3881 times ]
Re: Ludum Dare
by on (#184710)
This is now released:

https://team-disposable.itch.io/you-are-insignificant

Thanks everyone, comments and criticism appreciated. Thanks also for the comments while making the thing, nesdoug's tutorials, and all the help on the newbie forum in general. It's an excellent community, and much appreciated.
Re: Ludum Dare
by on (#184900)
Good job! It isn't easy getting a game playable by the end of Ludum Dare.
I enjoyed your game and made it to the end, although the delay when trying to move really threw me off while attempting many of the jumps.

How was your experience with making an NES game for Ludum Dare?
Re: Ludum Dare
by on (#185073)
Really impressive to get a nes game out for the LD!

I can haz source? :mrgreen:

Here is my feeble attempt: http://ludumdare.com/compo/ludum-dare-3 ... &uid=65233

I took it as an excuse to try and download/test out the latest xamarin/mono android support.
Re: Ludum Dare
by on (#185135)
Your game looks good, I'll definitely try it out.

I'm not releasing the full source right now as it's a bit of a pig's ear, having been put together in three days. I'll probably release it if/when I clean it up a bit, but right now I'm a bit busy working on my compo entry.

Is there anything in it you where interested in? I'd be happy to pull out bits and explain them. Nothing is handled in a particularly elegant way, however!

All of the levels are raw byte by byte maps produced in the NES Screen tool - I did this as I also use them for collision detection, which is how the spikes, the lava, the gold and the player physics work.

The enemies are a set of arrays, the main one being "enemy_active", which the central routine runs a for loop against, like this:

Code:
for(index = 0; index < sizeof(enemy_active);++index)
{
     if(enemy_active[index] == 0x01)
     {
             //do enemy routine
     }

}


There are then a bunch of other arrays - enemy_x, enemy_y, enemy_directionfacing, etc - all of which correspond to the same index as enemy_active.

Those two and the player physics are pretty much the bulk of the game. The player physics are pretty basic - I haven't noticed the lag in movement myself, but it is likely because I am using an 8.8 movement system - so there are eight positions for each pixel.

Jumping is something I would definitely improve on if I did this again. Currently, the longer you press the jump button, the more is added to the magnificently named variable player_remainingjumpstrengthtoapply. Chunks of this are then whacked on to the players Y value each frame until it is zero, or the player hits their head. Gravity is actually running the whole time on them, so it just kind of naturally takes over, much like in real life. Hence the awkward jumping. I would go for velocity based system if I were doing it again.

The big thing that I've found programming in c on the NES is that you really, really need to appreciate it is just converting everything to 3 registers in the backend. So there lots of occasions where I'd like to be comparing two arrays together, like this:

Code:
if(enemy_destination_x[index] > enemy_x[index])
{
//do something
}


Only the result of the above will default to true, no matter what the values in enemy_destination_x and enemy_x.

Storing one of the values to a var, and then doing the comparison, makes it work properly however. So this works:

Code:
index2 = enemy_x[index];
if(enemy_destination_x[index] > index2)
{
//do something
}


Apart from the obvious stuff, like yes, even I can technically put a NES game together, this is the most important thing I learned - if a routine isn't working, it's probably too complex for the machine, and you need to shift some of the values off the registers and in to RAM. At least, I think that is what is happening. Regardless, it works, as the above is a literal example that had me stumped for a good hour or two before I figured out the answer.
Re: Ludum Dare
by on (#185172)
Are you using an old version of cc65? I don't believe I've ever hit a bug like that where a two-array comparison would produce wrong results. It's slow yes, but correct.
Re: Ludum Dare
by on (#185186)
cc65 V2.15 pre-compiled windows binary, which appears to be the same version in the current downloadable windows snapshot.

I can post an example later, if you like. I haven't checked what it's doing in the ASM though - it's just a presumption based on the fact an assignment of the right value to a var in C fixes it. Similar things have happened in both the ludum dare project and my latest project.
Re: Ludum Dare
by on (#185187)
team_disposable wrote:
I can post an example later, if you like.

Please do. If the compiler is generating incorrect code that is a serious bug (and surprising).
Re: Ludum Dare
by on (#185188)
Yep, cc65 is actively maintained, so any bugs should be reported with test cases.
Re: Ludum Dare
by on (#185189)
Here's a rom that demonstrates both cases. Apologies, I just figured this was a regular thing - I'm sure it must be something I am doing, if not someone else would have noticed, no?

Pressing select switches between the two.

Please ignore the garish palettes and sparse rooms - I'm redecorating and haven't chosen a tone yet.

Here is the code difference (warning - big ol' chunk of code):

If no one spots anything stupid in the below, I'll go and report it to the CC65 people. And yes, index and index2 have a value in them. Do you want to see the ASM as well?

Code:
         if(debug_flip == 0x00)
         {
         
            index2 = enemy_x[index];
         
            if(enemy_destination_x[index] > index2)
            {
            
            ++enemy_x[index] ;
            enemy_directionfacing[index] = Going_Right;
            
            }
            else
            {
         
               if(enemy_destination_x[index] < index2)
               {
                  
                  --enemy_x[index] ;
                  enemy_directionfacing[index] = Going_Left;
               }
               else
               {
                  index2 = enemy_y[index];
         
                  if(enemy_destination_y[index] > index2){
                     
                     ++enemy_y[index] ;
                     enemy_directionfacing[index] = Going_Down;
                  }
                  
                  else
                  {
                     if(enemy_destination_y[index] < index2)
                     {
                     
                     --enemy_y[index] ;
                     enemy_directionfacing[index] = Going_Up;
                     }
                              
                  }
                              
               }
                  
            }
            

         }//end of debug flip is 0
         if(debug_flip == 0x01)
         {
            //index2 =
         
            if(enemy_destination_x[index] > enemy_x[index])
            {
            
            ++enemy_x[index] ;
            enemy_directionfacing[index] = Going_Right;
            
            }
            else
            {
         
               if(enemy_destination_x[index] < enemy_x[index])
               {
                  
                  --enemy_x[index] ;
                  enemy_directionfacing[index] = Going_Left;
               }
               else
               {
                  //index2 = enemy_y[index];
         
                  if(enemy_destination_y[index] > enemy_y[index]){
                     
                     ++enemy_y[index] ;
                     enemy_directionfacing[index] = Going_Down;
                  }
                  
                  else
                  {
                     if(enemy_destination_y[index] < enemy_y[index])
                     {
                     
                     --enemy_y[index] ;
                     enemy_directionfacing[index] = Going_Up;
                     }
                     
               
               
                  }
                  
                  
                  
               }
               
               
               
            }
   
         }//end of debug flip is 1
Re: Ludum Dare
by on (#185191)
team_disposable wrote:
If no one spots anything stupid in the below

I don't see anything wrong with it offhand, though we're lacking the definition of index2 and other values, which could be important.

team_disposable wrote:
Do you want to see the ASM as well?

That would be helpful. It wouldn't be very easy to find the generated code in the ROM based on the C code.
Re: Ludum Dare
by on (#185192)
Going_Left, Going_Right etc are an enum.
enemy_destination_x, enemy_x, and its y counterparts are variable arrays populated from set of const arrays when the player enters a room.

It would seem the bug would probably be in the first comparison, and replicated in the others, so I've posted the first loops first. I'm not too fussed as I have a solution, so let me know if digging through ASM isn't your thing and I'll just go bugtrack it over at CC65.

here is the buggy first loop:

Code:
;
; if(enemy_destination_x[index] > enemy_x[index])
;
   ldy     _index
   lda     _enemy_destination_x,y
   jsr     pusha0
   ldy     _index
   lda     _enemy_x,y
   jsr     tosicmp0
   bcc     L2671
   beq     L2671
;
; ++enemy_x[index] ;
;
   lda     #<(_enemy_x)
   ldx     #>(_enemy_x)
   clc
   adc     _index
   bcc     L2679
   inx
L2679:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     #$01
   clc
   adc     (ptr1),y
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Right;
;
   ldy     _index
   lda     #$00


the non-buggy first loop:

Code:

;
; index2 = enemy_x[index];
;
   ldy     _index
   lda     _enemy_x,y
   sta     _index2
;
; if(enemy_destination_x[index] > index2)
;
   ldy     _index
   lda     _enemy_destination_x,y
   sec
   sbc     _index2
   bcc     L263C
   beq     L263C
;
; ++enemy_x[index] ;
;
   lda     #<(_enemy_x)
   ldx     #>(_enemy_x)
   clc
   adc     _index
   bcc     L2642
   inx
L2642:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     #$01
   clc
   adc     (ptr1),y
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Right;
;
   ldy     _index
   lda     #$00



Here's the full ASM of the buggy if loop:

Code:
 
;
; if(debug_flip == 0x01)
;
L2832:   lda     _debug_flip
   cmp     #$01
   jne     L266F
;
; if(enemy_destination_x[index] > enemy_x[index])
;
   ldy     _index
   lda     _enemy_destination_x,y
   jsr     pusha0
   ldy     _index
   lda     _enemy_x,y
   jsr     tosicmp0
   bcc     L2671
   beq     L2671
;
; ++enemy_x[index] ;
;
   lda     #<(_enemy_x)
   ldx     #>(_enemy_x)
   clc
   adc     _index
   bcc     L2679
   inx
L2679:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     #$01
   clc
   adc     (ptr1),y
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Right;
;
   ldy     _index
   lda     #$00
;
; else
;
   jmp     L2830
;
; if(enemy_destination_x[index] < enemy_x[index])
;
L2671:   ldy     _index
   lda     _enemy_destination_x,y
   jsr     pusha0
   ldy     _index
   lda     _enemy_x,y
   jsr     tosicmp0
   bcs     L267F
;
; --enemy_x[index] ;
;
   lda     #<(_enemy_x)
   ldx     #>(_enemy_x)
   clc
   adc     _index
   bcc     L2687
   inx
L2687:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     (ptr1),y
   sec
   sbc     #$01
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Left;
;
   ldy     _index
   lda     #$01
;
; else
;
   jmp     L2830
;
; if(enemy_destination_y[index] > enemy_y[index]){
;
L267F:   ldy     _index
   lda     _enemy_destination_y,y
   jsr     pusha0
   ldy     _index
   lda     _enemy_y,y
   jsr     tosicmp0
   bcc     L268D
   beq     L268D
;
; ++enemy_y[index] ;
;
   lda     #<(_enemy_y)
   ldx     #>(_enemy_y)
   clc
   adc     _index
   bcc     L2695
   inx
L2695:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     #$01
   clc
   adc     (ptr1),y
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Down;
;
   ldy     _index
   lda     #$03
;
; else
;
   jmp     L2830
;
; if(enemy_destination_y[index] < enemy_y[index])
;
L268D:   ldy     _index
   lda     _enemy_destination_y,y
   jsr     pusha0
   ldy     _index
   lda     _enemy_y,y
   jsr     tosicmp0
   bcs     L266F
;
; --enemy_y[index] ;
;
   lda     #<(_enemy_y)
   ldx     #>(_enemy_y)
   clc
   adc     _index
   bcc     L26A3
   inx
L26A3:   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     (ptr1),y
   sec
   sbc     #$01
   sta     (ptr1),y
;
; enemy_directionfacing[index] = Going_Up;
;
   ldy     _index
   lda     #$02
L2830:   sta     _enemy_directionfacing,y
Re: Ludum Dare
by on (#185236)
I don't actually see errors in the disassembly. I think the code its producing is actually correct.

By tracing that function in your running ROM I think the error is with your "sp" variable, which is supposed to point to the C stack area, but looks like you have it initialized to 0 instead. (Follow the value of $8A in the trace, uses of the C stack are trying to push variables to ROM at ~$FFFE as a result.)

The reason your workaround "fixes" it is that it doesn't happen to use the C stack, but I'm tremendously surprised you haven't seen huge errors elsewhere yet.

Here's an example trace:
Code:
A:01 X:00 Y:00 S:FB P:nvUbdIZC     $C5D9: A4 0E     LDY $000E = #$00
A:01 X:00 Y:00 S:FB P:nvUbdIZC     $C5DB: B9 58 00  LDA $0058,Y @ $0058 = #$60
A:60 X:00 Y:00 S:FB P:nvUbdIzC     $C5DE: 20 A4 CD  JSR $CDA4
A:60 X:00 Y:00 S:F9 P:nvUbdIzC       $CDA4: A2 00     LDX #$00
A:60 X:00 Y:00 S:F9 P:nvUbdIZC       $CDA6: 48        PHA
A:60 X:00 Y:00 S:F8 P:nvUbdIZC        $CDA7: A5 8A     LDA $008A = #$00
A:00 X:00 Y:00 S:F8 P:nvUbdIZC        $CDA9: 38        SEC
A:00 X:00 Y:00 S:F8 P:nvUbdIZC        $CDAA: E9 02     SBC #$02
A:FE X:00 Y:00 S:F8 P:NvUbdIzc        $CDAC: 85 8A     STA $008A = #$00
A:FE X:00 Y:00 S:F8 P:NvUbdIzc        $CDAE: B0 02     BCS $CDB2
A:FE X:00 Y:00 S:F8 P:NvUbdIzc        $CDB0: C6 8B     DEC $008B = #$00
A:FE X:00 Y:00 S:F8 P:NvUbdIzc        $CDB2: A0 01     LDY #$01
A:FE X:00 Y:01 S:F8 P:nvUbdIzc        $CDB4: 8A        TXA
A:00 X:00 Y:01 S:F8 P:nvUbdIZc        $CDB5: 91 8A     STA ($8A),Y @ $FFFF = #$C0
A:00 X:00 Y:01 S:F8 P:nvUbdIZc        $CDB7: 68        PLA
A:60 X:00 Y:01 S:F9 P:nvUbdIzc       $CDB8: 88        DEY
A:60 X:00 Y:00 S:F9 P:nvUbdIZc       $CDB9: 91 8A     STA ($8A),Y @ $FFFE = #$AA
A:60 X:00 Y:00 S:F9 P:nvUbdIZc       $CDBB: 60        RTS (from $CDA4) ---------------------------
A:60 X:00 Y:00 S:FB P:nvUbdIZc     $C5E1: A4 0E     LDY $000E = #$00
A:60 X:00 Y:00 S:FB P:nvUbdIZc     $C5E3: B9 30 00  LDA $0030,Y @ $0030 = #$67
A:67 X:00 Y:00 S:FB P:nvUbdIzc     $C5E6: 20 2F CD  JSR $CD2F
A:67 X:00 Y:00 S:F9 P:nvUbdIzc       $CD2F: A2 00     LDX #$00
A:67 X:00 Y:00 S:F9 P:nvUbdIZc       $CD31: 85 8C     STA $008C = #$3F
A:67 X:00 Y:00 S:F9 P:nvUbdIZc       $CD33: 86 8D     STX $008D = #$02
A:67 X:00 Y:00 S:F9 P:nvUbdIZc       $CD35: A0 00     LDY #$00
A:67 X:00 Y:00 S:F9 P:nvUbdIZc       $CD37: B1 8A     LDA ($8A),Y @ $FFFE = #$AA
A:AA X:00 Y:00 S:F9 P:NvUbdIzc       $CD39: AA        TAX
A:AA X:AA Y:00 S:F9 P:NvUbdIzc       $CD3A: E6 8A     INC $008A = #$FE
A:AA X:AA Y:00 S:F9 P:NvUbdIzc       $CD3C: D0 02     BNE $CD40
A:AA X:AA Y:00 S:F9 P:NvUbdIzc       $CD40: B1 8A     LDA ($8A),Y @ $FFFF = #$C0
A:C0 X:AA Y:00 S:F9 P:NvUbdIzc       $CD42: E6 8A     INC $008A = #$FF
A:C0 X:AA Y:00 S:F9 P:nvUbdIZc       $CD44: D0 02     BNE $CD48
A:C0 X:AA Y:00 S:F9 P:nvUbdIZc       $CD46: E6 8B     INC $008B = #$FF
A:C0 X:AA Y:00 S:F9 P:nvUbdIZc       $CD48: 38        SEC
A:C0 X:AA Y:00 S:F9 P:nvUbdIZC       $CD49: E5 8D     SBC $008D = #$00
A:C0 X:AA Y:00 S:F9 P:NvUbdIzC       $CD4B: D0 09     BNE $CD56
A:C0 X:AA Y:00 S:F9 P:NvUbdIzC       $CD56: 50 FD     BVC $CD55
A:C0 X:AA Y:00 S:F9 P:NvUbdIzC       $CD55: 60        RTS (from $CD2F) ---------------------------


So, the fix is not with CC65. The problem is that you have not initialized sp, which must be done by your CRT startup before entering main. I don't know whose CRT startup you are using, so I can't tell you where to fix it.

See line 100 here (in CC65's included NES CRT), and make sure the same gets done in your startup: https://github.com/cc65/cc65/blob/master/libsrc/nes/crt0.s
Re: Ludum Dare
by on (#185244)
Deja vu: viewtopic.php?p=155070#p155070

Were you using some kind of a template code to start the project? If so, it might be worth fixing it at the source.
Re: Ludum Dare
by on (#185245)
While you're in there, make sure you're also doing jsr copydata or equivalent in your startup as well.
Re: Ludum Dare
by on (#185251)
Ha, I would it say it is precisely because I am not using template code that I am not initializing the stack. Consider it fixed at source!

Looking back at all of the C tutorials, I can see that section in there. Adding it in and the comparison works as expected.

Thanks!

Interestingly, even with the stack initialized, making two index comparisons seems to take up more cycles then assigning one half of the comparison to a var and then making the comparison,

Is it considered bad practice for any reason to do this? As it would seem it only costs me a char I can reuse and has a visible performance benefit.

yes i am using jsr copydata as previously recommended, thanks!
Re: Ludum Dare
by on (#185254)
Just as a quick check, are you using -O as a compiler flag? With CC65 optimization is recommended even when debugging.

There are lots of unfortunate ways that it might generate worse code one way than another. In particular it seems to have problems keeping efficient track of arrays and pointers, especially with 16-bit indexing. (In general advice: use 8-bit types as much as possible, and use array types rather than pointers when possible.)

Anyhow, presuming you've already got optimization turned on, there are often cases where doing things one way or a trivially different way might result in much better or worse (but functionally equivalent) code. This is just an unfortunate fact about this compiler.

Measure the performance of your code frequently; when it makes something unusually slow it'll be easier to figure it out if you've been checking. Whenever something runs unexpectedly slow, take a peek at the assembly.
Re: Ludum Dare
by on (#185333)
Yes, I'm compiling with the flags O and i.

I've stuck pretty exclusively to 8 bit variables and constants and it seems to be fairly snappy so far.

For any one else using C, I'd highly recommend having a var you can assign to to avoid a direct array to array comparison. Even with only three enemies on the screen, it seems to be saving a good chunk of cycles. Which, ironically, seems to be because it avoids the C stack.

Thanks for all of the help!
Re: Ludum Dare
by on (#186108)
team_disposable wrote:
Is there anything in it you where interested in?


I'm just a noob hoping to someday bang out a working nes game and trying to absorb as much source as possible.

Many thanks for your code explanation!