Urban Strike (Game Boy)
Urban Strike |
---|
Developer: Borta This game has uncompiled source code. |
Say hello to one of Game Boy's most hideous title screens.
Uncompiled Source Code
Two big chunks of uncompiled code can be found by using a hex editor on the ROM. Note that the formatting seen below matches the formatting seen in the ROM.
0x69E80:
call DO_SEQUENCE START_INTERIOR_CAMPAIGN: ld sp, $dfff ; set the stack pointer call LCD_off call InitWorld call PlayGame ;═════════════════════════════════════════════════════════════════════════════ vr_start_wait: ; Waits for the beginning of vertical retrace. Returns immediately if the ; display is turned off. Interrupts must be disabled if this routine is called ; while the display is turned on. push af ld a, (LCDC) and a, %10000000 jr z, .exit .loop: ld a, (LY) cp a, 145 ; 144 jr nz, .loop .exit: pop af ret ;───────────────────────────────────────────────────────────────────────────── vr_end_wait: ; Waits for the end of vertical retrace. Returns immediately if the display is ; turned off. Interrupts must be disabled if this routine is called while the ; display is turned on. push af ld a, (LCDC) and a, %10000000 jr z, .exit .loop: ld a, (LY) or a, a jr nz, .loop .exit: pop af ret ;───────────────────────────────────────────────────────────────────────────── LCD_off: ; Turns off the video display. Assumes interrupts are disabled. push af call vr_start_wait ld a, (LCDC) and a, %01111100 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── LCD_on: ; Turns on the video display. push af ld a, (LCDC) or a, %10000011 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── ;LCD_on_bkgr_off: ; Disables the display of the background but leaves the screen on. ; push af ; ; ld a, (LCDC) ; or a, %10000000 ; and a, %11111110 ; ld (LCDC), a ; ; pop af ; ; ret ;───────────────────────────────────────────────────────────────────────────── bkgr_off: ; Disables the display of the background. push af ld a, (LCDC) and a, %11111110 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── bkgr_on: ; Enables the display of the background. push af ld a, (LCDC) or a, %00000001 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── spr_off: ; Disables the display of sprites. push af ld a, (LCDC) and a, %11111101 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── spr_on: ; Enables the display of sprites. push af ld a, (LCDC) or a, %00000010 ld (LCDC), a pop af ret ;───────────────────────────────────────────────────────────────────────────── sound_off: push af ld a, (sound_flags) and a, 254 ld (sound_flags), a xor a, a ld (NR52), a pop af ret sound_on: push af ld a, (sound_flags) or a, 1 ld (sound_flags), a ld a, %11111111 ld (NR51), a ld (NR50), a ld a, %10001000 ld (NR52), a pop af ret ;───────────────────────────────────────────────────────────────────────────── cls: ; Clears one of the two VRAM display areas. May be called only when the ; display is turned off. ; call with D = area number (0 or 1) ; E = clear value ; push af ; push bc ; push hl ld bc, 1024 ld hl, $9800 bit 0, d jr z, .loop ld h, $9c .loop: ld (hl), e inc hl dec bc ld a, c or a, b jr nz, .loop ; pop hl ; pop bc ; pop af ret ;───────────────────────────────────────────────────────────────────────────── get_buttons: ; Returns with A = status of the buttons. push bc ld c, 0 ld a, $20 ld (c), a ; select direction buttons ld a, (c) ld a, (c) ld a, (c) and a, $0f ; A = 0000dulr ld b, a ; B = 0000dulr ld a, $10 ld (c), a ; select other buttons ld a, (c) ld a, (c) ld a, (c) ld a, (c) ld a, (c) ld a, (c) ld a, (c) ld a, (c) ld a, (c) and a, $0f ; A = 0 0 0 0 sta sel b a swap a ; A = sta sel b a 0 0 0 0 or a, b ; A = sta sel b a d u l r cpl pop bc ret ;───────────────────────────────────────────────────────────────────────────── fill_copy_proc: ; call with B = total bytes of data / 2; B must be <= 144 ; DE -> second-to-last byte of data ; the correct bank selected ; Before jumping to copy_proc, set SP -> byte after last destination byte, and ; HL = return address. push af push bc push de push hl ld hl, copy_proc .loop: inc hl ld a, (de) inc de ld (hli), a ld a, (de) dec de dec de dec de ld (hli), a inc hl dec b jr nz, .loop ld a, (jp_addr) ld e, a ld a, (jp_addr + 1) ld d, a ld a, $11 ld (de), a ; "erase" previous "jp (hl)" instr. ld a, $e9 ; $e9 = "jp (hl)" ld (hl), a ; insert "jp (hl)" instruction ld a, l ld (jp_addr), a ld a, h ld (jp_addr + 1), a pop hl pop de pop bc pop af ret ;───────────────────────────────────────────────────────────────────────────── load_chars: ; call with (dest_addr) -> byte after last destination byte ; May be called only when the display is turned off or during v-blank. If ; (dest_addr + 1) = 0, then load_chars does nothing. load_chars sets ; (dest_addr + 1) = 0. ld (stack_save), sp ld sp, hl ; SP = (dest_addr) ld hl, .back jp copy_proc .back: ld hl, stack_save ld a, (hli) ld h, (hl) ld l, a ; HL = (stack_save) ld sp, hl ; SP = (stack_save) ret ;───────────────────────────────────────────────────────────────────────────── RAMMoveSpriteObject: ; call with A = total sprites in object ; C = number of first sprite (0 - 39) ; D = dy ; E = dx push af push bc push hl ld b, a ; B = total sprites in object ld a, c ; A = number of first sprite add a, a add a, a ; A = number of first sprite * 4 ld l, a ld h, $c0 ; HL -> sprite in RAM sprite table .loop: ld a, (hl) ; A = sprite y-coordinate cp a, $e0 jr z, .skip add a, d ld (hli), a ld a, (hl) ; A = sprite x-coordi
0x6EB0B:
ld b, 11 .ENCODE_LOOP: ld a, (hl) ld de, PASS_CHAR add a, e ld e, a ld a, d adc a, 0 ld d, a ld a, (de) ld (hli), a dec b jr nz, .ENCODE_LOOP ret ;******************************************************* ;******************************************************* ;******************************************************* ;******************************************************* ;******************************************************* ; password decoding ;******************************************************* ; PASS_DECODE: ;******************************************************* PASS_DECODE: ; copy PASSWD to PASSWD_TEMP, reduce to 0-31 range ld hl, PWString ld de, PWTemp ld b, 11 .REDUCE_LOOP: ld a, (hli) ; a = character from p.w. string push bc push hl ld hl, PASS_CHAR + 30 ; 28 ; 31 ld b, 31 ; 29 ; 32 .search: ld c, (hl) dec hl cp a, c jr z, .match dec b jr nz, .search pop hl pop bc jp .FAIL .match: dec b ld a, b ld (de), a inc de pop hl pop bc dec b jr nz, .REDUCE_LOOP .DECODE: ld a, (PWTemp_5) sra a ld b, a ld (nibble_2), a ld a, (PWTemp_10) sub a, b ld b, a ld (nibble_5), a ld a, (PWTemp_1) sub a, b ld b, a ld (nibble_3), a ld a, (PWTemp_4) sub a, b ld b, a ld (nibble_0), a ld a, (PWTemp_7) sub a, b ld b, a ld (nibble_1), a ld a, (PWTemp_8) sub a, b ld b, a ld (nibble_7), a ld a, (PWTemp_0) sub a, b ld b, a ld (nibble_4), a ld a, (PWTemp_9) sub a, b ld b, a ld (nibble_6), a ld a, (PWTemp_2) sub a, b ld b, a ld (nibble_8), a .CHECK: ld hl, nibble ld de, 0 ld b, 9 .CHECK_LOOP: ld a, (hl) add a, d ld d, a ld a, (hli) xor a, e ld e, a dec b jr nz, .CHECK_LOOP ld a, (PWTemp_3) ld c, a ld a, d ; and a, 01Fh .loop: cp a, 31 jr c, .ok sub a, 31 jr .loop .ok: cp c jr NZ, .FAIL ld a, (PWTemp_6) ld c, a ld a, e sla a cp c jr NZ, .FAIL .UNMANGLE: ld de, GameScore ld hl, CRYPTO STORE_HL_TO TEMPW_2 ld hl, nibble ld b, 4 .UNMANGLE_LOOP: ld a, (hli) ld c, a ld a, (hli) sla a sla a sla a sla a or a, c push hl push af LOAD_HL_FROM TEMPW_2 pop af xor a, (hl) inc hl ld (de), a inc de STORE_HL_TO TEMPW_2 pop hl dec b jr nz, .UNMANGLE_LOOP ; check level < FINAL_WORLD ld a, (hl) cp a, FINAL_WORLD + 3 ; allow view game end (=10) , credits (=11), fail on (=12) jr NC, .FAIL ld (CURR_WORLD), a and a, a ret .FAIL: jr .FAIL ; zero out the current world and game score xor a ld hl, GameScore ld (hli), a ld (hli), a ld (hli), a ld (hli), a ld (CURR_WORLD), a scf ret cp a, FINAL_WORLD + 3 ; allow view game end (=10) , credits (=11), fail on (=12) jr NC, .FAIL ld (CURR_WORLD), a and a, a ret .FAIL: jr .FAIL ; z
ZIP Archives
Two corrupted ZIP archives that probably contained more source code of the game can be found in the ROM. The last modified dates of the files they contain range between 6 to 10 months before the final US release date.
0x27F8C:
Contains a file named OSTRUCT4.ASM with a last modified date of 1996-05-09 10:49:00 in UTC time that can't be extracted due to the ZIP file's corruption.
0x4FEFE:
Contains two files: one of them is named OSTRUCT.INC, has a last modified date of 1996-01-17 08:36:16 in UTC time and can't be extracted for the same reason of the precedent one. The other file, UDATA.INC, was last modified on 1996-03-13 10:59:30 UTC and can be extracted:
PASS_CHAR: ; db "0123456789ABCDEFGHJKMNPQRTUVWXYZ" db "0123456789BCDFGHJKLMNPQRSTVWXYZ"
From the commented-out instruction it can be seen that at some point of the development A, E and U were valid password characters before being replaced with L and S in the final game (one character was removed in the final version).
The Strike series
| |
---|---|
Amiga | Desert Strike: Return to the Gulf |
Genesis | Desert Strike: Return to the Gulf • Jungle Strike • Urban Strike |
Sega Master System | Desert Strike |
Game Gear | Jungle Strike |
SNES | Desert Strike: Return to the Gulf • Jungle Strike • Urban Strike |
Game Boy | Desert Strike: Return to the Gulf • Urban Strike |
PlayStation | Nuclear Strike |
Nintendo 64 | Nuclear Strike 64 (Prototypes) |
Game Boy Advance | Desert Strike Advance |
- Pages missing developer references
- Games developed by Borta
- Pages missing publisher references
- Games published by Black Pearl
- Game Boy games
- Super Game Boy games
- Pages missing date references
- Games released in 1996
- Games released in November
- Games with uncompiled source code
- Games with unusual dummy files
- Strike series
Cleanup > Pages missing date references
Cleanup > Pages missing developer references
Cleanup > Pages missing publisher references
Games > Games by content > Games with uncompiled source code
Games > Games by content > Games with unusual dummy files
Games > Games by developer > Games developed by Borta
Games > Games by platform
Games > Games by platform
Games > Games by platform > SNES games > Super Game Boy games
Games > Games by publisher > Games published by THQ Nordic > Games published by THQ > Games published by T·HQ > Games published by Black Pearl
Games > Games by release date > Games released in 1996
Games > Games by release date > Games released in November
Games > Games by series > Strike series
The Cutting Room Floor > Unimportant Awards > Game Boy games
The Cutting Room Floor > Unimportant Awards > Game Boy games