Jump to content
NHL'94 Forums

chaos

Admin
  • Posts

    2,134
  • Joined

  • Last visited

  • Days Won

    93

Everything posted by chaos

  1. I looked into this more, I'll prob post some info on how acceleration and top speed works soon. In 94, where we have a 0-30 range for Speed, there are only 15 entries in the MaxSpeed table. So, when the value is divided by 2 (shifted right by 1 bit), it will check if the Speed value was odd. Since there's no way to handle remainders, it needs to do extra math. So if it finds the starting Speed value was odd, it will take the difference between the 2 steps, divide that by 2, and add it to the lower MaxSpeed entry (So that it is halfway between the 2), and use that for MaxSpeed. Why are the MaxSpeed values squared? Because it is adding the squares of the new X and Y velocities and using that number to compare to MaxSpeed. Also, should be noted, if the player has the puck and is joypad controlled, their velocity adjustment will be halved. So they will be slower to get up to speed than without the puck (does not affect CPU players carrying puck though)
  2. Nice experiment! Just for reference, in the 92 source code (92 uses a 0-15 value for attributes), max speed table is listed like this: MaxSpeed ;max speed values for each rating level 0-f dc.l ((0+20)*250)^2 dc.l ((1+20)*250)^2 dc.l ((2+20)*250)^2 dc.l ((3+20)*250)^2 dc.l ((4+20)*250)^2 dc.l ((5+20)*250)^2 dc.l ((6+20)*250)^2 dc.l ((7+20)*250)^2 dc.l ((8+20)*250)^2 dc.l ((9+20)*250)^2 dc.l ((10+20)*250)^2 dc.l ((11+20)*250)^2 dc.l ((12+20)*250)^2 dc.l ((13+20)*250)^2 dc.l ((14+20)*250)^2 dc.l ((15+20)*250)^2 Just to give you an idea on how it calculated the values. 94 values are a little different (they are the same as 93, which also uses a 0-15 value for attributes). The calculation is ((X + 20) *275)^2 where X = In game Spd value / 2. (Max is 30 for the in game values) In game Spd value = Spd attribute (0-6) * 5 + Hot/Cold Bonus (which could be anywhere from +3 to -4). For example, a 5 Spd rated player 5 * 5 = 25. Let's say they have a -3 Hot/Cold, so 25 + -3 = 22. 22 / 2 = 11. So the MaxSpeed would be ((11+20) * 275)^2 = 8525^2 =72,675,625 or $0454F129. But, there is a bug in the game where the game thinks the crowd meter is broken. So the in game Spd value gets a +2 bonus, which would change the 11 to 12. So now we have ((12+20) * 275)^2 = 8800^2 =77,440,000 or $049DA400. The player can go above this speed temporarily (for example when speed bursting, or even during normal skating a little bit), but they will not get any acceleration if they are above it, so they will decelerate until they are below the max speed and continue that cycle. So, my question for your tests is did you make the ROM a static ROM (no hot/cold)? Because that would affect your numbers as well
  3. A League Champs: S1: Uncle Seth S2: angryjay93 S3: Uncle Seth S4: kingraph S5: angryjay93 S6: Uncle Seth S7: Corbettkb S8: angryjay93 S9: angryjay93 S10: Schmidt B League Champs: S1: sonoffett87 S2: hokkeefan2 S3: Tickenest S4: szpakman S5: kazelegend S6: Wittgenstein S7: INDIO * (replaced skankhunt42) S8: jv S9: kidswasted S10: Stantonator C League Champs: S2: INDIO S3: TecmoDPS S4: Charlesworth S5: Big Valboski S6: skankhunt42 S7: SOH S8: NewJerseyKiller S9: Stantonator S10: niuhuskie224 Draft Cameos: S2: Jeremy Roenick S3: Luc Robitaille (no show) S4: Russ Courtnall S5: Teemu Selanne CDL Season 11 I plan on starting this league in a few weeks. I will give it till 7/3/25 for S10 players from A, B, and C Leagues to let me know if they are returning. Once the time is done (or I've heard from everyone), there may be some open spots. Open spots in A will be filled by previous A league caliber players (ones who have played in A and still qualified to stay in A), or I will do a play in of sorts from top B teams to determine replacements (though I doubt we will need this). Open spots in B will more than likely be filled by C league players from S10, with a play in as well. This all depends on who signs up. There may be exceptions to the rule (where someone of B quality returns, they would participate in the play-in as well). Note, the only thing holding up the draft will be A and B signups. Once this is figured out, I will announce the start of the draft (along with the draft order). Draft show TBD. C league signups will be open up to the day of the A/B League Draft, and are open to anyone. Current league cap is 26. C league signups will be limited to the number of A/B league teams. Players who completed their seasons in CDL10 get priority in spots. Any open spots will be discussed once I hear from the returning coaches. Relegation and Promotion The criteria is still the same. Last season we had 13 teams in A, and 13 in B. The champion from C is guaranteed to move up to B, and the champion from B is guaranteed to move up to A. The coach with the worst record in A will be moved to B and the coach with the worst record in B will be moved to C. Depending on signups, the top performing regular season teams from B and C will have a chance to be promoted as well, in which case the 2nd worst teams in A and B will be moved down to B and C respectively. If the winner of the league was also the top performing reg season team, the next best reg season team will be chosen in this scenario. This is not a guarantee like winning the league is. As of right now: Moving up to A - Stantonator (B Champ) and whalers (best reg season record) Moving down to B - kidswasted (0.104 win Pct) and Chris O (0.250 win Pct) Moving up to B - niuhuskie (C Champ) and TecmoJon (.750 win Pct) Moving down to C - LeifErikson (.354 win Pct) and skills324 (.375 win Pct). If there is a play-in for B, both will be allowed to play. Again, this could change, depending on who is returning, signing up, etc. There could be more or less movement. Sign-ups C League is more of like a "farm" league, where coaches will choose (via a Team Selection Draft) one of the drafted A/B teams to play a season with, continued with a playoff. The C Champ and the team with the best reg. season record will be promoted to B league the following season, and allowed to partake in the A/B draft. This league is geared more towards the guys who are more novices at the game, especially draft leagues. They can choose a team during the Team Selection Draft that fits their abilities. C is open to any player whose setup has been CONFIRMED to work (they will have a role assigned to them in Discord). Sign-up deadline will be the day of the A/B League Draft, and cannot exceed the total amount of A/B teams (currently 26). League spots are for CDL10 returnees first. Empty spots in A and B will be filled by my choice; see first paragraph. Draft News Once A/B returnees all report, and I fill out the remaining spots, I will post the draft order. We are starting a new set of seasons in CDL with CDL11. I decided to make changes to the draft process. CDL11 will have an entirely random draft order, just like how CDL1 was. Starting with CDL12, the draft will be done differently. I haven't completely decided on what to do, but there will be a lottery for the top few picks, instead of going strictly by record. As far as the draft show, we will do a post A/B draft show, analyzing the teams and hopefully giving some insight that can help the C league players before their Team Selection Draft. League Info Stuff not changing from S10: - 5 min periods, 10 min OT, 1 min Penalties - Quicker control and longer range of Goalie - 0 Team Bonuses and PP/PK bonus - Warm/Cool Bonus (very slight hot/cold, attributes in the Edit Lines screen will be accurate) - Small Home Team Bonus in the Playoff ROM (+1), to make home ice a little more meaningful. - Reduced Penalty Shot timer - Goalie Boosts - +1 to Agl, +1 to DfA, +1 to PkC (previously +1 Agl, and +1 to all Stk/Glv in CDL1-9). All Stk/Glv will be normal classic values. Rules Warning! There are glitches in the game. A majority of them are unavoidable. Some of them are able to be triggered. In this league, anything goes. If a glitch causes a goal against you, you are free to talk about it with your opponent and decide an outcome, and come to an agreement. But there is no rule stating they have to reciprocate the goal. Double penalty shot? Play to the whistle. Next time blow your opponent out if he does something to piss you off. One rule regarding pulling the goalie - It must be done while having possession, or before a faceoff in the offensive or neutral zone. Let me know if you are returning or not, by posting below, or in this Discord thread - CDL11 Signups and Returnees. If I don't hear from you, I will assume you are not returning. List of returnees:
  4. No, this was just recently found out, a few years ago. EARE has it wrong still. Just set the PK to the PP values you want and vice versa
  5. These are not used in the game, I believe they are carryovers from 93 for matchup displaying. Also, there is a bug in the game where the PP value is used for PK and vice versa.
  6. It's up to you whichever weight bug fix you'd like to do. But if you want to do this one, yeah, I would remove the WBF and then change the bytes
  7. I think that's $30E. Maybe it is different in the 32 team ROMs? I looked, I don't know what it's trying to do with $30A. Right before it enters the routine where it's crashing, it is setting A2 and A3 to the start of the team structs. EDIT: Looks like A2 is set to $30A in 12 spots, and in all cases, few instructions after, there's a call to doBitMap. EDIT2: OK, when looking at the 92 source code, there are instances before doBitMap called, a2 is set to #null. null is a long variable set to 0. At $30A, it is a long word of 0.
  8. The penalties were already in 94, so there was no change done there. Fighting* is the winning fighter, Fighting is for the one who lost
  9. Weird, because this code is before the call to $12A2E subroutine: updatepwrplay: ; CODE XREF: periodiceevents+46↑j ROM:00012A7C 0838 0001 C2FA btst #1,(word_FFC2FA).w ROM:00012A82 6600 29E0 bne.w rtss2 ROM:00012A86 347C C6CE movea.w #(HmShots-M68K_RAM),a2 ROM:00012A8A 47EA 0364 lea $364(a2),a3 ROM:00012A8E 302A 0024 move.w $24(a2),d0 ; tmap ROM:00012A92 906B 0024 sub.w $24(a3),d0 ROM:00012A96 6700 009A beq.w _clrpwrplay ; teams have same # of players on ice ROM:00012A9A 6A00 001A bpl.w _t0 ROM:00012A9E 0838 0006 C2EE btst #6,(sflags2).w ; #sf2pwrtm - 0 for team 1, 1 for team 2 ROM:00012AA4 6600 0026 bne.w _upp ROM:00012AA8 6100 0088 bsr.w _clrpwrplay ROM:00012AAC 08F8 0006 C2EE bset #6,(sflags2).w ROM:00012AB2 6000 0018 bra.w _upp ROM:00012AB6 ; --------------------------------------------------------------------------- ROM:00012AB6 ROM:00012AB6 _t0: ; CODE XREF: updatepwrplay+1E↑j ROM:00012AB6 C54B exg a2,a3 ROM:00012AB8 0838 0006 C2EE btst #6,(sflags2).w ROM:00012ABE 6700 000C beq.w _upp ROM:00012AC2 6100 006E bsr.w _clrpwrplay ROM:00012AC6 08B8 0006 C2EE bclr #6,(sflags2).w ROM:00012ACC ROM:00012ACC _upp: ; CODE XREF: updatepwrplay+28↑j ROM:00012ACC ; updatepwrplay+36↑j ... ROM:00012ACC 08F8 0005 C2EE bset #5,(sflags2).w ; #sf2pwrplay - turn on PP ROM:00012AD2 6600 0014 bne.w _uppt ROM:00012AD6 526B 0004 addq.w #1,4(a3) ; tmpwrplays ROM:00012ADA B6FC C6CE cmpa.w #$C6CE,a3 ; check if a3 is home team ROM:00012ADE 6600 0006 bne.w _away ROM:00012AE2 ROM:00012AE2 _home: ; CODE XREF: updatepwrplay:_away↓j ROM:00012AE2 6000 0004 bra.w _uppt ROM:00012AE6 ; --------------------------------------------------------------------------- ROM:00012AE6 ROM:00012AE6 _away: ; CODE XREF: updatepwrplay+62↑j ROM:00012AE6 60FA bra.s _home ROM:00012AE8 ; --------------------------------------------------------------------------- ROM:00012AE8 ROM:00012AE8 _uppt: ; CODE XREF: updatepwrplay+56↑j ROM:00012AE8 ; updatepwrplay:_home↑j ROM:00012AE8 6100 F0A8 bsr.w printz ROM:00012AE8 ; --------------------------------------------------------------------------- ROM:00012AEC 0000 dc.b 0 ROM:00012AED 0012 dc.b $12 ROM:00012AEE 00BF dc.b $BF ROM:00012AEF 0001 dc.b 1 ROM:00012AF0 0019 dc.b $19 ROM:00012AF1 0020 dc.b $20 ROM:00012AF2 0020 dc.b $20 ROM:00012AF3 0020 dc.b $20 ROM:00012AF4 0016 dc.b $16 ROM:00012AF5 0017 dc.b $17 ROM:00012AF6 0018 dc.b $18 ROM:00012AF7 0019 dc.b $19 ROM:00012AF8 00BF dc.b $BF ROM:00012AF9 0001 dc.b 1 ROM:00012AFA 001A dc.b $1A ROM:00012AFB 0020 dc.b $20 ROM:00012AFC 0020 dc.b $20 ROM:00012AFD 0000 dc.b 0 ROM:00012AFE ; --------------------------------------------------------------------------- ROM:00012AFE 6100 FF2E bsr.w sub_12A2E Which does what you put into the $12A2E routine. The data after printz is a string so you can ignore that. So maybe there is something strange going on there?
  10. Going into that subroutine starting at $12A2E, A2 is the start of the Home Team Struct ($C6CE) or the start of the Away Team Struct ($CA32), depending on who has the PP (A2 is the team on the penalty kill). The other team struct (PP team) will be in A3. D0 is the end result in seconds and is returned from the function and used to calculate the displayed time. ; a2 = team struct on PK ROM:00012A2E ; a3 = team struct on PP ROM:00012A2E ROM:00012A2E CalcPenTime: ; CODE XREF: updatepwrplay+82↓p ROM:00012A2E 4240 clr.w d0 ROM:00012A30 4243 clr.w d3 ROM:00012A32 41EA 009A lea $9A(a2),a0 ; Move penalty box list start into a0 ($C768 for Home, $CACC for Away) ROM:00012A36 ROM:00012A36 _getstatus: ; CODE XREF: CalcPenTime+18↓j ROM:00012A36 ; CalcPenTime+20↓j ROM:00012A36 4242 clr.w d2 ROM:00012A38 1418 move.b (a0)+,d2 ; move value at a0 (then increment) into d2 ROM:00012A3A 6B00 0014 bmi.w _endoflist ROM:00012A3E 3432 2066 move.w $66(a2,d2.w),d2 ; move status of d2 player into d2 (pen time) ROM:00012A42 0802 000E btst #$E,d2 ; test bit 14 if set ROM:00012A46 66EE bne.s _getstatus ; branch if set (player on ice, injured, on bench) ROM:00012A48 9443 sub.w d3,d2 ; sub d3 from d2 ROM:00012A4A D042 add.w d2,d0 ; add d2 to d0 ROM:00012A4C 3602 move.w d2,d3 ; move d2 into d3 ROM:00012A4E 60E6 bra.s _getstatus ; loop till end of list ROM:00012A50 ; --------------------------------------------------------------------------- ROM:00012A50 ROM:00012A50 _endoflist: ; CODE XREF: CalcPenTime+C↑j ROM:00012A50 0C6B 0006 0024 cmpi.w #6,$24(a3) ; checks how many players are on ice (6 = everyone) ROM:00012A56 6700 2A0C beq.w rtss2 ; exit if so ROM:00012A5A 9043 sub.w d3,d0 ; sub d3 from d0 ROM:00012A5C 41EB 009A lea $9A(a3),a0 ; same as above, opposite team ROM:00012A60 4242 clr.w d2 ; clear d2 ROM:00012A62 ROM:00012A62 _getstatusopp: ; CODE XREF: CalcPenTime+40↓j ROM:00012A62 1418 move.b (a0)+,d2 ROM:00012A64 6B00 29FE bmi.w rtss2 ROM:00012A68 0833 0006 2066 btst #6,$66(a3,d2.w) ; check if bit 6 is set (pen time 64 sec+) ROM:00012A6E 66F2 bne.s _getstatusopp ; branch if set ROM:00012A70 B073 2066 cmp.w $66(a3,d2.w),d0 ; compare pen time a3 to d0 (total time for PP) ROM:00012A74 6D00 29EE blt.w rtss2 ; exit if less than ROM:00012A78 D043 add.w d3,d0 ; add d3 to d0 ROM:00012A7A 4E75 rts ROM:00012A7A ; End of function CalcPenTime
  11. Yeah, could be that. I'm thinking anything out of the range (0-25). If it's outside the range, it will pick up a different value and can't do the right math with it.
  12. The instructions at $12A40 have to do with player status. The code will keep track of each player's status (injury, on bench, on ice, penalty box time). -4 = injury for game -3 = injury for period -2 = bench -1 = on ice 0+ = penalty box time (in seconds) What it is trying to do is get how much time is left so it can display the PP time. I wonder if it's a problem related to # of players on the team, or if it's more reproducible with more than one player in the box for a team. EDIT: Yeah I tested with breakpoints, at RAM locations $C768 (Home) and $CACC (Away), it stores the player offset of the players in the penalty box (1 byte each, ends in $FF). This is used in the subroutine to get the player's status (in this case penalty box time, which 2 minutes = 120 seconds $78). It will check and make adjustments based on how many players are in the box and their time left. So there must be an issue with the number of players, as there will only be space for status for 26 players.
  13. No, the 127 is just to mean there can't be a penalty. So the subroutine returns a value that is used for a comparison. Since there can't be a no hitting penalty on a team that has a PP coming up (delayed call on the other team), the subroutine returns a 127 instead of the RNGed value.
  14. No the 127 fixed value is just for the penalty probability comparison. When a guy is checked and falls down, value needs to be 3 or less for penalty. When a guy is checked and stays up, 4 or less for penalty. When a guy is hooked 6 or less. All the 127 is doing is making sure it passes that penalty probability check as no penalty
  15. I updated my repo yesterday. It has a new LST file you can open up in a text editor and look through the code with my comments.
  16. You mean the 127 value? No, that's just to make sure during a delayed call that there's no coinciding action penalties. The team who is going on the PP can still get an interference penalty or penalty from injury, but can't get any others. The 127 just insures it's not below the compare limits.
  17. Nice chart! I'm confused about the "Make Up" Calls though. What are you using to determine that?
  18. I'm interested in what you found. Sometime last year I analyzed this code, just haven't posted yet. When penalties are off: The B check is less effective, because a calculation is done using the Chk rating of the player throwing the B check, and the Agl of the player being checked. RNG is also used. If its a CPU player throwing the B check, this calculation is ignored and it would work just like if penalties are off. Calculation (used when penalties are Off, and the player checking is controlled by a joypad): - Start with 32 decimal - Add Chk rating (0-30 dec scale) of checking player - Sub Agl rating (0-30 dec scale) of player being checked - Subtract 2 from result (this is due to crowd meter bug, it's always active) - New result = RNG (between 0 and the result above) - If new result is less than 24 decimal, exit (unsuccessful B check) If penalties are on, or it's a CPU player B checking, or the above calculation deemed it was good enough to continue: - Get difference of the 2 players in X (X_checking - X_checked) - Get difference of the 2 players in Y (Y_checking - Y_checked) - Use those results to get a direction (Ex: If checking player is directly to the right of checked player, their Xpos is more positive than the checked player, the X difference will be positive. If the checking player is directly above the checked player, their Ypos is more positive than the checked player, so Y difference will be positive). This is used to determine where the checking player is relative to the checked player. The result will be 0-7 (0 would be above the checked player, 2 would be to the right, 4 below, 6 to the left) - Subtract the checked player's direction from the above. - Add 1 to the result - Pass the first 3 bits (to make sure the result will be between 0-7) - Compare the result to 2. If higher than 2, B check is unsuccessful. - If lower than or equal to 2, code will enter the Fall Down routine - After Fall Down routine, it will check for penalties using the Aggression attribute (check the thread on Penalties for this). It will check if the calculated result is more than 4. If so, no penalty, if less than or equal, Tripping penalty. For Example: - Player is joypad controlled, penalties on (bypasses the Chk-Agl calc) - Checking player is above and to the right of the checked player. His position is top right of the checked player, which would result in a 1 after checking the positions. (Think 0-7 direction going clockwise, where 0 would be directly above). - Sub the checked player's direction. Let's say the player is facing up (again 0-7 for direction CW, facing up is 0). So his direction value is 0. So 1-0=1 - Add 1 to the result. 1+1=2 - Pass the first 3 bits. In this case, it doesn't matter, since our result was <= 7. We still have 2. - Compare to 2. We are equal to 2, so the check is deemed "successful" and we enter the Fall Down routine. On return, it will check for a penalty. Let's use same above, but checking player is now directly to the right of the checked player (so direction would be 2). Checked player is still facing up. - Sub checked player's direction - 2-0 = 0 - Add 1 to the result. 2+1=3 - Compare that to 2. We are higher than 2, so we will exit the routine. Also, there will be no check for a penalty here. Note, this is just the checking part. Has nothing to do with stealing the puck. This is to determine if the player will fall down (or have a chance to toddle) from the B check. But when the player falls down, they lose the puck possession, and with the checker's stick close to the puck, they have a chance to collect it. The other part of B checking where you steal the puck is different, it relies on the Stk rating of both players, and penalties on/off don't make a difference there. This other part also just happens if you bump into the player and the puck is near your player's stick.
  19. The Save RAM uses addresses in the $200000 range. Did you relocate it, or change the save ram bit at runtime? Maybe it doesnt really matter, since the "Leave Off!" is left off (User Records)
  20. Fight_w_inj.mp4 Injury is working, along with the toddle getting to the penalty box after injury. I checked multiplayer, and there are no problems! In a 2 controller H2H game, both fighters will be joypad controlled. Compatible with 3 and 4 player too. Next I will work on adding Fighting attribute to be displayed with the rest of the attributes.
  21. You should look at the decompressed ROM, as most of these ROM hacks will be using those. Here's the 30 team ROM - I don't know a good example for a 32 team ROM. Maybe @AdamCatalyst can give you one.
  22. Fight banner is in and working. I have to get the possible injury from fighting working next. After that, all the 93 fight code will be working in 94. I will also need to test out 2P,3P,4P and make sure they work, though I suspect they will be fine. After that, there's one fix I would like to apply. In 93, when a fight happens, it actually clears out the Chks For stat for all players (because it uses them for a condition for fighting). I plan to keep those totals, and use a different area to copy the Chks For to, and have the code clear that area instead. I will also be adding the Fighting attribute to the edit lines screen and Team Roster screens, so they can be viewed. This may take a bit though, might be something to do in the future.
  23. Buildable source is easy when you have the 92 source code. I have analyzed the hell out of the 94 code using the 92 source. A lot of it is still a mystery though.
  24. Thanks everyone! I have spent a ton of time on this, and it's nice to see it come together. Especially when it was thought impossible to do back in the day. With what we learned as far as the animation frames, sprites and sprite tiles, it should be easy enough to add new sprites and animations. With the work of disassembling the 94 code, we can add new functionality to use these added animations (like features that were present in the next gen titles) So right now, my added code and the displaced tables used for sprites and animations have been added to open space in the expanded ROM. These locations can easily be moved though. I would need to look at the 30 and 32 team ROMs to see what addresses are being used for graphics and move my code to make it compatible. This shouldn't be too hard to do. There are still some bugs to be ironed out, and some customization to be added, but the hard part is over. The code will be designed as a patch, and can easily be applied to any compatible ROM
×
×
  • Create New...