PacManPlus Posted January 4, 2022 Author Share Posted January 4, 2022 Hey Guys: 41 minutes ago, Synthpopalooza said: Can someone point me to wav recordings of the arcade sound fx please? I also noticed that all sounds seem to share one channel. This is good, as we can stack POKEY filters in as many different ways as needed, even using all 4 channels for one sound if we so choose. Hey! RevEng posted the sounds below... They are identical to the arcade, and all the 'Presets' tell what each sound is. On 1/1/2022 at 10:09 PM, RevEng said: Speaking of Defender sound, I'll just leave this here... http://www.dl.unospace.net/defender_sound/ 1 Quote Link to comment Share on other sites More sharing options...
+DrVenkman Posted January 4, 2022 Share Posted January 4, 2022 35 minutes ago, Synthpopalooza said: The key to this: Set up two 16-bit channels in POKEY ... Please again, I'm begging you - get with Fred and be sure HOKEY can handle your files when this eventual masterpiece reaches the Store. At this point, it is increasingly untenable to use a ~40 year old vintage IC for each game we buy. Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted January 4, 2022 Share Posted January 4, 2022 I am in the process of getting a HOKEY to test this stuff out. Far as I know, it's all good on anything not using two tone mode, but I should find out more soon. 5 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted January 6, 2022 Author Share Posted January 6, 2022 Morning all! Just a quick update: I change the clearing of the scanner area to just removing the 'blip' immediately before placing the new 'blip' on the screen. While it did save a LOT of cycles, I'm still suffering from slow-down (and missing blips in the radar) when there are a lot of objects on the screen. I did the '7800 heat' utility again, and there doesn't seem to be any 'problem' or 'out of control' areas... This is really bugging me... I KNOW this should work... 4 Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted January 6, 2022 Share Posted January 6, 2022 Also FYI: Trying to avoid two tone mode here if I can help it. Don't think it'll be needed. Hopefully HOKEY can handle the hi-pass filtering tho 1 Quote Link to comment Share on other sites More sharing options...
ZylonBane Posted January 6, 2022 Share Posted January 6, 2022 It would be nice if there was some way, perhaps even hidden, to change the palette's purple color to red. Purple swarmers just look odd to me. Also, any chance of getting the "firework" explosions and warp-in effects? Even the ColecoVision and NES versions managed to squeeze those in. 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted January 6, 2022 Share Posted January 6, 2022 6 hours ago, PacManPlus said: I did the '7800 heat' utility again, and there doesn't seem to be any 'problem' or 'out of control' areas... 7800 heat is good for identifying frequently called small bits of code, but is less useful if the problem is larger chunks of code that aren't as frequently called. (i.e. 10 cycles of instructions looped 10 times will look "hotter" than 100 cycles of instructions called just once, even though the actual cycle cost is the same for both) Some alternative profiling advice... If you haven't already, I'd see what's eating most of your time by commenting out all BACKGRND register hits, and then before each routine you want to profile, change the BACKGRND color to something unique, and on exit from that routine set BACKGRND back to black. When you play the game, the screen will be a realtime-graph of what the cpu hogs are, relative to each other *and* relative to the overall frame time. The one weakness of this technique is that it can't identify routines that run during non-visible/vblank time. But since we usually reserve non-visible time for DL updating code, that's not often a problem. Generally I do the above technique at least once during development, to see how close I am to blowing past the frame timing. For Salvo, it was a useful technique to balance what was happening on even and odd frames. (expensive stuff like collision checks and enemy AI were set to run on different frames, to keep the rest of the action humming at 60Hz) 7 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted January 6, 2022 Author Share Posted January 6, 2022 Hello! 3 hours ago, ZylonBane said: It would be nice if there was some way, perhaps even hidden, to change the palette's purple color to red. Purple swarmers just look odd to me. Also, any chance of getting the "firework" explosions and warp-in effects? Even the ColecoVision and NES versions managed to squeeze those in. I may change the entire purple to red, but that will make the bombers red as well... which might not be a bad thing. The highlights on the player's ship will also be red. Those are on the 'nice to have' list. Which is the list I usually leave until the end to see if it can be done. I'm pretty sure I'll be able to do that with the player's ship upon explosion (I can sneakily remove all other objects from the screen when the explosion happens to get the maximum number of dots for the explosion), but the individual enemy explosions... let me get past these few issues and I can tell better... 2 hours ago, RevEng said: 7800 heat is good for identifying frequently called small bits of code, but is less useful if the problem is larger chunks of code that aren't as frequently called. (i.e. 10 cycles of instructions looped 10 times will look "hotter" than 100 cycles of instructions called just once, even though the actual cycle cost is the same for both) Some alternative profiling advice... If you haven't already, I'd see what's eating most of your time by commenting out all BACKGRND register hits, and then before each routine you want to profile, change the BACKGRND color to something unique, and on exit from that routine set BACKGRND back to black. When you play the game, the screen will be a realtime-graph of what the cpu hogs are, relative to each other *and* relative to the overall frame time. The one weakness of this technique is that it can't identify routines that run during non-visible/vblank time. But since we usually reserve non-visible time for DL updating code, that's not often a problem. Generally I do the above technique at least once during development, to see how close I am to blowing past the frame timing. For Salvo, it was a useful technique to balance what was happening on even and odd frames. (expensive stuff like collision checks and enemy AI were set to run on different frames, to keep the rest of the action humming at 60Hz) I love that idea. Thank you - I'll give that a try. 4 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted January 7, 2022 Author Share Posted January 7, 2022 (edited) 7 hours ago, RevEng said: Some alternative profiling advice... If you haven't already, I'd see what's eating most of your time by commenting out all BACKGRND register hits, and then before each routine you want to profile, change the BACKGRND color to something unique, and on exit from that routine set BACKGRND back to black. When you play the game, the screen will be a realtime-graph of what the cpu hogs are, relative to each other *and* relative to the overall frame time. So I did the above The area of code I did that in... ; HANDLE_ENEMIES - PROCESS THE VARIOUS STATES OF THE ENEMIES. HANDLE_ENEMIES LDA #$00 STA NUM_SCREEN_OBJECTS TAX HEN_LOOP LDA OBJTYPE,X ;SEE IF THIS OBJECT IS POPULATED BMI HEN_NEXT LDA #RED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STA BACKGND JSR HANDLE_ENEMY_MOVEMENT ;MOVE/ANIMATE THE ENEMY FOR EACH TYPE (INCLUDING DYING AND SCORE) LDA #BLUE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STA BACKGND JSR HANDLE_ENEMIES_ON_SCANNER ;UPDATE THE SCANNER LDA #GREEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STA BACKGND JSR HANDLE_ENEMY_SCREEN ;IF THE ENEMY IS ON THE SCREEN, DO SCREEN THINGS. LDA #BROWN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STA BACKGND JSR HANDLE_ENEMY_AGAINST_PLAYER_SHOT ;SEE IF ANY ENEMIES COLLIDED WITH THE PLAYER'S SHOT LDA #BLACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STA BACKGND HEN_NEXT INX CPX #NUM_OBJECTS ;GO THROUGH ALL ENEMIES ON PLANET BMI HEN_LOOP RTS Ummmm........ Wow Edited January 7, 2022 by PacManPlus 1 1 Quote Link to comment Share on other sites More sharing options...
SlidellMan Posted January 7, 2022 Share Posted January 7, 2022 Looks like the 7800 has been doing LSD. 4 Quote Link to comment Share on other sites More sharing options...
RevEng Posted January 7, 2022 Share Posted January 7, 2022 yeah, if you're looping between all enemies, and coloring the different subs within that loop, there's going to be a lot of banding. You could always just do separate enemy loops for each sub too. (which might also help if you want to split some of these subs across frames.) That said, it looks like blue - the radar code - is your biggest cpu hog. (also, you're definitely over a frame). Breaking that one across multiple frames, or otherwise making it more efficient, will probably give you back a lot of cpu. The big green bar at the bottom is likely due to an NMI interrupting the on-screen enemy handling, rather than that particular routine taking extra long for one of the enemies. That also might be the case for the biggest blue bar near the top too. 2 Quote Link to comment Share on other sites More sharing options...
+Pat Brady Posted January 7, 2022 Share Posted January 7, 2022 Do those subroutines have any other callers? IIRC you have 16 enemies, and the loop has 4 jsr's. Each jsr-rts pair costs 12 cycles, so just getting into and out of those subroutines costs 768 cycles per frame. 3 Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted January 7, 2022 Share Posted January 7, 2022 Got the day off, may try more experimemts in soinds. 2 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted January 9, 2022 Author Share Posted January 9, 2022 (edited) Hi all: So, can anyone help reduce the CPU time of this routine please? It's the big CPU time hog to do for at most 42 objects on the planet (32 enemies, 10 humanoids) The routine is what gets an object's vertical and horizontal position relative to the planet (e.g. not the screen), and reduces it to the scanner x and y position. Some background: Planet: 1024 pixels horizontally (arcade Defender had 2048, but we move in 2 pixel increments). I had originally created a single pixel offset graphics set to use, but that quickly became a major PITA. 128 COLUMNS HORIZONTALLY Scanner: 64 Pixels horizontally, split into 16 bytes. Each byte has 4 places where a 'blip' can go: XX000000, 00XX0000, 0000XX00, or 000000XX The routine: ; PUT ENEMY ON SCANNER LDA OBJVPOS,X ;TAKE VERTICAL POSITION LSR ;DIVIDE BY 2 TAY ;MAP FROM VERTICAL POSITION ON SCREEN TO VERTICAL SCANNER POS LDA VPOS_TO_SCANNERV_TABLE,Y ;VERTICAL POSITION IN SCANNER TAY LDA SCNADDRESSL,Y ;INDEX INTO SCANNER RAM, VERTICALLY STA TEMP0 LDA SCNADDRESSH,Y STA TEMP1 LDA OBJHCOL,X ;GET HORISONTAL PLANET COLUMN OF ENEMY ($00-$7F) CLC ;WE NEED TO GET A STATIC COLUMN IN THE SCANNER BETWEEN THE PLANET AND THE ENEMY/HUMANOID ADC #$35 ;I FEEL LIKE THIS SHOULD BE #$40, BUT $35 IS WHAT GIVES AN ACCURATE NUMBER SEC SBC WINDOWSTARTCOL ;SUBTRACT CURRENT WINDOW COLUMN TO GET COLUMN FOR SCANNER LSR ;DIVIDE BY 2 TO GET THE NUMBER OF X POSITIONS IN THE SCANNER AND #$3F ;FOR WRAPAROUND STA TEMP5 ;64 PIXELS IN SCANNER ($00-$3F) LSR ;WE NOW DIVIDE BY 4 TO GET THE BYTE INDEX INTO THE SCANNER RAM LSR ;THERE ARE 16 BYTES PER ROW OF SCANNER RAM STA TEMP4 ;HORIZONTAL POSITION BYTE IN SCANNER LDA TEMP5 AND #$03 ;GET POSITION WITHIN BYTE IN SCANNER STA TEMP5 LDA OBJTYPE,X ;GET ENEMY TYPE ASL ;SHIFT OVER TO CREATE AN INDEX ASL ; WITHIN THE TABLE OF OBJECT TYPE / BYTE POSITION ORA TEMP5 ;'OR' WITH DOUBLE-BIT POSITION TAY ;Y INDEX LDA NMYSCNLINE1,Y ;THIS GETS THE ENEMY TYPE AND POSITION WITHIN THE SCANNER BYTE STA TEMP5 LDY TEMP4 ;HORIZONTAL BYTE POSITION IN SCANNER RAM LDA (TEMP0),Y ;GET WHAT IS ALREADY THERE ORA TEMP5 ;'OR' VALUE WITH NEW OBJECT STA (TEMP0),Y ;STORE TOP LINE INC TEMP1 ;NEXT PAGE DOWN LDA (TEMP0),Y ;GET WHAT WAS ALREADY THERE ORA TEMP5 ;'OR' VALUES WITH NEW OBJECT STA (TEMP0),Y While it works, we've seen how much time it takes. If I can reduce the CPU usage of this routine, we should be good. ? Thanks, Bob Edited January 9, 2022 by PacManPlus 5 1 Quote Link to comment Share on other sites More sharing options...
PacManPlus Posted January 10, 2022 Author Share Posted January 10, 2022 Hi guys: I'm afraid I have bad news. I am unable to get this working any faster, and it's not even at the point where the maximum amount of enemies are on the planet. So, for the second time I'm going to have to put this down permanently. Thank you for the help and feedback, but I think it's time to move on to another project. Bob 6 Quote Link to comment Share on other sites More sharing options...
RevEng Posted January 10, 2022 Share Posted January 10, 2022 [edit - just saw your last reply as I was in the process of editing+posting this, Bob. Figured I might as well go ahead with the post anyway, so the info is here in case you ever want to pick it up.] On 1/9/2022 at 3:10 PM, PacManPlus said: So, can anyone help reduce the CPU time of this routine please? It's the big CPU time hog to do for at most 42 objects on the planet (32 enemies, 10 humanoids) While it works, we've seen how much time it takes. If I can reduce the CPU usage of this routine, we should be good. ? Here's a first-pass at a cycle-bummed version. Assuming I haven't goofed with any of my assumptions, it should save 26 cycles per object, which unfortunately only gets you down to ~75% of the original cycles. If you haven't already, you should also avoid the JSR+RTS pair per object, per Pat Brady's previous post. I've used some undocumented opcodes, but only ones that are known stable, and have been in use with the 7800 for a while. ; PUT ENEMY ON SCANNER LDA OBJVPOS,X ;TAKE VERTICAL POSITION ;LSR ;DIVIDE BY 2 ASR #$FE ; *** AND+LSR, so we can force carry clear TAY ;MAP FROM VERTICAL POSITION ON SCREEN TO VERTICAL SCANNER POS ; *** -0 cycles / -0 cycles total ; *** with a bit of expansion we can combine both of these table lookups... ;LDA VPOS_TO_SCANNERV_TABLE,Y ;VERTICAL POSITION IN SCANNER ;TAY ;LDA SCNADDRESSL,Y ;INDEX INTO SCANNER RAM, VERTICALLY ;STA TEMP0 ;LDA SCNADDRESSH,Y ;STA TEMP1 ; *** somthing like this... LDA VPOS_TO_SCANNER_ADDRESSL,Y STA TEMP0 LDA VPOS_TO_SCANNER_ADDRESSH,Y STA TEMP1 ; *** -6 cycles / -6 cycles total ; *** do this once, prior to the radar enemy loop... ; LDA WINDOWSTARTCOL ; SEC ; SBC #$36 ; $36 instead of $35, due to later carry=clear ; STA WINDOWSTARTCOL_ADJUSTED ; *** so we can streamline this... ;LDA OBJHCOL,X ;GET HORISONTAL PLANET COLUMN OF ENEMY ($00-$7F) ;CLC ;WE NEED TO GET A STATIC COLUMN IN THE SCANNER BETWEEN THE PLANET AND THE ENEMY/HUMANOID ;ADC #$35 ;I FEEL LIKE THIS SHOULD BE #$40, BUT $35 IS WHAT GIVES AN ACCURATE NUMBER ;SEC ;SBC WINDOWSTARTCOL ;SUBTRACT CURRENT WINDOW COLUMN TO GET COLUMN FOR SCANNER ; *** to this... LDA OBJHCOL,X ;GET HORISONTAL PLANET COLUMN OF ENEMY ($00-$7F) SBC WINDOWSTARTCOL_ADJUSTED ; *** -6 cycles / -12 cycles total ;LSR ;DIVIDE BY 2 TO GET THE NUMBER OF X POSITIONS IN THE SCANNER ;AND #$3F ;FOR WRAPAROUND ASR #$7F ; *** AND+LSR ; *** -2 cycles / -14 cycles total ;STA TEMP5 ;64 PIXELS IN SCANNER ($00-$3F) TAY ; *** save LSR ;WE NOW DIVIDE BY 4 TO GET THE BYTE INDEX INTO THE SCANNER RAM LSR ;THERE ARE 16 BYTES PER ROW OF SCANNER RAM STA TEMP4 ;HORIZONTAL POSITION BYTE IN SCANNER ;LDA TEMP5 TYA ; *** restore ; *** -2 cycles / -16 cycles total AND #$03 ;GET POSITION WITHIN BYTE IN SCANNER ; *** TEMP5 is about to be wiped after this, so just keep the value in A ; STA TEMP5 ;LDA OBJTYPE,X ;GET ENEMY TYPE ;ASL ;SHIFT OVER TO CREATE AN INDEX ;ASL ; WITHIN THE TABLE OF OBJECT TYPE / BYTE POSITION ;ORA TEMP5 ;'OR' WITH DOUBLE-BIT POSITION ORA OBJTYPEX4,X ; *** OBJTYPE*4 can be pre-calculated/statically-assigned TAY ;Y INDEX ; *** -10 cycles / -26 cycles total LDA NMYSCNLINE1,Y ;THIS GETS THE ENEMY TYPE AND POSITION WITHIN THE SCANNER BYTE STA TEMP5 LDY TEMP4 ;HORIZONTAL BYTE POSITION IN SCANNER RAM LDA (TEMP0),Y ;GET WHAT IS ALREADY THERE ORA TEMP5 ;'OR' VALUE WITH NEW OBJECT STA (TEMP0),Y ;STORE TOP LINE INC TEMP1 ;NEXT PAGE DOWN LDA (TEMP0),Y ;GET WHAT WAS ALREADY THERE ORA TEMP5 ;'OR' VALUES WITH NEW OBJECT STA (TEMP0),Y I think to do much better you'll need something more algorithmic, like caching 2 Quote Link to comment Share on other sites More sharing options...
+cjherr Posted January 10, 2022 Share Posted January 10, 2022 Of course we're disappointed, but we certainly don't want you chewing yourself up over something you feel can't be done. Do what makes you happy. 5 Quote Link to comment Share on other sites More sharing options...
Goochman Posted January 10, 2022 Share Posted January 10, 2022 Bob - better than delivering a Defender with the excuse that the laser shot is so powerful the ship disappears when shooting! Im looking at your 2600 port! 2 Quote Link to comment Share on other sites More sharing options...
ZylonBane Posted January 10, 2022 Share Posted January 10, 2022 Seems like splitting the scanner processing across multiple frames would be a viable option. As RevEng already pointed out, you're doing a lot of calculations for each enemy that could be pre-calculated. One of the reasons those old Eugene Jarvis games ran so fast on such primitive hardware is because he wasn't shy about just skipping or delaying any non-critical tasks that would have impacted the frame rate. Too many enemies on the screen? Move 'em! Too much AI processing? Do it later! So no shame in using the same tricks for a port. 6 Quote Link to comment Share on other sites More sharing options...
+Pat Brady Posted January 10, 2022 Share Posted January 10, 2022 39 minutes ago, ZylonBane said: Seems like splitting the scanner processing across multiple frames would be a viable option. As RevEng already pointed out, you're doing a lot of calculations for each enemy that could be pre-calculated. One of the reasons those old Eugene Jarvis games ran so fast on such primitive hardware is because he wasn't shy about just skipping or delaying any non-critical tasks that would have impacted the frame rate. Too many enemies on the screen? Move 'em! Too much AI processing? Do it later! So no shame in using the same tricks for a port. Excellent point, in case Bob's decision is not final. In this case, distributing that function across 2 frames (i.e. update half of the objects each frame) combined with @RevEng's optimizations should save about 3000 cycles per frame. For slow moving objects it would probably be fine to update even less often, maybe every 4 frames for slow-moving enemies and 5 frames for humanoids (since there are 10 of them). Alternatively, you could update humanoids only when they move, though that might not help the worst case. 2 Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted January 11, 2022 Share Posted January 11, 2022 I will still work on the Defender sounds, just in case Bob reconsiders. 7 Quote Link to comment Share on other sites More sharing options...
Zonie Posted January 11, 2022 Share Posted January 11, 2022 When I play Defender/Stargate, I rarely if ever look at the scanner. Too much going on in the playfield to take your eyes off of it... How about skipping the scanner? Just sayin. Quote Link to comment Share on other sites More sharing options...
Atariboy Posted January 11, 2022 Share Posted January 11, 2022 I think the desire for faithfulness probably would prevent that, but if Defender indeed is dead, I'd love to see PacManPlus repurpose his work someday on an original game in this style. One that doesn't have the resource intensive scanner. 2 Quote Link to comment Share on other sites More sharing options...
gambler172 Posted January 11, 2022 Share Posted January 11, 2022 No one should be forced, to work on a game, if it cannot be done like he wants. But a Defender version, less original, than the arcade would be ok too. Look at the XL version. If original arcade cannot be done....this is ok. But i know Bob is Perfectionist. 4 Quote Link to comment Share on other sites More sharing options...
ZylonBane Posted January 11, 2022 Share Posted January 11, 2022 13 hours ago, Zonie said: When I play Defender/Stargate, I rarely if ever look at the scanner. Too much going on in the playfield to take your eyes off of it... How about skipping the scanner? Oh sure, throw out one of the most distinctive aspects of the original game, which is present in literally every port. Nobody would mind that. Jesus, some people really don't think before they post. 3 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.