' FIZZ BUZZ
'
' AN ARCADE PUZZLE GAME
'
' WRITTEN ENTIRELY ON AN IPHONE!
'
' CODE & GRAPHICS COPYRIGHT (C) 2019 NAT PRYCE
' LICENSE: CC BY-NC-SA 4.0

' TODO
' - SOUND FX

' PALETTES
' 0: FIZZ SPRITE
' 1: BUZZ SPRITE
' 2: ZAPPER
' 3: DIGITS
' 4: BORDER & TITLE TEXT
' 5: BUBBLE
' 6: GUAGE LEVEL
' 7: HIGHLIGHT TEXT

GLOBAL DEBUG
DEBUG = 0

GLOBAL NONE
NONE = -1

GLOBAL FALSE, TRUE
FALSE = 0
TRUE = NOT FALSE

'--------------------------------------------
' PATH API
' 
' INTERPOLATES PATHS IN MEMORY


GLOBAL PATH_SOURCE
PATH_SOURCE = NONE

' COUNT DUPLICATED IN A VARIABLE FOR
' CONVENIENCE
GLOBAL PATH_COUNT


GLOBAL PATH_COORD_OFFSET
PATH_COORD_OFFSET = 32


SUB PATH_SET_SOURCE(ADDR)
  PATH_SOURCE = ADDR
  PATH_COUNT = PEEK(PATH_SOURCE)
END SUB


SUB _PATH_OFFSET(P, RESULT)
  IADDR = PATH_SOURCE + 1 + 2*P
  RESULT = 256*PEEK(IADDR)+PEEK(IADDR+1)
END SUB


SUB PATH_LEN(PATH, RESULT)
  OFFSET = NONE
  CALL _PATH_OFFSET(PATH, OFFSET)
  RESULT = PEEK(PATH_SOURCE + OFFSET)
END SUB


SUB _PATH_GET_COORD(OFFSET, RESULT)
  ADDR = PATH_SOURCE + OFFSET
  RESULT = PEEK(ADDR) - PATH_COORD_OFFSET
END SUB


SUB _PATH_AOFFSET(P, A, XOFFSET)
  POFFSET = NONE
  CALL _PATH_OFFSET(P, POFFSET)
  XOFFSET = POFFSET + 1 + A*4
END SUB


SUB _PATH_ANCHOR_OFFSET(P, A, AOFFSET)
  POFFSET = NONE
  CALL _PATH_OFFSET(P, POFFSET)
  AOFFSET = POFFSET + 1 + A*4
END SUB


' INLINES THE RECURSIVE DEFINITION OF
' DE CASTELJAU'S ALGORITHM FOR THE 
' CASE OF CUBIC SPLINES.
'
' PRE: 
'   B() HAS SIZE OF AT LEAST 3
'   C() HAD SIZE OF AT LEAST 2
' POST: 
'   D CONTAINS THE INTERPOLATED VALUE
'   B() & C() CONTAIN INTERMEDIATE RESULTS
'   (USEFUL FOR SPLITTING CURVES)
'
SUB DECASTELJAU(V(), T, B(), C(), D)
  U = 1 - T
  
  B(0) = U*V(0) + T*V(1)
  B(1) = U*V(1) + T*V(2)
  B(2) = U*V(2) + T*V(3)
  
  C(0) = U*B(0) + T*B(1)
  C(1) = U*B(1) + T*B(2)
  
  D = U*C(0) + T*C(1)
END SUB


SUB PATH_POS(PATH, T, POSX, POSY)
  S = T \ 1
  CALL PATH_SEGMENT_POS(PATH,S,T-S,POSX,POSY)
END SUB


SUB PATH_SEGMENT_POS(PATH, S, T, POSX, POSY)
  DIM X(4)
  DIM Y(4)
  CALL PATH_SEGMENT_POINTS(PATH, S, X(), Y())
  
  CALL BEZIER_POS(X(), T, POSX)
  CALL BEZIER_POS(Y(), T, POSY)
END SUB


SUB BEZIER_POS(V(), T, VOUT)
  DIM B(2)
  DIM C(1)
  CALL DECASTELJAU(V(), T, B(), C(), VOUT)
END SUB


