Basic Questions and Answers Thread

Discussion in 'Discussion & Q&A' started by Malevolence, Jul 7, 2009.

  1. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    On that behalf, anyone know why ASM68K is unable to identify negative OOR errors as such, instead of a plain "illegal value"? Shitty compiler or what is it?
     
    HackGame likes this.
  2. jubbalub

    jubbalub Mania fanboy Member

    Joined:
    Dec 25, 2014
    Messages:
    286
    That fixed the build error, but now whenever I test out my hack, it just loops the Sega screen over and over again.
     
  3. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    There is absolutely nothing wrong with the ASM68K assembler's error messages, Selbi. It's no more than a quick of the assembler itself, more precisely, it's the way code generation works. I personally wouldn't interpret this in a bad way of ASM68K being buggy or ambiguous - for being as simple and old as it is, the ASM68K does a damn good job.

    True, you may get different error messages on the same opcode having the similar causes (in our case, if the label referenced to by a branch gets too far from the branch itself). If the label is above the branch in the code, you usually get "Illegal value" error right away; if it's being expected somewhere below, the assembler simply doesn't know anything about the label by the time it parses the branch opcode: it doesn't know whether it's in the valid range yet (because the label wasn't met yet, its offset is unknown), it isn't even sure whether the label will be met eventually. In the latter case, the assembler will attempt to resolve the opcode later, during the next pass. The next, or the second pass, is where the "higher level" errors (like "Branch offset is out of range") usually occur.

    The types of the errors you get depend on the pass at which these errors were met. ASM68K is a simple two-pass assembler.

    During the first pass, it physically assembles the opcodes to their respective offsets in the output binary file, evaluates symbols (labels and constants) and any expressions that can be resolved right away (those, including simple math ($02+$02*8) or already-evaluated symbols from above). All opcode optimizations occur during this pass (they cannot occur later since the opcodes are being "physically" written to the binary file and their respective offsets are settled, so their sizes cannot be altered anymore).
    If the symbol or expression cannot be evaluated during this pass (a label wasn't met yet etc.), the opcode and its operands will use the full, non-optimized form (bra becomes bra.w, (SomeAddress) becomes (SomeAddress).l etc). This explains why ASM68K will never optimize bra LabelBelow to bra.s LabelBelow. Many people who spotted such behavior considered it a bug, while it's just the way assembler works.
    If there were no basic computation or syntax errors, the assembler proceeds to the second pass.

    During the second pass, the assembler will resolve all the operands and expressions that couldn't be evaluated during the first pass. All the opcodes are already written by the time, some of them just missing operand values. These unresolved operands are being evaluated and these values cannot be used in the context of the operand, opcode- or operand-specific errors occur.
     
  4. FireRat

    FireRat Do Not Interact With This User, Anywhere!!! Exiled

    Joined:
    Oct 31, 2009
    Messages:
    535
    Time for a non-technical but nevertheless very "basic" question: Assuming anything is do-able "the good and efforted way", what you think do a fan-character (not the protagonist) actually "require" to be accepted? Having a well represented "true" world to be around, fluent and detailed animations, what..?
     
  5. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    In my opinion, as long as the OC looks different any main character and has something to make it stand out (abilities, personality, etc.), it's acceptable in my book.

    You could also go the Pana/RHS route and change barely anything about the character while putting it in a really well made hack and no one would care because the hack is so good (although in RHS' case, he is an optional character).
     
    FireRat likes this.
  6. jubbalub

    jubbalub Mania fanboy Member

    Joined:
    Dec 25, 2014
    Messages:
    286
    Doesn't really have to do with hacking but I cannot for the life of me find working links to DAC samples from MJ's Moonwalker. Can someone point me in the right direction?
     
  7. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,016
    Check out ValleyBell's SMPS Research Pack. You can find Moonwalker's DAC samples, voice or otherwise, at Rips/68k/Michael Jackson's Moonwalker.
     
  8. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    I'm having trouble getting Hitaxas' splash screen to work in my Sonic 2 hack on the Xenowhirl disassembly. I appear to have some code written up by MJ a little ways down in the thread, which I put up here. After a lot of experimenting, I've gotten some odd, inconsistent results.

    If I run it after the SSRG splash screen in my hack, it loads my image just fine, but certain tiles/blocks in the image have weird black colors around them, although the art does get properly written to VRAM (I think this may be due to the squares using different palettes then they should, but I'm not sure). If I attempt to load it up immediately after the Sega screen, I get a black screen, despite the fact that the art and palettes appear to be loading in VRAM. Oddly enough, loading from the Level gamemode makes it work 100% perfectly, although loading it from an in-game level is obviously not reasonable for a splash screen.

    Does anyone have any idea what's going on? I know nothing of things like the VDP, art loading, mappings loading, or even just writing pixels directly to the screen, so despite my best efforts, this code is mostly lost on me...
     
  9. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    MJ's SSRG screen changes the backdrop color (color you normally see through the transparent tiles) to $00 (line 0 color 0), while many S1/S2 game modes usually use $20 (line 2 color 0).
    Looking at the splash screen's code, it really expects all the colors to be at palette line 2, including backdrop color, but it never ensures if backdrop color is set correctly. Which is why when the previous game mode has changed the backdrop color to a different one, it's not reverted, which is why you see black here and there -- VDP takes color from another palette line, but all the lines expect line 2 may be black during the splash screen.
    This also explains why it works properly after the "Level" game mode.

    To fix this bug, add ...
    Code:
        move.w    #$8720,VDP_control_port
    ... to the very beginning of the splash screen code, somewhere after the Pal_FadeFrom call.

    Not sure exactly why this happens, given there isn't enough information to tell, but if the splash screen doesn't crash or freeze, you may want to check if "display" is enabled on VDP.
    Although the splash screen code appears to enable "display" correctly as seen here:
    Code:
        move.w    ($FFFFF60C).w,d0        ; load VDP register 81XX data
        ori.b    #%01000000,d0            ; set display to "enable"
        move.w    d0,(a6)                ; save to VDP
    You may try to temporarily replace this bit with ...
    Code:
        move.w    #$8174,VDP_control_port
    ... to see if there's another bug here.
     
    MarkeyJester and Pacca like this.
  10. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    It worked perfectly! Thank you for the very thorough reply! I love to learn more about how the genesis works whilst fixing my problems :3
     
  11. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    Sorry for the double post, but I have another long standing issue that I'd like help on. In my hack, I temporarily replaced Sonic with Knuckles entirely, then later tacked on Sonic like I would a custom character, so the following code should be read with that in mind. The code in question is here. It's placed a little ways under the Level header, in the Xenowhirl disassembly.

    The issue is that when ever I try to play CNZ as any character other then Knuckles or Knuckles and Tails, the game seizes on the title cards for the zone. When I purposefully bypass the code by replacing the appropriate bne.s with bra.s, the game loads the level with the character just fine, so i'm 90% certain that this code is the issue. I can't explain why, though. The PLCs being loaded are for the Life Icons, which load normally in every other zone.

    I also have some other stuff above related to loading different level assets for each act, it works just fine for me, but I included it just in case it might be causing some of the issues at hand.
     
  12. Pokepunch

    Pokepunch That guy who posts on occasion Member

    Joined:
    Aug 7, 2009
    Messages:
    270
    Location:
    UK
    My first instinct is that you're overloading the PLC queue, I can remember experiencing this issue once before. You're limited to $14 Pattern Load Requests at one time, by placing more than this in the queue the PLC stalls, resulting in the game hanging on the Title Card as it waits for the game to finish decompressing the art, which it never will.

    CNZ also has more Patter Load Requests than the other zones, which leads me to be certain you're overloading the PLC queue.
     
  13. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    I modified part of the code to take what you said into account. Below the first LoadPLC branch (which seems to load the level art), I modified the code below (which clearly loads Knuckles life artwork, or sonics in a vanilla game.
    Code:
    cmpi.w    #1,(Player_mode).w    ; are we knuckles or knuckles and tails?
        bge.s    Level_NotKnux    ; if not, branch
        moveq    #1,d0    ;Start of life Icon art load?
        bsr.w    LoadPLC
    Level_NotKnux:
    This doesn't seem to help the issue, even though it looks like I'm taking an excess LoadPLC out of the running code for other characters. I could be wrong, though :I
     
  14. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    You said it works with Knuckles. Out of interest, does it work with Tails? Anyway:

    Change this:
    Code:
    	moveq	#1,d0	;Start of life Icon art load?
    	bsr.w	LoadPLC
    	bsr.w	sub_4450
    	moveq	#6,d0
    	tst.w	(Two_player_mode).w
    	bne.s	+
    	cmpi.w	#2,(Player_mode).w
    	bne.s	Level_NoTails
    	addq.w	#1,d0
    +
    	tst.b	(Graphics_Flags).w
    	bpl.s	+
    	addq.w	#2,d0
    +
    	bsr.w	LoadPLC
    ;start of sonic check; check for which Life Icon to load; load life icon; life icon load
    Level_NoTails:
    	cmpi.w	#3,(Player_mode).w	; are we Sonic?
    	bne.s	NotS_T	; if not, branch
    	moveq	#68,d0	; load Sonic's standard art
    	bsr.w	LoadPLC
    	bra.s Level_ClrRam
    NotS_T:
    	cmpi.w	#4,(Player_mode).w	; are we Sonic?
    	bne.s	LifeIcon_checkBuizel	; if not, branch
    	moveq	#68,d0	; load Sonic's standard art
    	bsr.w	LoadPLC
    	bra.s Level_ClrRam
    LifeIcon_checkBuizel:
    	cmpi.w	#5,(Player_mode).w	; are we buizle?
    	bne.s	LifeIcon_checkBuizelAndTails	; if not, branch
    	moveq	#71,d0	; load Buizel's standard art
    	bsr.w	LoadPLC
    	bra.s Level_ClrRam
    LifeIcon_checkBuizelAndTails:
    	cmpi.w	#6,(Player_mode).w	; are we Buizel?
    	bne.s	Level_ClrRam	; if not, branch
    	moveq	#71,d0	; load Buizel's standard art
    	bsr.w	LoadPLC
    To this:

    Code:
    	moveq	#1,d0			; Loads life icon (Knuckles), HUD, Rings and Numbers art
    	bsr.w	LoadPLC			; Load mentioned art
    	bsr.w	sub_4450		; Set/save player mode
    
    ; Knuckles life icon is loaded.  Ah, but we may not be Knuckles...
    	cmpi.w	#3,(Player_mode).w	; Is the player_mode set to be Sonic or Buizel?
    	bge.s	LoadSonicorBuizelsicon	; Yes?  Branch here
    	
    ; We must be Tails then.  But are we Miles or Tails and are we in single player or two player?
    	moveq	#6,d0			; Load Miles' icon into d0 but for 2-player's VRAM location
    	tst.w	(Two_player_mode).w	; Is it Two Player mode?
    	bne.s	+			; If so, branch
    	cmpi.w	#2,(Player_mode).w	; Are you Tails alone?
    	ble.s	Level_ClrRam		; If not, branch, and do not load a life icon (becuse you MUST be Knuckles and his icon is already loaded)
    	addq.w	#1,d0			; Load Miles' life icon but in a different VRAM location (where Knuckles VRAM location is set, seeming as it is single player)
    +
    	tst.b	(Graphics_Flags).w	; Is the Miles cheat set?
    	bpl.s	Loadlifeicon		; If so, branch, we're ready to load Mile's icon
    	addq.w	#2,d0			; It's not set, so set Tails life icon instead (it adds 2 to compensate if it's 2 player mode)
    	bra.s	Loadlifeicon		; We're set, load Tails' life icon
    
    
    LoadSonicorBuizelsicon:
    	moveq	#68,d0			; Set d0 to load Sonic's life icon
    	cmpi.w	#5,(Player_mode).w	; Are we actually Sonic?
    	blt.s	Loadlifeicon		; Yes?  Branch and load Sonic's life icon
    
    ; It's not Knuckles, Tails (Miles) or Sonic, it HAS to be Buizel...
    	moveq	#71,d0			; Set d0 to load Buizel's life icon
    
    Loadlifeicon:
    	bsr.w	LoadPLC			; Load Life Icon
    Your coding was potentially going to load 3 life icons when it didn't need to. This makes sure it only loads 2 at most. Reducing the PLC load. If CNZ still freezes, then you need to remove some from the PLC queue itself (ArtLoadCues: )


    More helpful advice (not that it will solve your current issue):
    Change this:

    Code:
    ; check for act 2, to use different table
    	tst.b	($FFFFFE11).w
    	bne.s	changeartpointers
    	lea	(LevelArtPointers).l,a2
    	bra.s	artpointers_act1
    changeartpointers:
    	lea	(LevelArtPointers2).l,a2
    artpointers_act1:

    To this:

    Code:
    ; check for act 2, to use different table
    	lea	(LevelArtPointers).l,a2		; Load act 1's address into a2
    	tst.b	($FFFFFE11).w			; Is it definitely act 1?
    	beq.s	+				; Yes?  Branch
    	lea	(LevelArtPointers2).l,a2	; Load act 2's address into a2 instead
    +
     
    Pacca, FireRat, jubbalub and 3 others like this.
  15. jubbalub

    jubbalub Mania fanboy Member

    Joined:
    Dec 25, 2014
    Messages:
    286
    Is there a way to make the game wait to do something, like wait X time before doing Y?
     
  16. TheStoneBanana

    TheStoneBanana banana Member

    Joined:
    Nov 27, 2013
    Messages:
    602
    Location:
    The Milky Way Galaxy
    What do you want to be waiting? I'm only asking because there are different ways to handle this based on what you want to wait (like an object, a time to display something on screen, etc.)
     
  17. jubbalub

    jubbalub Mania fanboy Member

    Joined:
    Dec 25, 2014
    Messages:
    286
    Specifically, setting the amount of time the Sega screen is up for.
     
  18. TheStoneBanana

    TheStoneBanana banana Member

    Joined:
    Nov 27, 2013
    Messages:
    602
    Location:
    The Milky Way Galaxy
    Within Sega_WaitPallet, there is a line at the very end which sets up a counter ($FFFFF614) used to time how long to display the screen.
    Code:
        ...
        move.w   #$1E,($FFFFF614).w ; < - here
    
    Sega_WaitEnd:
         move.b   #2,($FFFFF62A).w
         bsr.w   DelayProgram
         tst.w   ($FFFFF614).w
        ...
    
    Just change the value from #$1E to however long you want to display the screen in frames. In other words, a value of #60 would make the screen wait for exactly one second before changing.
    It's important to keep in mind that this all happens AFTER the SEGA sound is played, and it does not affect the length of the SEGA sound itself. The sound actually halts the game all together just to play, so it will always fully play before the counter is even set up
     
    Last edited: Jul 24, 2016
    redhotsonic, Pacca and jubbalub like this.
  19. its boomer

    its boomer Newcomer Member

    Joined:
    Jan 4, 2016
    Messages:
    17
    Location:
    Gornyak/Russia
    Hello, tell me how to change the order or delete some levels from the "Level Select" in the game sonic 1.
     
  20. TheStoneBanana

    TheStoneBanana banana Member

    Joined:
    Nov 27, 2013
    Messages:
    602
    Location:
    The Milky Way Galaxy
    You have to do two things, both requiring a hex editor.

    A.) Go into ls_point.bin and either change or remove a pointer for a level. They are in order of appearance on the Level Select, and the pointers are in the format of:
    XX YY
    XX = Zone ID
    YY = Act Number
    For the Zone IDs, 00 is Green Hill Zone, 01 is Labyrinth Zone, 02 is Marble Zone, 03 is Star Light Zone, 04 is Spring Yard Zone, and 05 is Scrap Brain Zone. ID 06 is for the Ending, 07 is Special Stage.
    The act numbers should be self explanatory.

    B.) Go into menutext.bin and edit the text for the Level Select entries. Each entry is $18 bytes long, and each letter correlates to the tile number within the font's art. It's a bit confusing, but just take a look at the art in SonMapEd or something and count the tiles (in hexidecimal, of course) to find what you need. For any blank spaces, use $FF.