playermissile Posted November 22, 2016 Share Posted November 22, 2016 There's a new release of Omnivore that includes a built-in MAC/65 compatible assembler: https://github.com/robmcmullen/omnivore/releases/tag/0.14.0 There's an overview of creating custom levels here: https://playermissile.com/jumpman/#advanced-levels-with-custom-code and I'm including my level Clockwise as an example. clockwise.atr clockwise.s 4 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted November 22, 2016 Share Posted November 22, 2016 AWESOME! -Thom Quote Link to comment Share on other sites More sharing options...
Goochman Posted December 24, 2016 Share Posted December 24, 2016 Question on the designer. Im working on a level which has alot of girder erasing. After a certain point I am getting an error trying to create more triggers for erasing - or actual building for that matter. Is there a limit? Quote Link to comment Share on other sites More sharing options...
playermissile Posted December 24, 2016 Author Share Posted December 24, 2016 Yeah, looking at the routine in the code at $4b00 it looks like there is a 256 byte limit for the harvest table. Each harvest table entry is 6 bytes long, so that means there's a limit of 42 triggers. I'll have to add a check for than into Omnivore. Quote Link to comment Share on other sites More sharing options...
Mclaneinc Posted December 24, 2016 Share Posted December 24, 2016 Bloody hell, I missed this post...PM that is an awesome bit of coding, its a level that would have shone on the game when released.. Of course I'm loving all these new levels so a MASSIVE thank you to Goochman, Kevin, yourself and anyone else who made some, wish the contest had gone better but I guess its been a tough old year all around so people were lost for time. Still, it makes the ones that did get made even more special... Thank you all.. 1 Quote Link to comment Share on other sites More sharing options...
Goochman Posted December 25, 2016 Share Posted December 25, 2016 Yeah, looking at the routine in the code at $4b00 it looks like there is a 256 byte limit for the harvest table. Each harvest table entry is 6 bytes long, so that means there's a limit of 42 triggers. I'll have to add a check for than into Omnivore. Well I hit it - I had a pretty cool idea to pretty much wipe a map.....maybe I can still do it with fewer triggers Quote Link to comment Share on other sites More sharing options...
playermissile Posted December 25, 2016 Author Share Posted December 25, 2016 Well I hit it - I had a pretty cool idea to pretty much wipe a map.....maybe I can still do it with fewer triggers It's not supported in Omnivore because it's not something that is very useful in general, but it's possible to design your own drawing elements. I haven't experimented with it, but Kevin and I noted the possibility in our reverse engineering notes: http://playermissile.com/jumpman/notes.html#h.wtrim2a10znr I don't know what the limits are, so I'm not sure how wide or tall the elements can be, but for your purposes, maybe you could create a large erasable element that could wipe out a bigger area. Quote Link to comment Share on other sites More sharing options...
Savetz Posted January 17, 2017 Share Posted January 17, 2017 I've published my custom code for three new levels (Score Eater, Lasers, and Jetpack) here: http://atariage.com/forums/topic/255262-jumpman-level-design-contest/?p=3674126 5 Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 18, 2017 Share Posted January 18, 2017 Ok seeing some of the samples Im trying to add some custom code (or should I say steal and reuse ) - In the editor I dont see a way to add custom code the way its documented on your website: You will need to edit the assembly source with your favorite text editor and then use the Jumpman -> Custom Code... to add the source file to your level. After that it will remember the file when you load the level again. Be sure the source code is in the same directory as the .atr image. If you move the .atr file to a new place, be sure to copy your assembly file as well. At this point Im taking some custom code and trying to change the sprite definitions for my use. Quote Link to comment Share on other sites More sharing options...
playermissile Posted January 18, 2017 Author Share Posted January 18, 2017 Are you using the latest Omnivore, 0.14.1? You also need to be in the jumpman level editor mode, otherwise you won't get that menu item. It doesn't work in the hex edit view. Quote Link to comment Share on other sites More sharing options...
Mclaneinc Posted January 18, 2017 Share Posted January 18, 2017 You may want to update the site to show 14.1 as the latest, still says 13.0, downloads does give you 14.1 tho... Quote Link to comment Share on other sites More sharing options...
playermissile Posted January 18, 2017 Author Share Posted January 18, 2017 You may want to update the site to show 14.1 as the latest, still says 13.0, downloads does give you 14.1 tho... I can see how that would be confusing. I don't update the website as much now that I'm on a podcasting break, so I'm just going to remove the latest version number and point everyone at the download page. Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 18, 2017 Share Posted January 18, 2017 Ok that does explain the issue - I have the latest Omnivore and have the menu item. One last question before I sorta give up. I copied the scoreeater.s file from this entry: http://atariage.com/forums/topic/255262-jumpman-level-design-contest/page-4#entry3674126 I renamed it to x.s I created a new level in the same folder called x.atr When I tried to add the custom code file I got an error stating: In file x.s line 4-- Error: Illegal label name, must start with '@', '?', or a letter Here are the first couple of lines of the file: ;score eater, a jumpman level ;by Kevin Savetz, October 26-27 2016 .org $2900 vbi1: It seems it doesnt like .org $900???? Quote Link to comment Share on other sites More sharing options...
Savetz Posted January 18, 2017 Share Posted January 18, 2017 You're right — it doesn't work. This is my fault, but really @playermissile's fault He changed Omnivore's source code syntax from cc65 to Mac/65. So — while score eater and jetpack compiled fine when I wrote them, Omnivore's required syntax changed out from under me since then. I need to update the code to the new syntax. In the mean time, lasers.s is already in Mac/65 syntax so it should work. —Kevin Ok that does explain the issue - I have the latest Omnivore and have the menu item. One last question before I sorta give up. I copied the scoreeater.s file from this entry: http://atariage.com/forums/topic/255262-jumpman-level-design-contest/page-4#entry3674126 I renamed it to x.s I created a new level in the same folder called x.atr When I tried to add the custom code file I got an error stating: In file x.s line 4-- Error: Illegal label name, must start with '@', '?', or a letter Here are the first couple of lines of the file: ;score eater, a jumpman level ;by Kevin Savetz, October 26-27 2016 .org $2900 vbi1: It seems it doesnt like .org $900???? Quote Link to comment Share on other sites More sharing options...
Savetz Posted January 19, 2017 Share Posted January 19, 2017 I have corrected the code format for jetpack and scoreeater. —Kevin scoreeater.s jetpack.s 1 Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 19, 2017 Share Posted January 19, 2017 Excellent - thanks! Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 19, 2017 Share Posted January 19, 2017 One last question - is there some easy to use editor on the PC which would give me the sprite strings for the data (is it in hex?) $00,$00,$24,$18,$18,$24,$00,$00 Quote Link to comment Share on other sites More sharing options...
Savetz Posted January 19, 2017 Share Posted January 19, 2017 I don't know. I don't use a PC, and anyway I like to design graphics on graph paper. On a Mac, you can the the calculator app: in binary mode, enter the image data for that line (e.g. 10010101 then convert to hex (95). I'm sure something is similar on a PC. -Kevin One last question - is there some easy to use editor on the PC which would give me the sprite strings for the data (is it in hex?) $00,$00,$24,$18,$18,$24,$00,$00 1 Quote Link to comment Share on other sites More sharing options...
playermissile Posted January 19, 2017 Author Share Posted January 19, 2017 You're right — it doesn't work. This is my fault, but really @playermissile's fault He changed Omnivore's source code syntax from cc65 to Mac/65. So — while score eater and jetpack compiled fine when I wrote them, Omnivore's required syntax changed out from under me since then. I need to update the code to the new syntax. In the mean time, lasers.s is already in Mac/65 syntax so it should work. The previous system (unpublished, Kevin was testing it) used the assembler & linker from cc65, but it was Makefile based and not integrated into Omnivore. Linking on cc65 is a particular pain, because you have to set up all these strange segments in a separate file and there's precious little documentation. And I don't know how it would have ever worked under Windows. So, wanting to make life much, much easier for everybody except Kevin, I found this great standalone assembler, ATasm, that uses MAC/65 source. I hacked around with it and created a python wrapper, then embedded this into Omnivore. It is much simpler and easier to use, plus all the vectors and triggers are automatically plugged into the level. Kevin is welcome to go back to the cc65 approach if he wants to. 1 Quote Link to comment Share on other sites More sharing options...
playermissile Posted January 19, 2017 Author Share Posted January 19, 2017 One last question - is there some easy to use editor on the PC which would give me the sprite strings for the data (is it in hex?) $00,$00,$24,$18,$18,$24,$00,$00 There's a flash-based player you can use from your browser at http://www.playsoft.co.uk/aplayed.html You can save the data in a binary format to reload in the browser, or LIST it to a file and you'll get the text output you want. It can do animation, too. 1 Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 19, 2017 Share Posted January 19, 2017 There's a flash-based player you can use from your browser at http://www.playsoft.co.uk/aplayed.html You can save the data in a binary format to reload in the browser, or LIST it to a file and you'll get the text output you want. It can do animation, too. That worked perfectly - expect a few updates to some of my older levels Quote Link to comment Share on other sites More sharing options...
Savetz Posted April 8, 2017 Share Posted April 8, 2017 It's been too long, but I will start to post the source code to Randy Glover's custom-code Jumpman levels, with my comments. By studying the code and my comments, you can learn to make custom-coded levels, too! There's no custom code on level 1. Here's level 2, Robots II. 02: robots I.s ; Commented code for ROBOTS II Jumpman level ; Comments by Kevin Savetz, 2017 *= $2880 L2880 JSR $49d0 ; Standard main game loop L2883 JSR $4b00 LDA L283E CMP #$00 BEQ L289E LDA $30be CMP #$08 BCC L2883 LDA $30f0 CMP #$ff BNE L2880 JMP L283F L289e JMP (L2844) *= $2900 LDA $30bd ; VBI entry point. CMP #$02 ; if Jumpman is super dead, BNE L2912 L2907 JMP $311b ; exit L290a LDA #$00 ; after the 2x loop STA L284F+1 ; Set no peanut has been taken JMP $311b ; exit L2912 LDA L2A5C ; $2a5c is Are Players initialized? CMP #$00 BNE L291C JMP L2A0C ; Go initialize Players. L291c JSR $41e0 ; Players are already initialized. 41e0 gets a number that's ; 1 just 1/4 of the time BNE L2907 ; exit 1/4 of the time. Slows things down. INC L2A65 LDA L2A65 ; alternates between 0 and 1 for animation frames AND #$01 STA L2A65 ; alternate it LDX #$ff L292e INX ; this loop is done twice, as 0 and 1 CPX #$02 BEQ L290A ; exit the loop LDA L2A5A,X ; is robot already on the move to a destination? CMP #$00 BNE L2990 ; If so, JMP away LDA L284F+1 ; Robot is not on the move. CMP #$00 ; Has a peanut just been taken? BNE L2955 ; If so, JMP away LDA L2A66,X ; Nope. No robots are not moving, so just animate in place. ; 2a66 Counts 1-4 AND #$03 ; set the image for each robot STA L2A66,X ; to one of the first 4 graphics INC L2A66,X ; rotating in order LDA L2A66,X ; their graphics move in unison STA $3076,X ; Set image data for Player 2&3 JMP L292E ; next loop L2955 JSR L29DA ; Oh boy a peanut has been taken LDA #$01 ; reminder: we're in a loop where X will be 0 or 1 STA L2A5A,X ; Set this robot is on the move LDA L2A61,X ; get pointer to next 3-tuple of movement data, LB STA $cb ; cb-d1 are scratch 0-page addresses LDA L2A63,X ; starts by loading cb-cc with 2e00 when X=0 and 2f00 when X=1 STA $cc LDY #$00 LDA ($cb),Y ; load 2e00, e.g. This is the robot's X change. STA L2A5D,X ; remember robot's X change INY LDA ($cb),Y ; load 2e01, e.g. STA L2A5F,X ; remember robot's Y change INY LDA ($cb),Y ; load 2e02, e.g. STA L2A68,X ; remember robot move counter LDA L2A61,X ; pointer to next 3-tuple of movement data CLC ADC #$03 ; set up pointer to read next set STA L2A61,X LDA L2A68,X ; get robot move counter CMP #$00 BNE L292E ; if >0, iterate X to next robot STA L2A5A,X ; robot's not to its destination yet. Store counter in the On The Move? byte JMP L292E ; iterate X to next robot L2990 DEC L2A68,X ; Robot is not to its destination. Move a step. Decrement robot move countdown. BEQ L2955 ; if its 0, jump to oh boy a peanut has been taken LDA $306c,X ; get Horizontal position of robot CLC ADC L2A5D,X ; add robot X change STA $306c,X ; change robot's X CLC LDA $3071,X ; get Vertical position of robot ADC L2A5F,X ; add robot Y change STA $3071,X ; change robot's Y LDA L2A5D,X ; get robot X change again CMP #$02 ; Show graphic for robot facing the right way, and animate. is it going 02 (right)? BEQ L29B9 CMP #$fe ; is it fe (left)? BEQ L29BE LDA #$05 ; robot's X is not changing (so it's on a ladder) JMP L29C3 L29b9 LDA #$01 ; it's 02 right, so use image 1 (or 2) JMP L29C3 L29be LDA #$03 ; its fe left, so use image 3 (or 4) JMP L29C3 ; this JMP is silly. L29c3 CLC ; A is loaded with a pointer to a different image based on X movement ADC L2A65 ; add 0 or 1 to animate movement STA $3076,X ; Set image data for robot JMP L292E ; end of loop; NEXT X LDA #$00 ; THIS CODE IS UNREACHABLE STA L2A5A,X ; UNREACHABLE:Store that robot has reached its destination, no longer moving LDA #$01 ; UNREACHABLE: STA L2A66,X ; UNREACHABLE:reset 1-4 counter back to 1 for standing still animation JMP L292E ; UNREACHABLE:iterate loop; NEXT X L29da LDA #$f1 ; sound subroutine STA $3040 LDA #$29 ; load address of sound STA $3041 STX L29F0 ; temp. storage of X register. Basically, a PHX LDA #$07 JSR $32b0 ; submit the sound list to the player for robot sound LDX L29F0 ; reset X register after JSR. PLX RTS ; end sound subrouine L29f0 BRK ; Temporary stortage of X in the sound routine. .byte $01, $a2, $14, $01; Robot sound data .byte $f0, $01, $3c, $01 .byte $c8, $01, $64, $01 .byte $a0, $01, $8c, $01 .byte $78, $01, $7d, $01 .byte $73, $01, $82, $01 .byte $6e, $01, $00 L2a0c LDA #$00 ; PM Initialization STA $3080 ; old Y position of Player 2 STA $3081 ; old Y position of Player 3 LDA #$6a STA $305d ; image data LB for Player 2 STA $305e ; image data LB for Player 3 LDA #$2a STA $3062 ; image data HB for Player 3 STA $3063 ; image data HB for Player 3 LDA #$0c STA $3067 ; image data bytes per image for Player 2 STA $3068 ; image data bytes per image for Player 3 LDA #$01 STA $3076 ; Set image data for Player 2 STA $3077 ; Set image data for Player 3 LDA L2A5D STA $306c ; Horizontal position of player 2 LDA L2A5E STA $306d ; Horizontal position of player 3 LDA L2A5F STA $3071 ; Y position of Player 2 LDA L2A60 STA $3072 ; Y position of Player 3 LDA #$01 STA $3058 ; P2 active STA $3059 ; P3 active INC L2A5C ; Mark players as initialized JMP $311b ; exit L2a5a .byte $00 ; Player 2 on the move? 0=reached destination .byte $00 ; Player 3 on the move? 0=reached destination L2a5c .byte $00 ; Are Players initialized? 1=yes L2a5d .byte $98 ; Player 2 robot X change L2a5e .byte $44 ; Player 3 robot X change L2a5f .byte $be ; Player 2 robot Y change L2a60 .byte $32 ; Player 3 robot Y change L2a61 .byte $00 ; Player 2 pointer to next 3-tuple of movement data, LB .byte $00 ; Player 3 pointer to next 3-tuple of movement data, LB L2a63 .byte $2e ; Player 2 pointer to 3-tuples of movement data, HB (this never changes) .byte $2f ; Player 3 pointer to 3-tuples of movement data, HB (this never changes) L2a65 .byte $00 ; alternates between 0 and 1 (for animation) L2a66 .byte $01 ; Counts 1-4 for Player 2 robot animation .byte $01 ; Counts 1-4 for Player 3 robot animation L2a68 .byte $00 ; Player 2 robot move countdown .byte $00 ; Player 3 robot move countdown .byte $18, $3c, $70, $70; UNUSED DATA .byte $3c, $18, $18, $24 .byte $42, $81, $81, $81 .byte $18, $3c, $70, $70 .byte $3c, $18, $18, $24 .byte $42, $81, $42, $24 .byte $18, $3c, $0e, $0e .byte $3c, $18, $18, $18 .byte $24, $42, $42, $42 .byte $18, $3c, $0e, $0e .byte $3c, $18, $18, $18 .byte $24, $42, $24, $18 .byte $18, $3c, $66, $66 .byte $3c, $18, $18, $18 .byte $18, $24, $42, $81 .byte $18, $3c, $66, $66 .byte $3c, $18, $18, $18 .byte $18, $18, $24, $42 What follows is a lot of mystery code that should not be there, which is duplicated in Roll Me Over. Then some graphic data from The Roost. Skipping all that mess. *= $2dff BRK ; movement data for Player 2 bot (orange) .byte $02 ; 3-tuples: X change - +2 pixels is right .byte $00 ; Y change is 0 .byte $05 ; ...for 5 cycles .byte $00 ; step 2 of move 1: moving up so X change is 0 .byte $fe ; Y change is -2. .byte $21 ; for 21 cycles .byte $02, $00 ; step 3: move right again .byte $07 ; for 7 cycles .byte $00, $00, $00, $02; 000000 means end of data for that move .byte $00, $0d, $00, $fe .byte $28, $fe, $00, $08 .byte $00, $00, $00, $fe .byte $01, $10, $fe, $00 .byte $0f, $00, $fe, $11 .byte $fe, $00, $09, $00 .byte $00, $00, $02, $00 .byte $09, $00, $02, $11 .byte $fe, $00, $0b, $00 .byte $02, $11, $fe, $00 .byte $09, $00, $00, $00 .byte $fe, $00, $07, $00 .byte $02, $11, $fe, $00 .byte $0d, $00, $02, $11 .byte $02, $00, $09, $00 .byte $00, $00, $02, $00 .byte $05, $02, $01, $22 .byte $02, $00, $06, $00 .byte $00, $00, $02, $00 .byte $05, $00, $fe, $21 .byte $02, $00, $07, $00 .byte $00, $00, $02, $00 .byte $0d, $00, $fe, $28 .byte $fe, $00, $08, $00 .byte $00, $00, $fe, $01 .byte $10, $fe, $00, $0f .byte $00, $fe, $11, $fe .byte $00, $09, $00, $00 .byte $00, $02, $00, $09 .byte $00, $02, $11, $fe .byte $00, $0b, $00, $02 .byte $11, $fe, $00, $09 .byte $00, $00, $00, $fe .byte $00, $07, $00, $02 .byte $11, $fe, $00, $0d .byte $00, $02, $11, $02 .byte $00, $09, $00, $00 .byte $00, $02, $00, $05 .byte $02, $01, $22, $02 .byte $00, $06, $00, $00 .byte $00 *= $2f00 .byte $02, $01, $0f, $02; movement data for Player 3 bot (green) .byte $00, $05, $00, $02 .byte $11, $02, $00, $0d .byte $00, $00, $00, $fe .byte $00, $1b, $00, $02 .byte $11, $02, $00, $0b .byte $00, $00, $00, $fe .byte $00, $17, $00, $02 .byte $21, $02, $00, $07 .byte $00, $00, $00, $fe .byte $00, $07, $00, $fe .byte $11, $02, $00, $09 .byte $00, $00, $00, $fe .byte $00, $09, $00, $fe .byte $11, $02, $00, $0d .byte $00, $fe, $11, $02 .byte $00, $23, $00, $00 .byte $00, $00, $fe, $11 .byte $fe, $00, $19, $fe .byte $ff, $0f, $00, $00 .byte $00, $02, $01, $0f .byte $02, $00, $05, $00 .byte $02, $11, $02, $00 .byte $0d, $00, $00, $00 .byte $fe, $00, $1b, $00 .byte $02, $11, $02, $00 .byte $0b, $00, $00, $00 .byte $fe, $00, $17, $00 .byte $02, $21, $02, $00 .byte $07, $00, $00, $00 .byte $fe, $00, $07, $00 .byte $fe, $11, $02, $00 .byte $09, $00, $00, $00 .byte $fe, $00, $09, $00 .byte $fe, $11, $02, $00 .byte $0d, $00, $fe, $11 .byte $02, $00, $23, $00 .byte $00, $00, $00, $fe .byte $11, $fe, $00, $19 .byte $fe, $ff, $0f, $00 .byte $00, $00 4 Quote Link to comment Share on other sites More sharing options...
Savetz Posted April 8, 2017 Share Posted April 8, 2017 Commented code for BOMBS AWAY. 03: bombs away.s *= $2860 L2860 JSR $49d0 ; Main loop (standard) L2863 JSR $4b00 LDA L283E CMP #$00 BEQ L287E LDA $30be CMP #$08 BCC L2863 LDA $30f0 CMP #$ff BNE L2860 JMP L283F L287e JMP (L2844) *= $2900 LDA $30bd ; VBI entry point #1 CMP #$02 ; is Jumpman super dead? BNE L2916 LDA $3034 ; Yes, he's dead. Is a sound playing on voice 2? (Explosion noise) CMP #$00 BNE L2913 ; There's a sound, exit. (Wait for the explosion sound to end) LDA #$00 ; Explosion sound is over, so quiet and falling sound, which happens on audio channel 3 STA $d205 ; Quiet AUDC3 L2913 JMP $311b L2916 JSR $41e0 ; Jumpman is alive BNE L2913 ; Exit 1/4 of the time. Keeps the bombs from falling too fast L291b LDA $d20a ; get a random number AND #$07 ; only want 3 bits - make the number from 0-7 BNE L2960 ; if it's >0 JMP to make bombs fall and explode LDA $d20a ; get another random number AND #$07 ; make it 0-7 too CMP #$05 ; this is a second chance for bombdrop BCS L2960 ; if it's >= 5, JMP to make bombs fall and explode TAX LDA L29C3,X ; check the table of available Players to see if a Player is available as a new bomb CMP #$00 BNE L2960 ; if that table entry>0, Player not available as a new bomb, so, JMP away LDA #$01 ; Start a new bomb STA $3055,X ; Turn Player on LDA #$c9 STA $305a,X ; image data LB LDA #$29 STA $305f,X ; image data HB. We're using the first group of bombs in the image series. LDA #$08 STA $3064,X ; image data bytes per image L2947 LDA $d20a ; random number CMP #$30 BCC L2947 ; if < $30 go get another random # (too far left) CMP #$c8 BCS L2947 ; >= #c8 is also unacceptable (too far right), get another # STA $3069,X ; that's the player X LDA #$01 STA $306e,X ; Player Y = top of screen STA $3073,X ; Use graphic 1 STA L29C3,X ; Set player is in use as a bomb L2960 INC L29C8 ; The following happens whether a new bomb was made or not. LDA L29C8 AND #$03 L2968 STA L29C8 ; 29c8 iterates 0-3 for animation frames LDX #$ff L296d INX ; FOR X = 0 TO 4 CPX #$05 BEQ L29AA ; if X=5 end the loop LDA L29C3,X ; 29c3 is "is this player usable as a bomb?" 0=available, 1=in use, 5-0a=exploding, ff=don't use CMP #$ff BEQ L296D ; this player is not available as a bomb, iterate to next player CMP #$05 BCS L296D ; if its >=5 (exploding), iterate to next player CMP #$00 BEQ L296D ; if its 0, iterate to next player LDA $306e,X ; So it must be 1. Make it fall. Get Y position CLC ADC #$03 ; move it down CMP #$c5 ; if it at the bottom, 'splode it BCS L29A2 STA $306e,X ; if it's not too low, save new Y position STA $d204 ; falling sound on AUDF3 LDA #$a2 STA $d205 ; AUDC3 LDA L29C8 ; the 0-3 counter CLC ADC #$01 STA $3073,X ; Set Player to next animation frame JMP L296D ; NEXT X L29a2 LDA #$05 ; Bomb reached the floor STA L29C3,X ; Mark it as ready to explode. JMP L296D ; NEXT X L29aa LDA L29C6 ; done iterating thru players ORA L29C6 ; if both bombs are "availilable" (not falling or exploding) then quiet AUD3 ORA L29C7 ; Notice how 29c6 is used twice. I bet one of those was originally 29c3 to support the combined-missile Player bomb CMP #$00 BEQ L29BA JMP $311b L29ba STA $d204 ; quiet AUDF3 STA $d205 ; quiet AUDC3 JMP $311b L29c3 .byte $ff ; Table of Players. Don't use Combined Missile Player as a bomb. (But you can! try it by changing it to 0) ; I ended up doing that in my Smart Bombs Away level .byte $ff ; don't use Player 0 as a bomb - that's jumpman! .byte $ff ; don't use player 1 as a bomb - that's the shadow! L29c6 BRK ; Do use Player 2 for a bomb L29c7 BRK ; Do use Player 3 as a bomb L29c8 BRK ; iterates 0-3 for animation frames .byte $66, $3c, $18, $18; Images start here .byte $3c, $2c, $3c, $18 .byte $34, $3c, $18, $18 .byte $3c, $34, $3c, $18 .byte $18, $18, $18, $18 .byte $3c, $3c, $3c, $18 .byte $2c, $3c, $18, $18 .byte $3c, $3c, $3c, $18 .byte $00, $00, $00, $00 .byte $00, $24, $18, $18 .byte $00, $00, $00, $24 .byte $3c, $18, $7e, $18 .byte $10, $4a, $52, $5a .byte $2c, $bd, $7e, $18 .byte $00, $00, $08, $52 .byte $3c, $99, $7e, $18 .byte $00, $00, $00, $08 .byte $10, $4a, $3c, $18 .byte $4c, $1b, $31, $00 .byte $ff, $ff, $00, $00 .byte $00 .byte $66, $3c, $18, $18; Here's a second copy of the bomb graphics, not used. .byte $3c, $2c, $3c, $18 .byte $34, $3c, $18, $18 .byte $3c, $34, $3c, $18 .byte $18, $18, $18, $18 .byte $3c, $3c, $3c, $18 .byte $2c, $3c, $18, $18 .byte $3c, $3c, $3c, $18 .byte $00, $00, $00, $00 .byte $00, $24, $18, $18 .byte $00, $00, $00, $24 .byte $3c, $18, $7e, $18 .byte $10, $4a, $52, $5a .byte $2c, $bd, $7e, $18 .byte $00, $00, $08, $52 .byte $3c, $99, $7e, $18 .byte $00, $00, $00, $08 .byte $10, $4a, $3c, $18 *= $2ac0 ORA ($8e,X) ; Sound data for explosion .byte $14 .byte $03 ORA ($8b,X) ASL $0103,X DEY PLP .byte $03 ORA ($85,X) .byte $32 .byte $03 ORA ($81,X) .byte $3c .byte $03 *= $2b00 INC L2B9E ; VBI entry point #2 - handles explosions LDA L2B9E AND #$01 STA L2B9E ; 2b9e switches between 0 and 1 BEQ L2B10 L2b0d JMP $311b ; if it's 1 - half the time - exit L2b10 LDX #$ff L2b12 INX ; FOR X=0 to 4 CPX #$05 BEQ L2B0D ; after the looping, exit LDA L29C3,X CMP #$0a ; Has this bomb finished explosion sequence? (05-0a) BEQ L2B6C ; Yes: JMP away for cleanup BCS L2B12 ; if status>$0a (that is, $ff, iterate to next player) CMP #$05 ; if it is not about to explode or already exploding, iterate to next bomb BCC L2B12 ; NEXT X INC L29C3,X ; This bomb is exploding. Increment explosion counter (5-0a) there are 4 animation frames, 6-9. 5 is ready to explode, 0a is done and ready for cleanup Note: we've incremented it for NEXT time, but A is still the lower number. STA $3073,X ; choose image for bomb. conveniently, explosion images are numbers 6-9 in the graphics list. CMP #$05 ; if this is the first image in the explosion sequence BEQ L2B41 ; JMP away to cycle back to 1st frame L2b2e LDA $3073,X ; get current animation image in use for bomb TAY ; which goes in Y LDA L2B94,Y ; It looks up the animation frame number in this table to get the color for this part of the explosion. The first 5 cells of the table are unused; only the data in the 5th-0Ath cells are used. PHA ; That color number goes on the stack LDA L2B8A,X ; offset table for Player colors TAY ; which goes in Y PLA ; fetch the color the stack STA $02c0,Y ; change Player color for pretty, colorful explosion JMP L2B12 ; NEXT X L2b41 LDA $3069,X ; cycle back to 1st image of 4 in a series SEC SBC #$04 STA $3069,X ; revert to 1st image in animation set LDA L2B8F,X ; get offset for adjusting Player width from table TAY LDA #$55 ; $55 is an interesting choice here for doube width. References I found say to use 0 for std, 1 for dbl, 2 for quad. There's no $55. But the LSB makes it double width. STA $d008,Y ; adjust Player width STX L2B6B ; PHX: Store X register (our offset from the table) for a sec, sound routine at 32b0's gonna clobber it LDA #$c0 STA $3040 ; LB of sound data LDA #$2a STA $3041 ; HB of sound data LDA #$04 ; A is the duration or speed? for the music driver JSR $32b0 ; music driver: start playing a tune pointed to by $3040 LDX L2B6B ; PLX: I want my X back JMP L2B2E ; Loop back L2b6b BRK ; Temp storage for X register. 6502 doesn't have PHX. Sad! L2b6c LDA L2B8F,X ; Bomb explosion sequence is done, clean up TAY ; 2b8f-2b93 is table of offets from d008 for resetting Player widths LDA #$00 STA $d008,Y ; reset Player width to single LDA L2B8A,X ; 2b8a-e is table of offets for reseting Player colors, from 02c0 TAY LDA L282A,Y ; get startup color for that Player STA $02c0,Y ; reset player colors after splosion LDA #$00 STA L29C3,X ; reset Player: available for new bomb STA $3069,X ; set player X offscreen JMP L2B12 ; NEXT X L2b8a .byte $07, $00, $01, $02; offset table - reset Player colors from $$02c0 .byte $03 L2b8f .byte $04, $00, $01, $02; offset table - resetting player widths from $d008 .byte $03 L2b94 .byte $00, $00, $00, $00; Table of colors for explosion. The first 5 bytes are unused, the real colors are in the 5th thru 0a spaces .byte $00, $54, $1a, $0f .byte $28, $54 L2b9e BRK ; switches between 0 and 1 ; later in the level there's some garbage data 2 Quote Link to comment Share on other sites More sharing options...
Savetz Posted April 8, 2017 Share Posted April 8, 2017 Jumping Blocks. 04: jumping blocks.s ; Commented code for JUMPING BLOCKS Jumpman level ; Comments by Kevin Savetz, 2017 *= $2860 LDA #$04 STA $30b6 ; Missiles are 2 pixels high LDA #$55 ; Wide missiles STA $d00c JMP L2880 *= $2880 L2880 JSR $49d0 L2883 JSR $4b00 LDA L283E CMP #$00 L288b BEQ L289E L288d LDA $30be CMP #$08 BCC L2883 LDA $30f0 CMP #$ff BNE L2880 JMP L28A6 L289e LDA #$02 STA $30b6 JMP (L2844) L28a6 LDA #$02 STA $30b6 ; put Missile height back to normal JMP L283E+1 *= $28f9 BRK ; This level is interesting, programatically very simple. BRK ; It uses the Jumpman engine's regular bullet logic BRK ; But changes the size and color of the bullets. BRK ; Instead of the usual "bullet hit means death" code at 49a0, BRK ; the level's custom hit detection routine tricks the engine BRK ; into thinking the trigger was pressed and the joystick was BRK ; moved to jump in one of three directions. LDA $3098 ; VBI entry point ORA $3099 L2906 ORA $309a ORA $309b AND #$01 ; Did any of the Missiles hit Jumpman? (In some other levels Glover uses $30a0 to do the exact same thing. I wonder if this was written before he wrote that.) CMP #$00 BNE L2915 JMP L2943 ; if not, jump away L2915 LDA #$10 ; A missile hit Jumpman STA $302c ; Fake pressing the trigger LDA $d20a AND #$03 ; Random # 0-3 CMP #$00 ; Fake joystick push in a direction based on the random # BEQ L292B CMP #$01 BEQ L2933 CMP #$02 BEQ L293B L292b LDA #$e0 ; Joystick up STA $3028 JMP L2953 L2933 LDA #$70 ; Joystick right STA $3028 ; STA here makes the game engine think the stick is pushed JMP L2953 L293b LDA #$b0 ; Joystick left STA $3028 JMP L2953 L2943 LDA $3028 ; No missile hit Jumpman AND #$0f ; ?force the joystick to 0-127. Hm, why not just STA 0? STA $3028 LDA $302c AND #$0f ; ?Same thing with the trigger result. What information is saved in those 4 bits? STA $302c L2953 LDA $30b8 ; This continues whether or not a missile hit JM STA $02c7 ; Change the misiles to a random(ish) color. JMP $311b ; And we're done ORA ($9d,X) ; The rest of the level code is junk/unused code. ORA L2C30+1 ; Some seems to be assembly source from Builder level. See Reverse Engineering Notes. 1 Quote Link to comment Share on other sites More sharing options...
Savetz Posted April 8, 2017 Share Posted April 8, 2017 Vampire. 05: vampire.s *= $2900 LDA $30be ; VBI vector. If Jumpman status CMP #$08 ; is super dead BCS L290E ; exit this routine. Allows the death song to play with out bats flying around LDA $30bd ; Check the other Jumpman alive flag. CMP #$02 ; if JM is Dead With Birdies BNE L2911 L290e JMP $311b ; ...also exit this routine L2911 LDA L2A73 ; check Are Players initialized? byte CMP #$00 BNE L291B JMP L29C8 ; Not initialized, JMP away to initialize them L291b INC L2A5E ; 2a5e increments 0-7 LDA L2A5E ; only continue if it==7 CMP #$07 ; otherwise exit BNE L290E ; this gives the bats their relatively slow pace LDA #$00 STA L2A5E ; reset counter to 0 LDX #$ff L292c INX ; FOR X=0 TO 4 CPX #$05 ; Iterating through the Players, where 0=Combined Missile Player, 3 and 4=the other available Players. These are the bats. BEQ L290E ; after the loop, exit CPX #$01 BEQ L292C ; if X=1, NEXT X CPX #$02 BEQ L292C ; if X=2, NEXT X LDA L2A5F,X ; Check Bat Asleep/Awake Table CMP #$02 BEQ L2943 JMP L292C ; If it's not 2 (awake), NEXT X L2943 INC $3073,X ; Move bat to next animation frame LDA $3073,X CMP #$08 ; But if its 8... BNE L2952 LDA #$02 ; move it back to 2. The flying animation is frames 2-7 STA $3073,X L2952 LDA $306a ; Get Jumpman X CMP $3069,X ; Compare with Bat X BEQ L298B ; if they're equal, JMP away LDA $306f ; But they're not equal, so get Jumpman Y CMP $306e,X ; compare with Bat Y BEQ L29A8 ; If the Ys are equal, JMP away CLC ; Neither Xs or Ys are equal. Sad bat. L2963 LDA $3069,X ; Get Bat X again ADC L2A64,X ; Add X to this bat's entry in Bat X Change Table STA $3069,X ; New Bat X CLC LDA $306e,X ; Get Bat Y CLC ADC L2A68+1,X ; Add Y to this bat's entry in Bat Y change table CMP #$c2 BCS L297E ; If the Y would be >=$c2, JMP to fix that STA $306e,X ; New Bat Y JMP L292C ; NEXT X L297e LDA #$00 ; Bat Y is >=C2, at bottom of screen, move it back to top STA $306e,X LDA #$02 STA L2A68+1,X ; Adjust Bat Y Change Table: This bat will continue moving downward JMP L292C ; NEXT X L298b LDA #$00 ; JMP dest when Bat X = JM X STA L2A64,X ; Store 0 in this Bat's X Change Table entry LDA $306f ; Get JM Y CMP $306e,X ; Compare to Bat's Y BCS L29A0 ; JMP away if JM Y >= Bat Y (JM is below bat) LDA #$fe ; Bat is below JM, so STA L2A68+1,X ; modify Bat Change Table entry to move it up JMP L2A0E L29a0 LDA #$02 ; Bat is above JM, so... STA L2A68+1,X ; Modify Bat Y Change table to move it down JMP L2A0E L29a8 LDA #$00 ; JMP dest when Bat Y = JM Y STA L2A68+1,X ; Modify Bat's Y change table entry to 0 LDA $306a ; Get Jumpman's X CMP $3069,X ; compare to bat's X BCS L29BD ; If JM X >= Bat's (bat is to the left of JM) JMP away LDA #$fe ; Bat wants to move left STA L2A64,X ; store that in X change table JMP L2A0E L29bd LDA #$02 ; Bat is to JM's left STA L2A64,X ; Modify Bat X Table to start Bat moving right JMP L2A0E L29c5 JMP $311b L29c8 LDX #$ff ; Player initialization STX L2A73 ; Set Are Players Initialized? byte L29cd INX ; FOR X=0 to 4 CPX #$05 BEQ L29C5 ; after this loop, exit CPX #$01 BEQ L29CD ; IF X=1 NEXT X cuz this player is for JM CPX #$02 BEQ L29CD ; IF X=2 NEXT X cuz this player is for the shadow LDA #$26 STA $305a,X ; Player Image Data LB LDA #$2a STA $305f,X ; Player Image Data Table HB LDA #$08 STA $3064,X ; there are 8 data bytes per image STA $3082,X ; just stuff anything other than the startup image in the "old" image data table LDA L2A64,X ; Get Bat Starting X from Bat X Change Table STA $3069,X ; Save Bat X LDA L2A68+1,X ; Get Bat starting Y from table STA $306e,X ; Save Bat Y LDA #$01 STA $3073,X ; Start all bats with Image 1 (sleeping) STA $3055,X ; Activate that Player LDA #$00 STA L2A64,X ; From now on the Bat X table is change (X movement direction) so store 0. Bats always start traveling down LDA #$02 STA L2A68+1,X ; Same thing for the Y change table. Bats will head down when they wake JMP L29CD ; NEXT X L2a0d BRK ; temp storage for X L2a0e STX L2A0D ; If bat changed X or Y direction, it wants to talk about it. PHX LDA #$74 STA $3040 ; Sound data LB LDA #$2a STA $3041 ; Sound data HB LDA #$07 ; This is speed or duration or something for the sound routine JSR $32b0 ; start playing bat sound LDX L2A0D ; PLX JMP L2963 ; JMP to actually move the bat based on new X and Y change choices L2a26 .byte $24, $18, $18, $3c; Image Data .byte $7e, $18, $18, $00 .byte $81, $42, $42, $3c .byte $18, $00, $00, $00 .byte $00, $00, $81, $7e .byte $18, $00, $00, $00 .byte $00, $00, $00, $7e .byte $99, $00, $00, $00 .byte $00, $00, $00, $3c .byte $5a, $42, $81, $00 .byte $00, $00, $00, $5a .byte $bd, $00, $00, $00 .byte $00, $00, $81, $db .byte $3c, $00, $00, $00 L2a5e .byte $00 ; Counts 0-7 L2a5f .byte $01, $00, $00, $01; Bat asleep(01)/wake(02) Table L2a63 .byte $01 L2a64 .byte $74, $00, $00, $7c; Bat X Change Table .byte $84 L2a69 .byte $2a, $00, $00, $28; Bat Y Change Table .byte $2a .byte $01, $00, $00, $01; This looks like a "use this Player as a bat?" table but is unused .byte $01 L2a73 .byte $00 ; Are Players Initialized? byte 0=no .byte $01, $a6, $05, $01; Sound data .byte $0f, $01, $0a, $01 .byte $00, $a0, $cc, $ae .byte $a0, $c7, $cc, $cf .byte $d6, $c5, $d2, $20 .byte $a0, $cc, $ae, $a0 .byte $c7, $cc, $cf, $d6 .byte $c5, $d2, $20 *= $2aff BRK ; This VBI vector runs with every peanut collection L2b00 LDA L283E ; # of peanuts left to take? Level starts with 14. CMP #$0c ; If >=12, exit BCS L2B13 CMP #$09 BCS L2B14 ; if 9, wake 1st bat CMP #$06 BCS L2B21 ; if 6, wake second bat CMP #$03 BCS L2B2E ; if 3, wake 3rd bat L2b13 RTS ; otherwise exit L2b14 LDA L2A5F ; Is bat 1 (CMP) sleeping? CMP #$01 ; he really should be at this juncture BNE L2B13 ; but if not, exit LDA #$02 STA L2A5F ; mark him as awake RTS ; exit L2b21 LDA L2A62 ; Is bat 2 (Player 2) asleep CMP #$01 ; again, he really should be when we get here BNE L2B13 ; if not, exit LDA #$02 STA L2A62 ; mark him as awake RTS ; exit L2b2e LDA L2A62+1 ; and Bat 3 (Player 3) CMP #$01 BNE L2B13 LDA #$02 STA L2A62+1 ; same deal RTS ; The rest of the stuff on this level is unused/junk, including ; image data from The Roost 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.