SUB PATH_SEGMENT_POINTS(P, S, X(), Y())
  ' X() AND Y() MUST HAVE AT LEAST 4 ELEMENTS
  
  CALL PATH_ANCHOR(P, S, X(0), Y(0))
  CALL PATH_CONTROL(P, S, 1, X(1), Y(1))
  CALL PATH_CONTROL(P, S+1, -1, X(2), Y(2))
  CALL PATH_ANCHOR(P, S+1, X(3), Y(3))
END SUB


SUB PATH_ANCHOR(P, A, X, Y)
  AOFFSET = NONE
  CALL _PATH_AOFFSET(P, A, AOFFSET)
  CALL _PATH_GET_COORD(AOFFSET, X)
  CALL _PATH_GET_COORD(AOFFSET+1, Y)
END SUB


SUB PATH_CONTROL(P, A, SIDE, X, Y)
  ' P: PATH
  ' A: ANCHOR INDEX
  ' SIDE: -1 OR 1
  '   INDICATES WHICH SIDE OF THE ANCHOR
  '   THE CONTROL POINT IS
  ' X: RETURNS THE X COORD
  ' Y: RETURNS THE Y COORD
  
  AOFFSET = NONE
  
  AX = NONE
  AY = NONE
  CX = NONE
  CY = NONE
  
  CALL _PATH_ANCHOR_OFFSET(P, A, AOFFSET)
  CALL _PATH_GET_COORD(AOFFSET, AX)
  CALL _PATH_GET_COORD(AOFFSET+1, AY)
  
  ' TANGENT VECTOR
  TX = PEEK(PATH_SOURCE+AOFFSET+2)-128
  TY = PEEK(PATH_SOURCE+AOFFSET+3)-128
  
  X = AX + SIDE*TX
  Y = AY + SIDE*TY
END SUB


'--------------------------------------------

GLOBAL HISCORE
HISCORE = 0



SUB DRAW_BORDER
  BG 0
  BG SOURCE ROM(3)
  BG COPY 0, 0, 20, 16 TO 0, 0
END SUB


SUB TITLE_SCREEN
  SPRITE OFF
  CLS
  
  CALL DRAW_BORDER
  
  ATTR (6)
  BG 1
  FOR TY = 0 TO 1
    FOR TX = 0 TO 12
      CELL TX, TY, 131+(16*TY)+TX
    NEXT TX
  NEXT TY
  
  BG 0
  ATTR (4)
  
  TEXT 2, 6, "TAP 1,2,3, ...99"
  TEXT 2, 8, "BUT MULITIPLE OF"
  TEXT 2, 9, "3: TAP FIZZ"
  TEXT 2, 10, "5: TAP BUZZ"
  TEXT 2, 11, "3&5: FIZZ, BUZZ"
  
  ATTR (7)
  TEXT 4, 13, "TAP TO START"
  
  REPEAT
    SHAKEX = 2*(RND - 0.5)
    SHAKEY = 2*(RND - 0.5)
    SCROLL 1, -48 + SHAKEX, -20 + SHAKEY
    
    WAIT VBL
  UNTIL TAP
  
  CLS
  SCROLL 1, 0, 0
END SUB


SUB PAUSE_CONTINUE
  WAIT 120
  
  ATTR (7)
  TEXT 2, 13, "TAP TO CONTINUE"
  
  REPEAT
    WAIT VBL
  UNTIL TAP
  
  ' ENSURE TAP DOESN'T AFFECT NEXT SCREEN
  WAIT VBL
END SUB


SUB LOSE_SCREEN

  SCORE = TARGET - 1
  IF SCORE > HISCORE THEN
    HISCORE = SCORE
  END IF
  
  CLS
  SPRITE OFF
  SCROLL 1, 0, 0
  
  CALL DRAW_BORDER
  
  ATTR (4)
  TEXT 5, 2, "GAME OVER"
  TEXT 2, 6, "YOUR SCORE: " + STR$(SCORE)
  TEXT 2, 9, "HIGH SCORE: " + STR$(HISCORE)
  
  CALL PAUSE_CONTINUE
END SUB



SUB WIN_SCREEN
  CLS
  SPRITE OFF
  SCROLL 1, 0, 0
  
  CALL DRAW_BORDER
  
  ATTR (4)
  TEXT 6, 2, "YOU WIN"
  
  TEXT 2, 6, "CONGRATULATIONS"
  TEXT 2, 9, "YOU REACHED 100"
  
  CALL PAUSE_CONTINUE
