-
Posts
608 -
Joined
-
Last visited
Everything posted by Norman Sword
-
Re Game Over. In JSW their are a multitude of sound effects. The title tune and in game tune plays their notes in a differing method to all the other sound FX's. Both the title tune and in game tune attempt to play the note over a fixed period of time. Your simple demo routine plays the tune, were each notes length is dictated by its pitch. The overall length of each note is the product of a fixed length and a pitch variable. This has several repercussions. The obvious visual one is the speed change in the boot as it descends. The obvious audio effect would be shifting tempo. Your routine might benefit from using a routine more similar to the in game tune routine. Whereby the length of each note is fixed (sort of). ;in game tune ;Pitch of note held in D which should be copied to E before playing ;a=border colour 8B60 LD BC,$0003 ;length of the note overall 8B63 OUT ($FE),A 8B65 DEC E 8B66 JR NZ,$8B6B 8B68 LD E,D 8B69 XOR $18 8B6B DJNZ $8B63 8B6D DEC C 8B6E JR NZ,$8B63 Since this plays slower, this would also require new music data
-
In addition I have rewritten the cheat. Activated as normal, same place same password. It is activated by pressing "9" On the room name banner line, you will see the room number in decimal. Movement around the rooms is the same as another file I uploaded e.g. 1=left 2=right 3=up 4=down to re-enter a room press any movement key for left or right - Can be used as a major cheat, because as a sprite approaches you can press "9" and Willy will vanish. Wait for the sprite to move out of you way. Then press a key to carry on walking. Easier to probably press "F" "G" and remove the sprite. But the cheat mode is far older. I only started to write the "F" "G" feature yesterday afternoon.
-
Admit it. Your first thought on finding out what this effect did was to use it on MARIA.
-
Data for the arrows. In the normal set up of an arrow. It uses half of its allocated eight byte slot (after deleting the unnecessary data used at offset 5) e.g 0= direction and type (arrow) 1= 2=y position 3= 4=x position 5= 6=graphic 7= It is relatively easy to make the arrow, use the alternate spaces as the data for a second arrow. I did not go further with this idea, simply because in the games present format. It is difficult to actually define the second arrow to do much. I simply positioned the sprite to have the same Y-position as the first, and left it at that. This means every arrow in the game is paired with another arrow. If a method of changing the y-position of the second arrow (in the same guardian slot) was incorporated, and also a method of changing the default arrow timing. (A Major Change) Then this would allow 16 arrows in a room. The BLOB bouncing across the Bathroom was another Guardian type. That I rapidly lost interest in. It had many versions, some of which became floors that moved etc. Since none of the effects took my interest, the BLOB is all that remains.
-
This file serves no purpose, apart from toying with an idea, and showing the results of that toying. For years the baddies have dominated this game, and they think they have Willy on the ropes and scared. Take back control. In addition to the normal movement keys I have added (actually reassigned) two more keys. Press "F" for the first effect ---- part restricted in usage. whilst holding down "F" press "G" for the second effect. The room will reset after each visit. (so no sprites were harmed in allowing this effect to happen) When I wrote this I was aware of the BUG caused by stairs which affected the bullet sprite alignment. I was not going to fix it, but since then I have become aware of another problem concerning the time over data. (which was over written). So reluctantly I have rewritten some of the code. Willy 007.tap original File Willy 007a.tap stair fix - sound fx fix - time over fix willy 007.tap WILLY 007a.tap
-
Curious to see how much of a problem the Cell Graphic Feature is. So I have modified a game with most of the original data in it, just to display the room and show any graphic problems. The room data above $c000 is pretty much as used in the original. (might be a hand edit or two but nothing extensive) This version has had the game rem'd out. It will start in the bathroom minus willy. The initial room will not show the graphic data (too lazy to change this) But from the initial room onwards you can wander around the game using the keys 1=left 2=right 3=up 4=down Along the line below the room name will be displayed data in this format two digit room number in decimal Followed by 3 background tiles/ /3 floor tiles/ /3 wall tiles/ /3 baddy tiles/ /3 ramp tiles/ /3 conveyor tiles Each group of three tiles are generated by the various methods. The first tile is matched using CPIR The second tile is matched using CP (HL) and stepping The third tile is the actual definition. What is noticeable is there are very few incorrect matches. EDIT--- The program now outputs a second line of data (the same data minus the colours) tile_bug.tap
-
Re Cell Graphic feature: None of the "solutions" posted in this topic address the problem. What every "solution" does is eliminate one problem and ignores the fact that this method simply does not work. As an example a familiar scene from JSW edited very slightly to include a ramp, a stair and a conveyor. JSWED has drawn what should be drawn by the game in the room. If the fix does not draw the graphics as shown, then the fix has not cured the problem. In the case of the three graphics Stair-Ramp-Conveyor all being in the same room. Matthews code can not handle this scene properly. (The conveyor will cause the most problems in horizontal animation/movement) Remove the conveyor and change its colour, then this room would play with these graphics exactly as expected. I have posted a method elsewhere that draws exactly what was defined. (picture edited to remove jswed cursor)
-
Wrote this months ago, seems to be of the same theme. I had no problems fitting code into the available space. :your code can be rewritten to fit into the available space. My old solution. ; We are dealing with a vertical guardian. L917F push ix pop hl ld a,(hl) xor 8 ld (hl),a and $18 jr z,vert_phase ld a,(hl) add a,$20 ld (hl),a vert_phase: inc hl inc hl inc hl ld a,(hl) ; y inc hl add a,(hl) ;delta y ld d,(ix+7) ;max y cp d ;reached or exceeded max jr NC,reverse_delta ;reverse and save y as max y ld D,(IX+$06) ;min Y cp D ;reached or exceeded min jr Z,reverse_delta ;save MIN as position jr C,reverse_delta ;save MIN as position ld D,A ;save as calculated jr save_y reverse_delta: ld a,(hl) ;reverse delta y neg ld (hl),a save_y: dec hl ld (hl),d ;new ypos jr next_entity ;$93b3 ; around nine bytes of unused space here code from $93b3 ; this label/position is referenced from all other guardian movements, next_entity: LD DE,$0008 ADD IX,DE ;Point IX at the first byte of the next entity's buffer JP L90C4 ;Jump back to deal with any more guardians
-
replicate the sprite routine? The further I change routines and add my own routines the more likely I will have need for a routine that does the simple task of moving HL to the next raster line. (it is a big chunk of the sprite routine) so I write a routine called NEXT_RASTER that does exactly what it says on the label I use it to draw the logo, I use it to draw the sprites, in fact if I know a routine will draw more the eight raster lines, then I will call next_raster Calling a routine instead of having the code in-line is inherently slower. But look at the usage of IX in the willy sprite routine and compare the time with a call to just move to the next raster and return. (it is comparable) Plus all the in-line routines are removed to a simple call. It was also a deliberate ploy when developing new routines and generally just pushing my luck (experimenting) that I need to be certain that sprite/arrows anything that moved on the screen was constrained to the bounds of the screen. So I force NEXT_RASTER to comply with only returning VALID screen addresses. So if a sprite wanders off the bottom of the screen it will wrap around and emerge on the top , thereby not crashing the machine......Which is what the Y-table is meant to be used for. But in this game it is rarely used for that purpose. It is also easy to add lots of checks for screen bounds, in the experimental stages, which can be removed once the routine has been debugged. Since all the routines use the constraints it makes finding faults so much easier. (The game still runs with junk on the screen) ;--------------------------------------------------------------- In Jsw I think there are 3 separate sprite routines. 1) merge and test collision $9456 c=mode 2) write $9456 c=mode 3) merge with no collision check $9668 since you now use a flag to detect collision, and the routine does not abort. You can delete the third sprite routine. which is the one that draws willy onto the screen around $9670: (also draws the toilet) e.g. at $9670 change to ld c,Flag jp sprite_draw ;$9456 you can delete all code up to $9680 :this is space verses speed. I have split the two functions defined by The "C" register, so I actually use TWO independent routines, which individually are faster than the combined.... ;------------------------------------------- I do all the sprite drawing in a different way. e.g. The LD c,flag has been ditched. Re-stack. Using the bottom of the stack would be a handy form of debug. It would alert you to stack overflow and also screen overwrites.
-
I ditched the title screen very early in this current disassembly. Which is why I mentioned the title screen data. I do not have such an area of data, If I was aware of any 32 byte area of data that was below $c000 then I can bet I would delete it and implement code to replace it. I manually delete the last willy with a simple djnz loop. I also tried just filling the attributes, no easier so went back to manually deleting willy. The code I am messing with has at the moment no aim or purpose. I am editing this data just out of curiosity.
-
Using an assembler and ditching the constraints of Matthew's FIXED layout. I had changed every reference and had a running version before I passed any comments. Yes I deleted the 3 calls to dance/score/time. I deleted the screen clear and moved the attribute set up to before the room set up. It took less than a minute to do. It played havoc with two other routines that I have which is the room cheat mode. (in my version the rooms are displayed animated, with no willy) I also have a proper DEMO mode the plays through all the screens. It must have take a good two minutes to implement the changes. I would say there is a very high likelyhood that implementing the changes as you outlined, in the manner you have explained. would indeed result in an outcome that fulfils its need. My only comment is the usage of the Title screen data as a source for the sprite clearing data.
-
Have you tried this out? As far as I can tell you are one willy out, and need to change the offset added ($a0) to ($9e)
-
Re clock update: ; 01234567890123456789012345678901 ; text for position *1 L8554 DEFM "Items collected 000 Time00:00:00" ; This data is directly changed by item collection and time L857F equ L8554+24 ; references to the old data, changed to reference directly the data above L857C equ L8554+16 ; as above ;L857C DEFM "000" ; This data is deleted ;L857F DEFM " 7:00:00" ; This data is deleted I have just tried the simple equate change and deleted the other clock update. I have also now added the item equate as well, and deleted the item update This works... for data on the status line L8554 I was experimenting with differing clock formats so Clock data is different and in a different position NOTE *1 . The position find is not displayed on this forums page, due to this forum using proportional fonts. The assembler uses a fixed size font.
-
Off hand can see no problem with that approach in JSW. In MM the score can overflow its allocated space. So needs to be separate. It also removes the annoying update flicker when a new room is entered.
-
re clock update I moved the print the clock status line into a subroutine. I then changed the clock up date routine to finish by calling the clock print subroutine. the original code does this the other way round. (the abort to time over needs to include the clock update) I moved the print dancing willies into a subroutine: because of the problem you have also experienced on not clearing the data I moved the room update code into another subroutine. On room update it clears the screen then draws the room and updates various other routines. e.g. The room is updated, but before returning CALL DISPLAY_LIVES ; updated because lives might be lost and the number of willies displayed will be different CALL SHOW_CLOCK ; clock must be updated it is only shown on time change CALL SHOW_ITEMS ; only updated on item collection
-
re conveyor:- MOVE_CONVEYOR: ;L94F9 LD A,(CONV_LEN) OR A RET Z LD B,A The test for length is the first test I do in that routine The next test I do is the bit that declares if the conveyor is animated or not. (not part of Matthew's routines) Speed slow down is accumulative. But sometimes the code can be as sloppy and slow as needed. This normally occurs when a single event has been triggered and the game can practically stop whilst the event happens. E.g. You can increase the length of item collection sound by a considerable degree. Even to the extent of being able to see the slow down on the screen. The player will not mind as this is part of his reward. On the other hand that pesky clock is printed on each game loop along with the items collected text. This type of slowdown is caused by not bothering to update on an update only basis, and because the game has to have additional code to display the text on each new room. Easier to just print on each loop. The speed increase by moving the test from the near the middle of the conveyor routine to the beginning might be around 20 to 80 t-states. (depends how much code) On the other hand going back to the clock print routine. around 150 t-states per letter . so if it prints 6 letters that's 900 t-states per game loop to print text that has not changed. I will always attempt to go for the faster or shorter routine. Normally one is the same as the other. But sometimes you need to look at why something is being done, and perhaps not rewrite it. But redesign it. Re conveyor- The code I list tends to be the easiest edit I can do that follows the original layout . so if it has all the line numbers and references to line numbers then it is a quick edit. (and probably not tested by me)
-
Byte saving. This is something that Matthew does as part of the code to move down the screen from raster line to raster line. ld a,l ;line 1 add a,$20 ; 2 ld l,a ; 3 and $e0 : 4 ret nz ; or jr nz (depending on version) I just wonder why the opcode -and $e0- is used on line 4. The addition on line 2 - add a,$20 - has set the carry flag for all the conditions that are wanted. The code should be. ld a,l ;line 1 add a,$20 ; 2 ld l,a ; 3 ret c ; or jr c (depending on version) This save two bytes. Since various mods have been used around this area, The exact condition Carry or no carry, will depend on what else is happening around this code area.
-
The reason I only rotate once is simply because I do not like the original animation. When willy or a sprite is animated on a conveyor, the speed the conveyor moves is exactly the same speed as willy moves. (or a standard horizontally moving sprite) Simple logic dictates that if the conveyor is moving in the same direction as willy and at the same speed then the conveyor is static below willies feet. It then follows that willy should not be animated. He should stay in the same frame and move graciously and serenely along the conveyor without moving a limb. The game does not provide that kind of animation, so my compromise is to move the conveyor at a slower speed to justify the animation. The speed change is also linked to the direction byte. (not listed in the code because it is not part of the original) but in my versions, the direction byte also stores animation status bits. The bits switch on/off animation. e.g. In this manner/style (done by me, in various edits) bit 5 no animation of the conveyor. Return immediately. bit 6 no lower animation of the conveyor . point high of register pair to "0" bit 7 reverse animate the conveyor (reverse animate, just to confuse) .xor bit with direction bit before testing By testing a bit in the direction byte. Either HL or DE can be set to point to the ROM. By setting "D" or "H" to 0. This allows the following code to stay the same. But the registers pointing to the ROM will stop the appropriate animation from being shown. The code as used by Matthew can easily be modified to use a consistent check on the direction byte. e.g. ignore all the other bits, which then become available to use. .
-
The listings I have provided are created ad hoc. ; the version I have currently looks like this. Next week it might be changed again JR Z,TOTHER EX DE,HL TOTHER LD A,(DE) :>>>>>> the opcode in question LD C,(HL) RLC A RRC C CON_DO LD (DE),A LD (HL),C INC E INC L DJNZ CON_DO RET But I will go back and change the opcode... The link back to the code, does not provide any means of editing the code.
-
If the code had been written as Ld a,(ix+$06) ld (hl),a inc h inc h ld (hl),a dec h ld a,(hl) and c ld (hl),$ff jp nz,#90b5 ;>>>> kill willy jp #93b3 Then it might have been a valid point on drawing the arrow Otherwise you have returned and not drawn the arrow shaft. Byte code is purely a guide. (the count is indicating a trend- nothing more)
-
When running JSW on an emulator, it quickly becomes evident that the emulator has problems scanning the keys. This problem manifests itself, if the cheat code has been typed in and key combinations are required to jump to rooms. This can/could be a problem caused by either the host hardware, the emulator, or both. This short program will simply display key presses as interpreted by the host machine and passed through the emulator. I find it fascinating that on one of the emulators I use ("FUSE") has so many problems. For example Press and hold "F" and "G" ., the rest of the row will now be ignored, except "ENTER". e.g. "A", "S", "D", "H", "J", "K", "L" will not register A newer version is listed a few posts later. (the update is only a graphic update) key_test.tap
-
Expanding on the theme ; The value in (ix+$05) is only used locally X9278 ;>>9278 LD (IX+$05),$00 LD BC,$700 ;-1 B=7 C=0 X927C LD A,(HL) ;>>927D AND $07 ;>>927F CP $07 INC A ;-2 AND B ;-3 X9281 JR NZ,L_9286 ;>>9283 DEC (IX+$05) DEC C ;-5 L_9286 LD A,(HL) ;>>9287 OR $07 OR B ;-6 X9289 LD (HL),A X928A INC DE X928B LD A,(DE) X928C LD H,A X928D DEC H X928E LD A,(IX+$06) LD B,A ;-5 X9291 LD (HL),A X9292 INC H X9293 LD A,(HL) ;>>9294 AND (IX+$05) AND C ;-7 X9297 JP NZ,$90B7 ;>>>>> kill Willy X929A LD (HL),$FF X929C INC H ;>>X929D LD A,(IX+$06) ;>>X92A0 LD (HL),A LD (HL),B ;-9 X92A1 JP $93B3
-
Original posted elsewhere but an hour after that post (several days ago) I revisited the data. With the intention of getting rid of half of it... Numbers are extrapolated from the data here. Original rope table consisted of 86 bytes of data, 42 zero's, 86 bytes of data and another 42 zero's The original modification was to shorten it to 86 bytes of data followed by 170 zero's This final mod shortens it yet again to 43 bytes of data followed by 213 zero's Of course the 213 zero's are now free to use, This code/data mod will free 86+43=(129) bytes. But will also make the space continuous. ; ; ok the full compression from the original 256 byte data table down to 43 bytes a saving of 211 ROPE_TABLE x8300 DEFB (6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0 x8304 DEFB (6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0 x8308 DEFB (6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0 x830C DEFB (6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0,(6*2+0)*16+6*2+0 x8310 DEFB (6*2+1)*16+6*2+1,(6*2+1)*16+6*2+1,(6*2+1)*16+6*2+1,(6*2+1)*16+6*2+1 x8314 DEFB (6*2+1)*16+6*2+1,(6*2+1)*16+6*2+1,(6*2+2)*16+6*2+2,(6*2+2)*16+6*2+2 x8318 DEFB (4*2+2)*16+6*2+2,(6*2+2)*16+4*2+2,(6*2+2)*16+4*2+2,(6*2+2)*16+4*2+2 x831C DEFB (6*2+2)*16+4*2+2,(4*2+2)*16+4*2+2,(6*2+2)*16+4*2+2,(4*2+2)*16+4*2+2 x8320 DEFB (4*2+2)*16+4*2+2,(4*2+1)*16+4*2+2,(4*2+2)*16+4*2+1,(4*2+1)*16+4*2+2 x8324 DEFB (4*2+1)*16+4*2+1,(4*2+2)*16+4*2+2,(4*2+3)*16+4*2+2,(4*2+3)*16+4*2+2 x8328 DEFB (4*2+3)*16+4*2+3,(4*2+3)*16+4*2+3,(4*2+3)*16+4*2+3 L930E: LD A,(IX+rope5) ;$05;rope pixel LD E,A ;TEMP SAVE of rope5 OR (HL) LD (HL),A ;pixel drawn LD A,(IX+rope9) ;$09 ;Point HL at the relevant entry in the rope animation table at 8300 LD D,A ;TEMP SAVE of rope9 ld c,(ix+rope1) add a,c ;$01 AND $7f ;$7f=%01111111=127 sra a ;get rid of bit 0 but set/reset the carry LD L,A LD H,High ROPE_TABLE ; $83 ld a,(hl) jr nc,high_set rrca rrca rrca rrca high_set: ld b,a and 1100b rrca add a,iyl ld iyl,a ld a,b and 3 ; update the x-position (if need and the draw bit) JR Z,L9350 LD B,A ; BIT 7,C ;$01;Is the rope currently right of centre? LD A,E JR Z,rope_right ; rope_left: RLCa ;$05;Rotate the drawing byte left once JR nc,hop1 ;complete rotation ? DEC (IX+rope3) ;$03;adjust x-coordinate hop1: DJNZ rope_left ; JR SAVE_A rope_right: RRCa JR nC,hop2 ;complete rotation INC (IX+rope3) ;$03;adjust the x-coordinate hop2: DJNZ rope_right SAVE_A: LD (IX+rope5),A L9350: LD A,D :the segment counter CP (IX+rope4) ;$04;all segments drawn yet? JR Z,L935E ;Jump if so INC (IX+rope9) ;$09; adjust segment counter JP DRAW_ROPE ;L92B6 ;loop for next segment of rope ; the above just about fits into the available space
-
On the theme of byte saving ; this code has been rewritten to save around 41 bytes L8CE8 DJNZ L8CE8 ;Delay for about a millisecond LD A,C LD HL,ATT6+10 ;$58CA CALL TWINKLE ;Change the INK colour of "Game" at (6,10/11/12/13) LD L,LOW ATT6+18 ;$58D2 LOW=$D2 CALL TWINKLE ;Change the INK colour of "Over" at (6,18/19/20/21) DEC C ; JR NZ,L8CE8 ; DEC D ; JR NZ,L8CE8 ; JP L87CA TWINKLE: LD B,4 TWNK: AND 7 OR $40 LD (HL),A INC HL INC A DJNZ TWNK RET FREE SPACE UP TO $8D33 AROUND $29=41(DECIMAL)
-
A total rewrite of JSW in 48k using Matthews core code
Norman Sword replied to Norman Sword's topic in JSW
You probably noticed that the code listed, used labels for the offsets into the data. e.g ld a,(ix+rope5) This usage of labels is something I have tended to do more and more over the years. It stems from needing to do rapid changes of data caused by changes in how I write something. By using labels it becomes an easy global change (in an assembler) to change an offset via the label. In the case of JSW the rope data suffers from an overflow of data, and the solution (in my case) was to reassign the offsets and to move the allocation of one bit from bit 0 to bit 7. The changes needed in the code was minimal. It also makes it obvious that it is rope data that is being used.