roland p Posted October 6, 2008 Share Posted October 6, 2008 All this and it's only 4k so far? Pretty cool! Can't wait to see what comes of this! Yep, 1004 bytes ROM and 17 bytes of RAM left so far. That's not much RAM left for the actual game... the need to optimise somewhere or can I smell a superchip around the corner (I wouldn't blame ya here!)? I'm thinking of lowering the resolution of the ship, that would add 20 bytes. The actual resolution can be seen in the window of the ship. I took such high resolution for fine positioning, but I think I can achieve the same with careful usage of the VDELP0 and VDELP1 registers (left and right part of the ship will be updated every other line then) Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 6, 2008 Share Posted October 6, 2008 (edited) I'm thinking of lowering the resolution of the ship, that would add 20 bytes. The actual resolution can be seen in the window of the ship. I took such high resolution for fine positioning, but I think I can achieve the same with careful usage of the VDELP0 and VDELP1 registers (left and right part of the ship will be updated every other line then) It would be good to keep the high-resolution ship. Is the ship data loaded from ROM or RAM? I wouldn't worry about using ROM space as you can always add more by bankswitching, but 20 bytes of RAM is quite a lot. If you post up the source code, I'm sure the code wizards around here will be able to help you improve things. Chris Edited October 6, 2008 by cd-w Quote Link to comment Share on other sites More sharing options...
roland p Posted October 6, 2008 Share Posted October 6, 2008 (edited) I'm thinking of lowering the resolution of the ship, that would add 20 bytes. The actual resolution can be seen in the window of the ship. I took such high resolution for fine positioning, but I think I can achieve the same with careful usage of the VDELP0 and VDELP1 registers (left and right part of the ship will be updated every other line then) It would be good to keep the high-resolution ship. Is the ship data loaded from ROM or RAM? I wouldn't worry about using ROM space as you can always add more by bankswitching, but 20 bytes of RAM is quite a lot. If you post up the source code, I'm sure the code wizards around here will be able to help you improve things. Chris In the sky part the ship is loaded from ROM, in the checkerboard part the ship is loaded from RAM because of speed. Here is the sky code where upper part of sprite is loaded and lower part is put into memory: LDY #0 BlueLines ;ODD LINE LDA SHIPR,Y STA GRP1;display right part of ship ;EVEN LINE STA WSYNC LDA SHIPL,Y;;display left part of ship STA GRP0 TYA CLC ADC #20 ; add twenty to current line TAX LDA SHIPL,X ;Get left part STA sprite_data_l,Y;Store left part in memory LDA SHIPR,X ;Get right part STA sprite_data_r,Y;Store right part in memory STA WSYNC INY CPY #20 BNE BlueLines Edited October 6, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 6, 2008 Share Posted October 6, 2008 In the sky part the ship is loaded from ROM, in the checkerboard part the ship is loaded from RAM because of speed. Here is the sky code where upper part of sprite is loaded and lower part is put into memory: <snip> I'm still not clear why you need to put the data in memory - can you post up the code where it is displayed on screen? I think you can do LDA SHIPL+20,Y (4 cycles) instead of adding 20 explicitly to the Y value unless I am missing something. Chris Quote Link to comment Share on other sites More sharing options...
roland p Posted October 6, 2008 Share Posted October 6, 2008 I'm still not clear why you need to put the data in memory - can you post up the code where it is displayed on screen? Well the code is a bit strange and long. Here is the code for checkerboard line 7: SBC PlayfieldX_frag;(3) BCS SkipLine7 ;(2/3) SkipLine7 ;7A LDX tile_pointer + 7 LDY PLAYFIELD_DATA,X STY COLUBK INX LDY sprite_data_l + 7 STY GRP0 SLEEP 4 LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK ;7B LDY sprite_data_r + 8 STY GRP1 SLEEP 8 LDX tile_pointer + 7 LDY PLAYFIELD_DATA,X STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X NOP NOP STY COLUBK INX LDY PLAYFIELD_DATA,X LDX sprite_data_l + 8 ;prefetch sprite data for next line STY.w COLUBK I think you can do LDA SHIPL+20,Y (4 cycles) instead of adding 20 explicitly to the Y value unless I am missing something. Well, the sprite has to be able to scale and move too, so I left it a bit dynamically. And SHIPL+20 is rendered to a constant value at compile time right? Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 6, 2008 Share Posted October 6, 2008 Well, the sprite has to be able to scale and move too, so I left it a bit dynamically. And SHIPL+20 is rendered to a constant value at compile time right? Yes, this value will be treated as a constant at compile time, so it won't be suitable for your sprite data. However it looks like you might be able to use this approach in your kernel, e.g. replace INX LDY PLAYFIELD_DATA,X with LDY PLAYFIELD_DATA+1,X? The best approach for displaying the sprite data would probably be just to store a pointer to the sprite data in RAM and then use indirect indexed addressing during the display, e.g. LDA (SpritePtr),Y [5 Cycles]. It looks like you have enough spare cycles to do this in the code that you have posted, but you will need to free up the Y register and things are probably tighter towards the top of the screen? Chris Quote Link to comment Share on other sites More sharing options...
roland p Posted October 6, 2008 Share Posted October 6, 2008 Yes, this value will be treated as a constant at compile time, so it won't be suitable for your sprite data. However it looks like you might be able to use this approach in your kernel, e.g. replace INX LDY PLAYFIELD_DATA,X with LDY PLAYFIELD_DATA+1,X? The best approach for displaying the sprite data would probably be just to store a pointer to the sprite data in RAM and then use indirect indexed addressing during the display, e.g. LDA (SpritePtr),Y [5 Cycles]. It looks like you have enough spare cycles to do this in the code that you have posted, but you will need to free up the Y register and things are probably tighter towards the top of the screen? Chris I could load the sprite directly from rom, but I really have to find cycles for it. And I'll have to store every (zoomed) sprite in rom then. Some logic that could scale the sprite would be very nice. Quote Link to comment Share on other sites More sharing options...
roland p Posted October 6, 2008 Share Posted October 6, 2008 (edited) Well, the sprite has to be able to scale and move too, so I left it a bit dynamically. And SHIPL+20 is rendered to a constant value at compile time right? Yes, this value will be treated as a constant at compile time, so it won't be suitable for your sprite data. However it looks like you might be able to use this approach in your kernel, e.g. replace INX LDY PLAYFIELD_DATA,X with LDY PLAYFIELD_DATA+1,X? Wow... I missed that one Thanks! Edited October 6, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 6, 2008 Share Posted October 6, 2008 I could load the sprite directly from rom, but I really have to find cycles for it. And I'll have to store every (zoomed) sprite in rom then. Some logic that could scale the sprite would be very nice. I could be wrong, but I doubt you will find any quick logic to scale the sprite - much better just to store several different sizes in ROM if possible. In Juno First it looks like the sprites scale up as they approach the front of the screen, but in fact there are only 3 sizes used (small, medium, and large). Chris Quote Link to comment Share on other sites More sharing options...
roland p Posted October 6, 2008 Share Posted October 6, 2008 I could load the sprite directly from rom, but I really have to find cycles for it. And I'll have to store every (zoomed) sprite in rom then. Some logic that could scale the sprite would be very nice. I could be wrong, but I doubt you will find any quick logic to scale the sprite - much better just to store several different sizes in ROM if possible. In Juno First it looks like the sprites scale up as they approach the front of the screen, but in fact there are only 3 sizes used (small, medium, and large). Chris The original version of Ballblazer just cuts the ship into 4 parts which slides intelligently so it looks like it's scaling. I would like to do the same, but just store the sprites is much easier. Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted October 7, 2008 Share Posted October 7, 2008 I'm working on the drones right now. I managed to get them 16 pixels wide! So I can reasamble the original drones pretty close. Very nice. Split screen is lovely too. Keep up the good work I miss the graduated sky at the horizon, though... Cheers A Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 7, 2008 Share Posted October 7, 2008 I'm working on the drones right now. I managed to get them 16 pixels wide! So I can reasamble the original drones pretty close. So you concentrate on color writes only for creating the checkerboard, right? After trying to mix color writes and HMOVES, I fully understand your decision. And it looks good enough your way already. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 7, 2008 Share Posted October 7, 2008 Well, the sprite has to be able to scale and move too, so I left it a bit dynamically. RAM is much shorter than ROM, so maybe you better use a lot of fixed scales from ROM. Especially for vertical scaling. For horizontal scaling, a lot can be done by partially overlapping the two sprites. BTW: When you see the sprite from the side, you will need even more RAM because it isn't symmetric anymore. Quote Link to comment Share on other sites More sharing options...
roland p Posted October 7, 2008 Share Posted October 7, 2008 (edited) Well, the sprite has to be able to scale and move too, so I left it a bit dynamically. RAM is much shorter than ROM, so maybe you better use a lot of fixed scales from ROM. Especially for vertical scaling. For horizontal scaling, a lot can be done by partially overlapping the two sprites. BTW: When you see the sprite from the side, you will need even more RAM because it isn't symmetric anymore. I now use 20 bytes for left and 20 bytes for right. I might reduce that to 10 bytes left and 10 bytes right without sacrificeing too much quality. Currently, thanks to cd-w's optimizations, I have 32 bytes of RAM left. I now use the following code to read a sprite from ram: LDY sprite_data_r + 18 STY GRP1 That's 6 cycles If I want to change this to rom it would look like this? : LDY #18;Row number LDA (sprite_ptr_r),Y STA GRP0 That is 2 + 5 + 3 = 10 cycles. Finding 4 cycles can be very hard if you havn't any. I discovered that the goal can be on the left/right side too, meaning that missles must also be integrated into the checkerboard kernel. Edited October 7, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 7, 2008 Share Posted October 7, 2008 If I want to change this to rom it would look like this? : LDY #18;Row number LDA (sprite_ptr_r),Y STA GRP0 That is 2 + 5 + 3 = 10 cycles. Finding 4 cycles can be very hard if you havn't any. You shouldn't need to set Y on every access, so that should be 8 cycles instead of 6? Can you post the tightest part of your kernel so that we can see if any more optimisation is possible? I discovered that the goal can be on the left/right side too, meaning that missiles must also be integrated into the checkerboard kernel. I suppose you could omit this feature from the 2600 version since it isn't essential for the game? Chris Quote Link to comment Share on other sites More sharing options...
roland p Posted October 7, 2008 Share Posted October 7, 2008 I think I leave it this way. It ain't broken yet. The Accumulator is now dedicated for calculation of the horizontal movement only, because putting that in the kernel saved another 400/500 cycles outside the kernel. Quote Link to comment Share on other sites More sharing options...
cd-w Posted October 7, 2008 Share Posted October 7, 2008 I think I leave it this way. It ain't broken yet.The Accumulator is now dedicated for calculation of the horizontal movement only, because putting that in the kernel saved another 400/500 cycles outside the kernel. Yup, you are doing a great job so far - I'm looking forward to seeing how this develops. Chris Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 7, 2008 Share Posted October 7, 2008 I discovered that the goal can be on the left/right side too, meaning that missles must also be integrated into the checkerboard kernel. When can that happen? When the other player is having the ball? Anyway, I agree with cd-w, most likely one wouldn't even notice this missing. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 7, 2008 Share Posted October 7, 2008 I think I leave it this way. It ain't broken yet. The Accumulator is now dedicated for calculation of the horizontal movement only, because putting that in the kernel saved another 400/500 cycles outside the kernel. Are you doing a Bresenham inside the kernel? I really would like to see your complete source code, because I am pretty sure, together we can easier find a way to solve a problem. Quote Link to comment Share on other sites More sharing options...
roland p Posted October 7, 2008 Share Posted October 7, 2008 (edited) When can that happen? When the other player is having the ball? Anyway, I agree with cd-w, most likely one wouldn't even notice this missing. I actually played the game Example: When 2 ships are at the left side near a goal and the ball is at the right side near a goal the players will point to the ball and you will see the goal on your left. But I will make turns of 180 degrees instead of 90, the engine is already build like that. It will make things a bit easier. Maybe some indicators that help to indicate where the ball is located when it's off screen. Edited October 7, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 7, 2008 Share Posted October 7, 2008 I actually played the game So did I! Example: When 2 ships are at the left side near a goal and the ball is at the right side near a goal the players will point to the ball and you will see the goal on your left. But I will make turns of 180 degrees instead of 90, the engine is already build like that. It will make things a bit easier. Maybe some indicators that help to indicate where the ball is located when it's off screen. Interesting idea. I wonder how it will work out. With the ball, the player's ship always points to the opposite goal. So that's 180° anyway. But without the ball, the player's ship always points to the ball. How are you going to handle this? Won't 180° steps make fighting for the ball much different than now? Quote Link to comment Share on other sites More sharing options...
roland p Posted October 7, 2008 Share Posted October 7, 2008 (edited) I think I leave it this way. It ain't broken yet. The Accumulator is now dedicated for calculation of the horizontal movement only, because putting that in the kernel saved another 400/500 cycles outside the kernel. Are you doing a Bresenham inside the kernel? I really would like to see your complete source code, because I am pretty sure, together we can easier find a way to solve a problem. I Just saw this post. Here you have the source in it's current state. I think I do a sort of Bresenham. I start with LDA #255 And then for each line: SBC PlayfieldX_frag BCS *+2 When PlayfieldX_frag is 0, carry will never be set and BCS *+2 results in 2 cycles. When PlayfieldX_frag is 255 (max) carry will be set every line and BCS *+2 will result in 3 cycles on every line. This causes every line to scroll 1 pixel in relation to the previous. Any value in between will result in a smooth vector as seen in the game. I found this the coolest find during my ballblazer programming. ballblazer.zip Edited October 7, 2008 by roland p Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 8, 2008 Share Posted October 8, 2008 I think I do a sort of Bresenham. I start with LDA #255And then for each line: SBC PlayfieldX_frag BCS *+2 Yup, that's (some "sort of" ) Bresenham. And 5/6 cycles is really as fast as you can get. But you should initialize the A with $80 to be more correct. With different initialization values, you might get some kind of subpixel scrolling. But you also could do those calculations out side the kernel and free A inside, e.g for indirect, indexed sprite graphics. Put the carries into 3 (20/8) variables and ASL them. This will cost you up to (for the first and last bit of each variable you can use BIT instead of ASL) 7/8 cycles instead of 5/6. But if you can afford that, freeing A might give you some necessary flexibility. Quote Link to comment Share on other sites More sharing options...
roland p Posted October 8, 2008 Share Posted October 8, 2008 I think I do a sort of Bresenham. I start with LDA #255And then for each line: SBC PlayfieldX_frag BCS *+2 Yup, that's (some "sort of" ) Bresenham. And 5/6 cycles is really as fast as you can get. But you should initialize the A with $80 to be more correct. With different initialization values, you might get some kind of subpixel scrolling. But you also could do those calculations out side the kernel and free A inside, e.g for indirect, indexed sprite graphics. Put the carries into 3 (20/8) variables and ASL them. This will cost you up to (for the first and last bit of each variable you can use BIT instead of ASL) 7/8 cycles instead of 5/6. But if you can afford that, freeing A might give you some necessary flexibility. I'll stick with my current solution for now. I'll try to scale the sprite programmatically. If that doesn't work, I can load the sprite from rom anyway. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted October 8, 2008 Share Posted October 8, 2008 I'll stick with my current solution for now. I'll try to scale the sprite programmatically. Since everything else is scaled programmatically too, this seems logical. But I am afraid you will run out of RAM space that way. So, good luck! 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.