END SUB


'--------------------------------------------

' CHARACTER WIDTHS FOR DIGITS
DIM GLOBAL WIDTH(9)
FOR I = 0 TO 9
  WIDTH(I) = 5
NEXT I
WIDTH(1) = 3


' SPRITE ALLOCATION:
'  0-42: PARTICLES (RING BUFFER)
'  43: FIZZ
'  44: BUZZ
'  45-50: NUMBER BUBBLES (6)
'  51-63: DIGITS (1 OR 2 PER NUMBER BUBBLE)
'
' RANGE FOR HIT DETECTION: 43-50

GLOBAL S_FIZZ, S_BUZZ
S_FIZZ = 43
S_BUZZ = 44

GLOBAL S_NUMMIN, S_NUMMAX
S_NUMMIN = 45
S_NUMMAX = 50

GLOBAL S_HITMIN, S_HITMAX
S_HITMIN = 43
S_HITMAX = 50


GLOBAL S_PARTICLES
S_PARTICLES = 43

GLOBAL S_NEXT_PARTICLE
S_NEXT_PARTICLE = 0


GLOBAL MAX_LIFE
MAX_LIFE = 112

DIM GLOBAL S_BYNUM(99)
DIM GLOBAL S_X(63)
DIM GLOBAL S_Y(63)
DIM GLOBAL S_DX(63)
DIM GLOBAL S_DY(63)
DIM GLOBAL S_NUM(63)
DIM GLOBAL S_PATH(63)
DIM GLOBAL S_T(63)
DIM GLOBAL S_SHAKE(63)

GLOBAL MAX_LAUNCHED
MAX_LAUNCHED = 1 + S_NUMMAX - S_NUMMIN 


GLOBAL MIN_SPEED, MAX_SPEED, SPEED_RANGE
MIN_SPEED = 0.0125
MAX_SPEED = 0.025
SPEED_RANGE = MAX_SPEED - MIN_SPEED

GLOBAL GTIMER
GLOBAL LAUNCHED
GLOBAL LOWEST, HIGHEST
GLOBAL TARGET
GLOBAL LIFE
GLOBAL FIZZED


SUB MOVE(S)
  S_X(S) = S_X(S) + S_DX(S)
  S_Y(S) = S_Y(S) + S_DY(S)
END SUB


SUB POP(BUBBLE)
  BX = S_X(BUBBLE)
  BY = S_Y(BUBBLE)
  
  CALL PARTICLE_RING(18, BX,BY, 0.25, 0.25, 5)

  TRACK 0, 0
END SUB


SUB PARTICLE_RING(N, X, Y, BASEV, RNDV, COL)
  FOR P = 1 TO N
    ANGLE = RND * 2 * PI
    AX = COS(ANGLE)
    AY = SIN(ANGLE)
    PV = BASEV + RND*RNDV
    
    PX = X + 8*AX
    PY = Y + 8*AY
    PDX = PV * AX
    PDY = PV * AY
    
    CALL LAUNCH_PARTICLE(COL, PX,PY, PDX,PDY)
  NEXT P
END SUB


SUB LAUNCH_NUM(S, N)
  S_NUM(S) = N
  S_BYNUM(N) = S
  S_PATH(S) = N MOD PATH_COUNT
  S_T(S) = 0
  S_SHAKE(S) = 0
END SUB


SUB LAUNCH_GAME_START
  ' LAUNCH THE NEXT NUMBER BUBBLE AT THE 
  ' START OF THE GAME
  
  LOWEST = LOWEST - 1
  HIGHEST = MAX(HIGHEST, LOWEST)
  
  N = LOWEST
  S = S_NUMMIN + N - 1
  CALL LAUNCH_NUM(S, N)
END SUB


SUB RELAUNCH(S)
  N = S_NUM(S)
  
  IF N < LOWEST THEN
    HIGHEST = HIGHEST+1
    NEXTN = HIGHEST
  ELSE
    NEXTN = N
  END IF
  
  CALL LAUNCH_NUM(S, NEXTN)
END SUB


