+acadiel Posted August 8, 2017 Share Posted August 8, 2017 I brought it up in JS99er to take a quick look. Amazing job! (Yeah, I know I've been quite lately... been dealing with health problems. I'm still here though.) 4 Quote Link to comment Share on other sites More sharing options...
digdugnate Posted August 8, 2017 Share Posted August 8, 2017 I brought it up in JS99er to take a quick look. Amazing job! (Yeah, I know I've been quite lately... been dealing with health problems. I'm still here though.) i didn't think to use JS99er. The game is slick! Quote Link to comment Share on other sites More sharing options...
Asmusr Posted August 8, 2017 Share Posted August 8, 2017 Very nice. Keep up the good work. 1 Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 8, 2017 Share Posted August 8, 2017 Yes very nice! The movement of the monsters is perfect, although I did notice they aren't shooting projectiles. I imagine the sprite use and 4 per line limit is starting to get annoying. One aspect of utilizing the 32k would be you could do some good optimizations, such as a rotating sprite table in CPU memory. Quote Link to comment Share on other sites More sharing options...
PeteE Posted August 8, 2017 Author Share Posted August 8, 2017 Yes very nice! The movement of the monsters is perfect, although I did notice they aren't shooting projectiles. I imagine the sprite use and 4 per line limit is starting to get annoying. One aspect of utilizing the 32k would be you could do some good optimizations, such as a rotating sprite table in CPU memory. The projectiles are on my todo list, but they didn't make the cut for this release. Some projectiles will also bounce off the player if they face the shield toward it, and I'll work on that too when I add projectiles. The 4 sprites per line limit doesn't seem too terrible. What I'm doing now is the 2 hero sprites and 4 status bar sprites are always highest priority, since I never want them to flicker. The rest are written in forward order, or in reverse order, alternating every frame, so that sprites on the same line will appear to flicker. In reverse order, I write the VDP address once, then copy 6*4 bytes from sprites 0-5, then copy 4 bytes from 31st sprite to the VDP then the 30th sprite, 29th, etc. This is the SPRUPD (sprite update) function in tilda_b0.asm. There is a chance that sprites in the middle of the list will not be displayed if too many sprites are on the same line, but this happens very rarely (and most people probably have the 4-sprites-per-line limitation turned off in an emulator or the F18A.) I am keeping a copy of the sprite list table in the fast CPU RAM even though it takes 128 bytes out of the total 256. Manipulating the sprite list is the bulk of the work for each frame, so it seemed like a good idea to use the fast RAM instead of the slower expansion RAM. Hmm, when I brought it up in Classic99, it loads the first screen but if I move any direction but down it scrolls up the menu screen and then locks up. Anyone else experiencing that? UPDATE: Nevermind, figured it out. The joystick #2 was also configured to PC keyboard, which meant it was sending double inputs and causing some hijinks. Ah, I never considered that configuration. All of the joystick 2 inputs are mapped to the 3 action buttons: sword, item, and menu screen. This is so it will work with various 6-button controller configurations. This also reminded me of the alpha-lock problem, and other games I've seen ask the user to press the joystick up just to make sure alpha-lock is off, that would also help to ensure joystick 1 is being used. Thanks! No need to be sorry, as far as I am concerned; I keep coding in this way because I'm using the classic assembler in E/A and TASM on the Geneve. I'm not sorry. It feels retro to use all caps, and was intended to set up the joke about caps being used for shouting and the computer being old and hard of hearing: "Eh, speak up, sonny" Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 8, 2017 Share Posted August 8, 2017 The projectiles are on my todo list, but they didn't make the cut for this release. Some projectiles will also bounce off the player if they face the shield toward it, and I'll work on that too when I add projectiles. The 4 sprites per line limit doesn't seem too terrible. What I'm doing now is the 2 hero sprites and 4 status bar sprites are always highest priority, since I never want them to flicker. The rest are written in forward order, or in reverse order, alternating every frame, so that sprites on the same line will appear to flicker. In reverse order, I write the VDP address once, then copy 6*4 bytes from sprites 0-5, then copy 4 bytes from 31st sprite to the VDP then the 30th sprite, 29th, etc. This is the SPRUPD (sprite update) function in tilda_b0.asm. There is a chance that sprites in the middle of the list will not be displayed if too many sprites are on the same line, but this happens very rarely (and most people probably have the 4-sprites-per-line limitation turned off in an emulator or the F18A.) I am keeping a copy of the sprite list table in the fast CPU RAM even though it takes 128 bytes out of the total 256. Manipulating the sprite list is the bulk of the work for each frame, so it seemed like a good idea to use the fast RAM instead of the slower expansion RAM. Ah, I never considered that configuration. All of the joystick 2 inputs are mapped to the 3 action buttons: sword, item, and menu screen. This is so it will work with various 6-button controller configurations. This also reminded me of the alpha-lock problem, and other games I've seen ask the user to press the joystick up just to make sure alpha-lock is off, that would also help to ensure joystick 1 is being used. Thanks! I'm not sorry. It feels retro to use all caps, and was intended to set up the joke about caps being used for shouting and the computer being old and hard of hearing: "Eh, speak up, sonny" Ah yes, it makes sense to keep a copy of the table in the scratch-pad! The main thing with the 32k expansion is you could explore a "memory for time" approach. Generally speaking, any algorithm can be written to be faster by just being more memory wasteful. I'd need to look at your code first to see what could be done, but I've explored it with my work on the Gauntlet clone. I understand you have a goal here though, to not require the 32k expansion, so I'll be quiet about it. Just don't let it stop you from finishing the game! Quote Link to comment Share on other sites More sharing options...
Tursi Posted August 8, 2017 Share Posted August 8, 2017 Seriously impressive work here I also never noticed before today that the Triforce on the title page was actually Texas. 1 Quote Link to comment Share on other sites More sharing options...
+Schmitzi Posted August 8, 2017 Share Posted August 8, 2017 Oh, there is a sword ??? Can I use that on keyboard ? 1 Quote Link to comment Share on other sites More sharing options...
PeteE Posted August 8, 2017 Author Share Posted August 8, 2017 Seriously impressive work here I also never noticed before today that the Triforce on the title page was actually Texas. Thanks! I've been calling it the "TIFORCE", so what other shape would it have? Oh, there is a sword ??? Can I use that on keyboard ? The Enter key is sword. (On classic99 you can also use Tab since I think that is the emulated joystick fire button) 2 Quote Link to comment Share on other sites More sharing options...
+Schmitzi Posted August 8, 2017 Share Posted August 8, 2017 Thanks. I love that I can run with ASDW keys <3 Quote Link to comment Share on other sites More sharing options...
notwhoyouthink Posted August 29, 2017 Share Posted August 29, 2017 (edited) WOW. I am loving the look and feel of this. Will a finished cart of this require a F18A? Edited August 29, 2017 by notwhoyouthink 2 Quote Link to comment Share on other sites More sharing options...
PeteE Posted August 29, 2017 Author Share Posted August 29, 2017 (edited) WOW. I am loving the look and feel of this. Will a finished cart of this require a F18A? No, this version will not require F18A. I may decide to do a special F18A version to add 4 color graphics later, but no guarantee. Edit: Might as well post a status update since I'm here. Lately I've been working on the menu screen and item selection, and have animations done for the candle, bombs, boomerang, and magic rod. Started populating the overworld cave screens. I'm researching LZ77 compression for pattern tables since I'm getting close to running out of cartridge space in 32K, and haven't even started dungeons yet. I could go 64K but then I think it won't work on the FlashROM. I can't believe I thought this project would be easy in the beginning, but it's been great fun learning all the little things that go into making a game. Maybe it's a good thing I picked a classic game that makes it feel worthwhile to port so I don't get frustrated and give up thinking "why am I porting a 20 year-old game to a 26 year-old computer with worse graphics" Edited August 29, 2017 by PeteE 4 Quote Link to comment Share on other sites More sharing options...
+Schmitzi Posted August 29, 2017 Share Posted August 29, 2017 F18A support would be nice Quote Link to comment Share on other sites More sharing options...
notwhoyouthink Posted August 29, 2017 Share Posted August 29, 2017 While i'm thinking about retro-zelda related things, wasn't there a attempt to port zelda to the atari home computer? "Fanwor" i think it was called? Quote Link to comment Share on other sites More sharing options...
PeteE Posted August 30, 2017 Author Share Posted August 30, 2017 I found a compression algorithm in the ColecoVision programming forum: DAN2 which has nice properties of good compression ratio and low complexity. I converted the C decoder to TMS9900 asm, and it worked on the very first try - that never happens! This version only decodes from RAM/ROM to VDP memory, which is exactly what I need for pattern tables. The code assembles to about 220 bytes, not including VDPWB and VDPRB. ; Dan2 decompression ; R5 = Source data address ; R7 = VDP output address ; Register usage ; R3 = length (elias_gamma) ; R8 = status bits ; R9 = offset ; R10 = saved return address ; R12 = max offset bits DAN2DC MOV R11,R10 ; Save return address CLR R8 LI R12,9 ; R12 = 10 (max offset bits initial value) ! INC R12 BL @D2RBIT ; R12 = (count of 1 bits) + 10 DATA -! D2LIT ; literal MOVB *R5+,R1 MOV R7,R0 BL @VDPWB INC R7 D2LZLP ; LZ loop BL @D2RBIT DATA D2LIT ; length = read_elias_gamma() CLR R4 ; len (number of bits in elias_gamma) LI R3,1 ; elias_gamma ! INC R4 ; while carry_flag == 0 CI R4,17 JEQ D2_L17 BL @D2RBIT DATA ! ; if carry, increment counter JMP -! D2_L17 ; elias_gamma = 0; so length = 0, done! B *R10 ; Return to saved address D2_IEG ; increment elias_gamma INC R3 ; elias_gamma += 1 ! DEC R4 JEQ ! SLA R3,1 BL @D2RBIT DATA D2_IEG ; if carry, increment elias_gamma JMP -! ! ; R3 = elias_gamma = length (known to be nonzero) ; offset = read_offset(length) CLR R9 ; offset = 0 ; read_offset(option=R3) returns offset in R1 CI R3,2 JLE ! ; if (option > 2) BL @D2RBIT DATA D2OFF3 ! CI R3,1 JLE ! ; if (option > 1) BL @D2RBIT DATA D2OFF2 ! BL @D2RBIT DATA D2OFF1 INC R9 BL @D2RBIT DATA D2_OFF CLR R9 D2_OFF ; offset = R9 NEG R9 DEC R9 A R7,R9 ; R9 index = = out_addr - offset - 1 ! MOV R9,R0 ; Read byte from R9 (index) BL @VDPRB INC R9 MOV R7,R0 ; Write byte to R7 (out_addr) BL @VDPWB INC R7 DEC R3 JNE -! JMP D2LZLP MAXOF1 EQU 2 ; 1<<1 MAXOF2 EQU MAXOF1+16 ; 1<<4 MAXOF3 EQU MAXOF2+256 ; 1<<8 D2OFF3 ; read_bits(max_bits - MOV R12,R4 AI R4,-8 ; R4=MAX_OFFSET_BITS-8 BL @D2RBTS SLA R9,8 AI R9,MAXOF3-MAXOF2 ;fall thru D2OFF2 MOVB *R5+,@R9LB AI R9,MAXOF2 JMP D2_OFF D2OFF1 LI R4,4 BL @D2RBTS AI R9,MAXOF1 JMP D2_OFF ; read_bits(count=R4) return in R9 D2RBTS MOV R11,R0 ; Save return address ! SLA R9,1 BL @D2RBIT DATA D2RBT2 JMP D2RBT3 D2RBT2 INC R9 D2RBT3 DEC R4 JNE -! B *R0 ; Return to saved address ; read_bit, jump to *R11+ if set, return otherwise ; Modifies R2 D2RBIT MOV *R11+,R2 D2RBI2 SLA R8,1 JEQ D2RFIL JNC ! B *R2 ! RT ; read_bit refill bits D2RFIL LI R8,>0080 MOVB *R5+,R8 JMP D2RBI2 9 Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 31, 2017 Share Posted August 31, 2017 I found a compression algorithm in the ColecoVision programming forum: DAN2 which has nice properties of good compression ratio and low complexity. I converted the C decoder to TMS9900 asm, and it worked on the very first try - that never happens! This version only decodes from RAM/ROM to VDP memory, which is exactly what I need for pattern tables. The code assembles to about 220 bytes, not including VDPWB and VDPRB. ; Dan2 decompression ; R5 = Source data address ; R7 = VDP output address ; Register usage ; R3 = length (elias_gamma) ; R8 = status bits ; R9 = offset ; R10 = saved return address ; R12 = max offset bits DAN2DC MOV R11,R10 ; Save return address CLR R8 LI R12,9 ; R12 = 10 (max offset bits initial value) ! INC R12 BL @D2RBIT ; R12 = (count of 1 bits) + 10 DATA -! D2LIT ; literal MOVB *R5+,R1 MOV R7,R0 BL @VDPWB INC R7 D2LZLP ; LZ loop BL @D2RBIT DATA D2LIT ; length = read_elias_gamma() CLR R4 ; len (number of bits in elias_gamma) LI R3,1 ; elias_gamma ! INC R4 ; while carry_flag == 0 CI R4,17 JEQ D2_L17 BL @D2RBIT DATA ! ; if carry, increment counter JMP -! D2_L17 ; elias_gamma = 0; so length = 0, done! B *R10 ; Return to saved address D2_IEG ; increment elias_gamma INC R3 ; elias_gamma += 1 ! DEC R4 JEQ ! SLA R3,1 BL @D2RBIT DATA D2_IEG ; if carry, increment elias_gamma JMP -! ! ; R3 = elias_gamma = length (known to be nonzero) ; offset = read_offset(length) CLR R9 ; offset = 0 ; read_offset(option=R3) returns offset in R1 CI R3,2 JLE ! ; if (option > 2) BL @D2RBIT DATA D2OFF3 ! CI R3,1 JLE ! ; if (option > 1) BL @D2RBIT DATA D2OFF2 ! BL @D2RBIT DATA D2OFF1 INC R9 BL @D2RBIT DATA D2_OFF CLR R9 D2_OFF ; offset = R9 NEG R9 DEC R9 A R7,R9 ; R9 index = = out_addr - offset - 1 ! MOV R9,R0 ; Read byte from R9 (index) BL @VDPRB INC R9 MOV R7,R0 ; Write byte to R7 (out_addr) BL @VDPWB INC R7 DEC R3 JNE -! JMP D2LZLP MAXOF1 EQU 2 ; 1<<1 MAXOF2 EQU MAXOF1+16 ; 1<<4 MAXOF3 EQU MAXOF2+256 ; 1<<8 D2OFF3 ; read_bits(max_bits - MOV R12,R4 AI R4,-8 ; R4=MAX_OFFSET_BITS-8 BL @D2RBTS SLA R9,8 AI R9,MAXOF3-MAXOF2 ;fall thru D2OFF2 MOVB *R5+,@R9LB AI R9,MAXOF2 JMP D2_OFF D2OFF1 LI R4,4 BL @D2RBTS AI R9,MAXOF1 JMP D2_OFF ; read_bits(count=R4) return in R9 D2RBTS MOV R11,R0 ; Save return address ! SLA R9,1 BL @D2RBIT DATA D2RBT2 JMP D2RBT3 D2RBT2 INC R9 D2RBT3 DEC R4 JNE -! B *R0 ; Return to saved address ; read_bit, jump to *R11+ if set, return otherwise ; Modifies R2 D2RBIT MOV *R11+,R2 D2RBI2 SLA R8,1 JEQ D2RFIL JNC ! B *R2 ! RT ; read_bit refill bits D2RFIL LI R8,>0080 MOVB *R5+,R8 JMP D2RBI2 Nice! I'll have to try this with my text and see how it works... Quote Link to comment Share on other sites More sharing options...
PeteE Posted August 31, 2017 Author Share Posted August 31, 2017 Nice! I'll have to try this with my text and see how it works... Let me know if you need RAM to RAM decompression, and I'll make the changes for you. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted August 31, 2017 Share Posted August 31, 2017 I found a compression algorithm in the ColecoVision programming forum: DAN2 which has nice properties of good compression ratio and low complexity. I converted the C decoder to TMS9900 asm, and it worked on the very first try - that never happens! This version only decodes from RAM/ROM to VDP memory, which is exactly what I need for pattern tables. The code assembles to about 220 bytes, not including VDPWB and VDPRB. Thank you, that will be handy for my projects. I have not used anything more advanced than RLE before. I also once wrote some assembly code that worked the first time. It has never happened since. Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 31, 2017 Share Posted August 31, 2017 Unfortunately for my needs, it won't quite work... I tested a single line of text with the command-line encoder and it only shrunk it like 9%. In my case, I have a lot of separate data records of different fixed sizes, each of which is compressed individually. Most compression techniques rely upon finding matches and similarities over a much larger sample size. For example, if you embedded ALL text dialogue for a given map or location into a large block, you would probably be able to compress it much better. However, this would be a major architecture change to my engine at this point, plus I'm not a fan of it because it means variable sized files, and a great amount of difficulty adding and removing dialogue later. I may play around with some variants with my text encoding after I get the bulk of my data complete, see if I can find something that works a little better. Dropping the use of the 8th bit for "precede with space" and instead using the upper 128 for another set of dictionary replacements is worth trying... I just need to find a way to identify the most common character combinations in my text, an N^2 job to say the least... 1 Quote Link to comment Share on other sites More sharing options...
PeteE Posted October 18, 2017 Author Share Posted October 18, 2017 Finally got the NPCs, cave text and items appearing now. As you can see in the screenshots, the NPCs use two sprites and background characters for full detail, and the fire is one sprite and background characters. Each item is also a sprite (which means if you walk on the same row they will flicker due to the 4 sprites per line limitation on the 9918.) The text appears one character at a time, like the original. 10 Quote Link to comment Share on other sites More sharing options...
digdugnate Posted October 18, 2017 Share Posted October 18, 2017 that is just amazing the work you have done. definitely keep it up! Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted October 18, 2017 Share Posted October 18, 2017 Looking awesome! Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 18, 2017 Share Posted October 18, 2017 Really impressive work! Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted October 18, 2017 Share Posted October 18, 2017 Me like! Quote Link to comment Share on other sites More sharing options...
ramidavis Posted October 18, 2017 Share Posted October 18, 2017 Finally got the NPCs, cave text and items appearing now. As you can see in the screenshots, the NPCs use two sprites and background characters for full detail, and the fire is one sprite and background characters. Each item is also a sprite (which means if you walk on the same row they will flicker due to the 4 sprites per line limitation on the 9918.) The text appears one character at a time, like the original. A W E S O M E ! Love the old-school zelda's, not so much the new ones. Zelda 1, and Star tropics 1 & 2 are probably my top favorite NES titles ever. Speaking of star tropics, does anyone know of a re-implementation / clone of star tropics for pc? (If you know what the program "zelda classic" is, think that only for playing custom star tropics levels) 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.