SUB MOVE_NUMBER(S)
  TMAX = NONE

  V = MIN_SPEED + SPEED_RANGE*(TARGET-1)/98
  
  S_T(S) = S_T(S) + V
  
  CALL PATH_LEN(S_PATH(S), TMAX)
  
  IF S_T(S) > TMAX THEN
    CALL RELAUNCH(S)
  ELSE
    P = S_PATH(S)
    CALL PATH_POS(P, S_T(S), S_X(S), S_Y(S))
  
    CALL DRAW_SPRITE(S, 16)
    SPRITE.A S, (5,0,0,0,1)
    CALL DRAW_NUMBER(S)
    
    CALL COUNTDOWN_SHAKE(S)
  END IF
END SUB


SUB DRAW_NUMBER(S)
  N = S_NUM(S)
  NY = S_Y(S)-4
  
  N1 = N \ 10
  N2 = N MOD 10
  
  NUMINDEX = S - S_NUMMIN
  
  NS = S_NUMMAX + 1 + NUMINDEX*2
  
  IF N1 = 0 THEN
    NX = INT(S_X(S)) - INT(WIDTH(N2)/2)
    CALL ADD_SHAKE(S, NX)
    
    SPRITE NS, NX, NY, N2+1
    SPRITE.A NS, (3,0,0,0,0)
  ELSE
    NX1 = INT(S_X(S)) - WIDTH(N2)
    CALL ADD_SHAKE(S, NX1)
    
    NX2 = S_X(S)+1
    CALL ADD_SHAKE(S, NX2)
    
    SPRITE NS, NX1, NY, N1+1
    SPRITE.A NS, (3,0,0,0,0)
    
    SPRITE NS+1, NX2, NY, N2+1
    SPRITE.A NS+1, (3,0,0,0,0)
  END IF 
END SUB


SUB MOVE_NUMBERS
  FOR S = S_NUMMIN TO S_NUMMAX
    IF S_NUM(S) > 0 THEN CALL MOVE_NUMBER(S)
  NEXT S
END SUB


SUB BOUNCE(N, DN, MAXN)
  EDGEN = MAXN + 8
  
  IF N < 8 AND DN < 0 THEN
    N = 8 + (N - 8)
    DN = -DN
  ELSE IF N > EDGEN AND DN > 0 THEN
    N = EDGEN - (N - EDGEN)
    DN = -DN
  END IF
END SUB


SUB MOVE_FIZZBUZZ(S, FRAME0)
  CALL MOVE(S)
  CALL BOUNCE(S_X(S), S_DX(S), 135)
  CALL BOUNCE(S_Y(S), S_DY(S), 111)
  
  F = FRAME0 + 2*((TIMER/10) MOD 8)
  
  CALL DRAW_SPRITE(S, F)
  
  CALL COUNTDOWN_SHAKE(S)
END SUB


SUB DRAW_SPRITE(S, F)
  X = S_X(S)-8
  Y = S_Y(S)-8
  
  CALL ADD_SHAKE(S, X)
  
  SPRITE S, X, Y, F
END SUB


SUB SHAKE(S)
  S_SHAKE(S) = 60
END SUB


SUB ADD_SHAKE(S, X)
  IF S_SHAKE(S) > 0 THEN
    PERIOD = 12
    MAGNITUDE = 3
    
    A = (S_SHAKE(S) MOD PERIOD)/PERIOD
    DX = MAGNITUDE * SIN(2*PI*A)
  
    X = X + DX
  END IF
END SUB


SUB COUNTDOWN_SHAKE(S)
  S_SHAKE(S) = MAX(0, S_SHAKE(S) - 1)
END SUB


SUB MOVE_PARTICLE(S)
  CALL MOVE(S)
  
  PT = GTIMER - S_T(S)
  F = PT\15

  IF F >= 4 THEN
    S_T(S) = 0
    SPRITE OFF S
  ELSE
    SPRITE S, S_X(S), S_Y(S), 20 + F
  END IF
END SUB


SUB MOVE_PARTICLES
  FOR S = 0 TO S_PARTICLES-1
    IF S_T(S) > 0 THEN
      CALL MOVE_PARTICLE(S)
    END IF
  NEXT S
END SUB


SUB LAUNCH_PARTICLE(COL, X, Y, DX, DY)
  S = S_NEXT_PARTICLE
  S_NEXT_PARTICLE = (S+1) MOD S_PARTICLES
  
  S_X(S) = X
  S_Y(S) = Y
  S_DX(S) = DX
  S_DY(S) = DY
  
  S_T(S) = GTIMER
  
  SPRITE.A S, (COL, 0, 0, 0, 0)
END SUB


SUB ZAP(SRC, DST)
  X0 = S_X(SRC)
  Y0 = S_Y(SRC)
  X1 = S_X(DST)
  Y1 = S_Y(DST)
  
  DX = X1 - X0
  DY = Y1 - Y0
  
  N = 12
  FOR I = 1 TO N
    R = I/N
    PX = X0 + R*DX
    PY = Y0 + R*DY
    PDX = 0.25*RND
    PDY = 0.25*RND
    CALL LAUNCH_PARTICLE(2, PX, PY, PDX, PDY)
  NEXT I
END SUB


SUB FLASH_BUBBLE(SRC)
  SX = S_X(SRC)
  SY = S_Y(SRC)
  
  CALL PARTICLE_RING(24, SX, SY, 0.25, 0.5, 2)
END SUB


SUB SHOW_REMOTE_POP(SRC, DST)
  IF DST <> NONE THEN
    CALL ZAP(SRC, DST)
  ELSE
    CALL FLASH_BUBBLE(SRC)
  END IF
END SUB


SUB LIFE(N)
  LIFE = MAX(0, MIN(LIFE + N, MAX_LIFE))
  SCROLL 1, 0, LIFE - MAX_LIFE
END SUB


SUB MISSED(TAPPED)
  CALL SHAKE(TAPPED)
  
  PENALTY = 1 + TARGET\5
  CALL LIFE(-PENALTY)
END SUB


SUB SUCCESS(POPPED)
  CALL LIFE(+5)
  TARGET = TARGET + 1
  
  MIDN = (LOWEST + HIGHEST)/2
  
  IF TARGET > MIDN THEN
    LOWEST = MIN(LOWEST+1, 100-MAX_LAUNCHED)
  END IF
  
  ' IT IS POSSIBLE TO HIT FIZZ OR BUZZ BEFORE
  ' A TARGET BUBBLE HAS BEEN LAUNCHED, IN
  ' WHICH CASE, POPPED WILL BE NONE
  IF POPPED <> NONE THEN
    CALL POP(POPPED)
    CALL RELAUNCH(POPPED)
  END IF
END SUB


SUB HANDLE_HIT(TAPPED)
  N = S_NUM(TAPPED)
  
  IF DEBUG THEN
    BG 0
    ATTR (7)
    TEXT 0, 2, "HIT: "+STR$(N)+" "
  END IF
  
  T3 = TARGET MOD 3 = 0
  T5 = TARGET MOD 5 = 0
  
  IF T3 AND T5 THEN
    IF FIZZED AND TAPPED=S_BUZZ THEN
      TS = S_BYNUM(TARGET)
      CALL SHOW_REMOTE_POP(S_FIZZ, TS)
      CALL SHOW_REMOTE_POP(S_BUZZ, TS)
      CALL SUCCESS(TS)
      FIZZED = FALSE
    ELSE IF NOT FIZZED AND TAPPED=S_FIZZ THEN
      FIZZED = TRUE
    ELSE
      CALL MISSED(TAPPED)
    END IF
    
  ELSE IF T3 THEN
    IF TAPPED = S_FIZZ THEN
      TS = S_BYNUM(TARGET)
      CALL SHOW_REMOTE_POP(S_FIZZ, TS)
      CALL SUCCESS(TS)
    ELSE
      CALL MISSED(TAPPED)
    END IF
  
  ELSE IF T5 THEN
    IF TAPPED = S_BUZZ THEN
      TS = S_BYNUM(TARGET)
      CALL SHOW_REMOTE_POP(S_BUZZ, TS)
      CALL SUCCESS(TS)
    ELSE
      CALL MISSED(TAPPED)
    END IF
    
  ELSE
    IF N = TARGET THEN
      CALL SUCCESS(TAPPED)
    ELSE
      CALL MISSED(TAPPED)
    END IF
  END IF
END SUB


SUB DETECT_HIT
  FOR S = S_HITMIN TO S_HITMAX
    DX = TOUCH.X - S_X(S)
    DY = TOUCH.Y - S_Y(S)
    DSQ = DX^2 + DY^2
    
    IF DSQ <= 256 THEN
      CALL HANDLE_HIT(S)
      EXIT SUB
    END IF
  NEXT S
END SUB


SUB START_GAME
  SPRITE OFF
  
  FOR S = 0 TO 63
    S_X(S) = 0
    S_Y(S) = 0
    S_DX(S) = 0
    S_DY(S) = 0
    S_PATH(S) = NONE
    S_T(S) = 0
    S_NUM(S) = NONE
    S_SHAKE(S) = 0
  NEXT S
  
  FOR I = 0 TO 98
    S_BYNUM(I) = NONE
  NEXT I

  
  LIFE = 112
  LOWEST = MAX_LAUNCHED+1
  HIGHEST = -1
  TARGET = 1
  FIZZED = 0
  
  SPRITE S_FIZZ, , , 76
  SPRITE.A S_FIZZ, (0,0,0,1,1)
  S_X(S_FIZZ) = 40
  S_Y(S_FIZZ) = 56
  S_DX(S_FIZZ) = -1/SQR(2)
  S_DY(S_FIZZ) = -1/SQR(2)
  
  SPRITE S_BUZZ, , , 78
  SPRITE.A S_BUZZ, (1,0,0,1,1)
  S_X(S_BUZZ) = 120
  S_Y(S_BUZZ) = 56
  S_DX(S_BUZZ) = 1/SQR(2)
  S_DY(S_BUZZ) = 1/SQR(2)
  
  CALL DRAW_GUAGE
END SUB


SUB DRAW_GUAGE
  ATTR (4,0,0,1)
  
  BG 0
  CELL 19, 0, 11
  FOR CY = 1 TO 14
    CELL 19, CY, 12
  NEXT CY
  CELL 19, 15, 13
  
  BG 1
  FOR CY = 0 TO 31
    CELL 19, CY, 14
  NEXT CY
  
  ATTR (3,0,0,1)
  FOR CY = 1 TO 14
    CELL 19, CY,
  NEXT CY
END SUB


SUB RUN_GAME
  CALL START_GAME
  
  GTIMER = 0
  
  REPEAT
    IF TAP THEN
      CALL DETECT_HIT
    END IF
    
    CALL MOVE_FIZZBUZZ(S_FIZZ, 64)
    CALL MOVE_FIZZBUZZ(S_BUZZ, 96)
    CALL MOVE_NUMBERS
    CALL MOVE_PARTICLES
    
    WAIT VBL
    
    GTIMER = GTIMER + 1
    
    IF LOWEST > 1 AND TARGET = 1 THEN
      IF GTIMER MOD 60 = 1 THEN 
        CALL LAUNCH_GAME_START
      END IF
    ELSE
      IF GTIMER MOD 30 = 1 THEN
        CALL LIFE(-1)
      END IF
    END IF
    
    IF DEBUG THEN
      BG 0
      ATTR (7)
      TEXT 0,0, "TARGET: "+STR$(TARGET)
    END IF
  UNTIL LIFE = 0 OR TARGET = 100
END SUB



TOUCHSCREEN
CALL PATH_SET_SOURCE(ROM(4))

DO
  CALL TITLE_SCREEN
  CALL RUN_GAME
  IF TARGET = 100 THEN
    CALL WIN_SCREEN
  ELSE
    CALL LOSE_SCREEN
  END IF
LOOP

#1:MAIN PALETTES
003F303C003F0333003C383400332230
003E3925003F2A15003F3020003F2A15

#2:MAIN CHARACTERS
00000000000000000000000000000000
0070D8D8D8D870000000000000000000
0060E060606060000000000000000000
0070D8183060F8000000000000000000
00F018701818F0000000000000000000
00C0D0D0F81010000000000000000000
00F8C0F01818F0000000000000000000
0070C0F0D8D870000000000000000000
00F81830306060000000000000000000
0070D870D8D870000000000000000000
0070D8D8781870000000000000000000
2C4646461C1846831C3E3E3E3C183E7F
83C183E5A7C183C16727672743276727
837E182C46460E3C7F7E181C3E3E7E3C
18181818181818181818181818181818
00000000000000000000000000000000
0000020C181020000718204040808080
0000800202010101E018040202010101
00010C1830200040071E33674FDFFFBF
0000000000000000E0F8FCFEFEFFFFFF
40A04000000000000000000000000000
000000000000000040A0400000000000
00000000000000000040000000000000
00400000000000000040000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
20000000000018078080804040201807
01010102020418E001010102020418E0
0000000000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00010C1830230343071E33674FDFFFBF
0000000000EC0C0CE0F8FCFEFEFFFFFF
00010C18307D6161071E33674FFFFFFF
0000000000BE868CE0F8FCFEFEFFFFFF
00010C1830373070071E33674FFFFFBF
0000000000EF60C1E0F8FCFEFEFFFFFF
00010C1830F73060071E33674FFFFFFF
0000000000E060C0E0F8FCFEFEFFFFFF
00010C1830F03060071E33674FFFFFFF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
00000000001F1818E0F8FCFEFEFFFFFF
0303030000000000FFFFFF7F7F3F1F07
CC0C0C0000000000FFFFFFFEFEFCF8E0
7961610000000000FFFFFF7F7F3F1F07
98B0BE0000000000FFFFFFFEFEFCF8E0
3133370000000000FFFFFF7F7F3F1F07
8306EF0000000000FFFFFFFEFEFCF8E0
C183F70000000000FFFFFF7F7F3F1F07
8000E00000000000FFFFFFFEFEFCF8E0
C080F00000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
1E18180000000000FFFFFFFEFEFCF8E0
00010C1830270647071E33674FDFFFBF
00000000009BDB9BE0F8FCFEFEFFFFFF
00010C1830F3DBF3071E33674FFFFFFF
00000000006F6163E0F8FCFEFEFFFFFF
00010C1830B7B0F0071E33674FFFFFBF
0000000000EF60C1E0F8FCFEFEFFFFFF
00010C1830F73060071E33674FFFFFFF
0000000000E060C0E0F8FCFEFEFFFFFF
00010C1830F03060071E33674FFFFFFF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
0000000000000000E0F8FCFEFEFFFFFF
00010C1830200040071E33674FDFFFBF
00000000001E1B1EE0F8FCFEFEFFFFFF
0606070000000000FFFFFF7F7F3F1F07
DBDB8E0000000000FFFFFFFEFEFCF8E0
DBDBF10000000000FFFFFF7F7F3F1F07
666CCF0000000000FFFFFFFEFEFCF8E0
B1B3E70000000000FFFFFF7F7F3F1F07
8306EF0000000000FFFFFFFEFEFCF8E0
C183F70000000000FFFFFF7F7F3F1F07
8000E00000000000FFFFFFFEFEFCF8E0
C080F00000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
0000000000000000FFFFFFFEFEFCF8E0
0000000000000000FFFFFF7F7F3F1F07
1B1B1E0000000000FFFFFFFEFEFCF8E0
0034664E0E1C3801384C9FBFFF7F3F3F
0000FF550000AAFF000000AAFFFFFFFF
001AB327072E1C041C264FDFFFFEFCFC
20000A81100010003CFCFBE378787860
409120010400020170F1EFCFCCC1C3C3
108010200180104010F0F363C3801878
06600250284010A0067EFED8387070E0
8402405204010400FC7E6E7E3C3F3733
842018000000000087EE7E7666666666
104A1024500810021E7EF5EDD9183062
208C1248841009223EFEF6CC8C181933
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
23312331233123311F0F1F0F1F0F1F0F
00000000000000000000000000000000
8CC48CC48CC48CC47C3C7C3C7C3C7C3C
8010C01000000000E0F0F31000000000
0000228000000000C7C7E6F000000000
0190000000000000F999010100000000
0114418000000000FFF7C18000000000
505401820000000073777FFE00000000
18423C00000000007E7E3C0000000000
29200B40000000006FFFFBC000000000
088006C0000000003FFFFEC000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
200034664E0F1C381F3F4F9FBFFF7C38
FF550000AAFF000000AAFFFFFFFF0000
801A332787CE1C007CE6CFDFFFFE1C00
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
183C3C3C3C183C181824242424182418
6CFEFE7E240000006C92925A24000000
247EFF7E7EFF7E24245A815A5A815A24
083E7F7E3F7F3E080836414631413608
62F7FE7C3E7FEF4662959A742E59A946
1C3E7E7EFFFE7F3A1C224A46919A453A
183C3C78300000001824244830000000
0C1E3C78783C1E0C0C1224484824120C
30783C1E1E3C78303048241212244830
00247E7EFF7E7E2400245A6681665A24
00183C7EFF7E3C180018246681662418
000000183C3C78300000001824244830
0000007EFF7E00000000007E817E0000
00000000183C3C180000000018242418
060F1E3C78F0E040060912244890A040
3C7EFFFFFFFF7E3C3C4299918999423C
183C7C3C3C7EFF7E182444242466817E
3C7EFF7E3C7EFF7E3C429972244E817E
3C7EFF7E6FFF7E3C3C4299726999423C
66FFFFFF7F0F0F066699998179090906
7EFFFEFE7F7FFE7C7E819E827979827C
1C3E7CFEFFFF7E3C1C224C829999423C
7EFF7F1E3C7878307E81791224484830
3C7EFF7EFFFF7E3C3C4299429999423C
3C7EFF7F7FFF7E3C3C4299417999423C
0000183C183C18000000182418241800
0000183C183C78300000182418244830
000C1E3C783C1E0C000C12244824120C
00007EFF7EFF7E0000007E817E817E00
0030783C1E3C78300030482412244830
3C7EFF7E3C183C183C42997224182418
3C7EFFFFFFFE7E3C3C429991919E423C
183C7EFFFFFFFF661824429981999966
7CFEFFFEFFFFFE7C7C8299829999827C
3C7EFFF6F6FF7E3C3C4299969699423C
78FCFEFFFFFEFC787884929999928478
7EFFFEFCF8FEFF7E7E819E84989E817E
7EFFFEFCF8F0F0607E819E8498909060
3C7EFEFFFFFF7E3C3C429E919999423C
66FFFFFFFFFFFF666699998199999966
3C7E3C3C3C3C7E3C3C4224242424423C
1E3F1F0F6FFF7E3C1E2119096999423C
66FFFEFCFCFEFF666699928484929966
60F0F0F0F0FEFF7E60909090909E817E
42E7FFFFFFFFFF6642A5998181999966
66FFFFFFFFFFFF666699898191999966
3C7EFFFFFFFF7E3C3C4299999999423C
7CFEFFFEFCF0F0607C8299829C909060
3C7EFFFFFFFE7F3E3C4299999592413E
7CFEFFFEFCFEFF667C82998284929966
3E7FFE7E3F7FFE7C3E419E423979827C
7EFF7E3C3C3C3C187E81662424242418
66FFFFFFFFFF7E3C669999999999423C
66FFFFFFFF7E3C186699999999422418
66FFFFFFFFFFE742669999818199A542
66FF7E3C7EFFFF666699422442999966
66FFFF7E3C3C3C186699994224242418
7EFF7E3C78FEFF7E7E817224489E817E
3C7E7C78787C7E3C3C424C48484C423C
60F0783C1E0F07026090482412090502
3C7E3E1E1E3E7E3C3C4232121232423C
183C7EFF660000001824429966000000
00000000007EFF7E00000000007E817E

#3:MAIN BG
00001410800481048104810481048104
81048104810481048104810481048104
81048104810481048104820490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000600000000
00000006000600000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
00000000000000000000920490040000
00000000000000000000000000000000
00000000000000000000000000000000
00009204900400000000000000000000
00000000000000000000000000000000
000000000000000000009204A004A104
A104A104A104A104A104A104A104A104
A104A104A104A104A104A104A104A104
A104A204

#4:PATHS
06000D002E004B0068008100A6071018
90884838908080389080A8488090A878
8090808870804888708010B0709006C0
106D81AB316C7E9E59687E90786F8081
926B814860726620106E590648108088
4048708040909890687888809890A070
98487080981080780568B09880689068
80687098806850688068309880681060
8008D0387080A0307080784878884878
6880286080764848988078788888A090
9080D0889080041898A18146979C7E70
6D9C8296419C80C02AA681

#15:MAIN SOUND
280030001DDD0A0018004052083A0000
0800606000000000280030301DFE0E00
38002020000000003800505000000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
40404040404040404040404040404040
421F00441F00FF000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000

