aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2026-03-23 23:59:26 +0100
committerMiquel Sabaté Solà <mssola@mssola.com>2026-03-23 23:59:26 +0100
commit0c9b0ad7938e2ba7e994574b4947e25c82440b8c (patch)
treecb6721fc9689104463b5a71ca02303299486af9e
parentfb23cf51040f06bfcfbaf318d7b452d76ffbedfb (diff)
downloadjetpac.nes-0c9b0ad7938e2ba7e994574b4947e25c82440b8c.tar.gz
jetpac.nes-0c9b0ad7938e2ba7e994574b4947e25c82440b8c.zip
Implement the "take off" animation
This is the animation that is done after clearing a stage. Moreover, and for the first time since I started development, now we can move into the next level as intended from the game's design. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
-rw-r--r--.nasm/segments.txt2
-rw-r--r--assets/jetpac.chrbin8192 -> 8192 bytes
-rw-r--r--assets/session.nss54
-rw-r--r--src/background.s54
-rw-r--r--src/driver.s303
-rw-r--r--src/interrupts.s10
-rw-r--r--src/items.s143
-rw-r--r--src/over.s48
8 files changed, 498 insertions, 116 deletions
diff --git a/.nasm/segments.txt b/.nasm/segments.txt
index 85c337d..c2666b1 100644
--- a/.nasm/segments.txt
+++ b/.nasm/segments.txt
@@ -1,4 +1,4 @@
- HEADER: 16/16 (100%)
-- ROM0: 8276/32762 (25.26%)
+- ROM0: 8716/32762 (26.60%)
- ROMV: 6/6 (100%)
- ROM2: 8192/8192 (100%)
diff --git a/assets/jetpac.chr b/assets/jetpac.chr
index e76c625..83ed901 100644
--- a/assets/jetpac.chr
+++ b/assets/jetpac.chr
Binary files differ
diff --git a/assets/session.nss b/assets/session.nss
index 64ff0d6..ffaadd3 100644
--- a/assets/session.nss
+++ b/assets/session.nss
@@ -3,8 +3,8 @@ NSTssTXT
BtnTiles=1
BtnChecker=0
BtnSelTiles=0
-BtnChrBank1=1
-BtnChrBank2=0
+BtnChrBank1=0
+BtnChrBank2=1
BtnChrBank3=0
BtnChrBank4=0
BtnGridAll=1
@@ -53,10 +53,10 @@ VarBankActive_msprBuffer=0
VarPalBank_mapBuffer=0
VarPalBank_msprBuffer=0
VarTileViewTagBuf=0
-VarBgPalCur=0
+VarBgPalCur=1
VarPalActive=2
-VarTileActive=128
-VarBankActive=0
+VarTileActive=66
+VarBankActive=4096
VarPPUMask=0
VarPPUMaskSet0=0
VarPPUMaskSet1=0
@@ -81,10 +81,10 @@ VarNameSelectionT=-1
VarNameSelectionB=24
VarNameCopyW=17
VarNameCopyH=3
-VarCHRSelectionL=0
-VarCHRSelectionR=1
-VarCHRSelectionT=8
-VarCHRSelectionB=9
+VarCHRSelectionL=2
+VarCHRSelectionR=4
+VarCHRSelectionT=4
+VarCHRSelectionB=6
VarCHRCopyW=1
VarCHRCopyH=1
VarCHRCopyRect=1
@@ -160,7 +160,7 @@ RadioAutoexport_UseSubDir_NEXXT=0
CheckAutoexport_MetatileAsBMP=0
-VarCHRSelected=00[80]0100[7f]
+VarCHRSelected=00[42]0100[bd]
Palette=0f3024280f16241b0f1610300f1630000f302c280f1122330f282c160f1324350f1324360f1526370f1627370f1928380f1829380f1b2a390f1b2b3c0f1c2c3b
@@ -169,13 +169,13 @@ Palette=0f3024280f16241b0f1610300f1630000f302c280f1122330f282c160f1324350f132436
PalUndo=0f3024280f16241b0f1610300f1630000f302c280f1122330f282c160f1324350f1324360f1526370f1627370f1928380f1829380f1b2a390f1b2b3c0f1c2c3b
-CHRMain=00[10]2f7fffddfb7b71212f7fffddfb7b7121bdff[2]f7ebddad04bdff[2]f7ebddad044cfeff3efffe9c084cfeff3efffe9c0801[2]02[2]05[2]090800[8]80[2]c0[2]e0[2]f01000[8]09[8]00[8]f0[5]50[3]00[8]09[5]19[2]2900[8]10f0b030b018f8fc00[8]2959[2]89b9[4]00[8]fcf4f6[2]f1f7[3]00[8]b9[3]f9a9[2]f4f500[8]f7[2]fff5[3]6fef00[8]555289b9b8[4]00[8]eacb919717[4]00[9]3c464a52623c00[a]182808[3]3e00[a]3c42023c407e00[a]3c420c02423c00[a]081828487e0800[a]7e407c02423c00[a]3e407c42[2]3c00[a]3e02040810[2]00[a]3c423c42[2]3c00[a]3c42[2]3e023c00[9]3c4299a1[2]99423c00[9]3c42[2]7e42[2]00[a]7c427c42[2]3c00[a]3c4240[2]423c00[a]7c42[4]7c00[a]7c407040[2]7c00[a]3c40[2]7040[2]00[a]3c42404e423c00[a]42[3]7e42[2]00[a]3e08[4]3e00[a]02[3]42[2]3c00[a]44487048444200[a]40[5]7e00[a]42665a42[3]00[a]4262524a464200[a]3c42[4]3c00[a]7c42[2]7c40[2]00[a]3c42[3]3c0600[a]3c42[2]7c444200[a]3e403c02[2]7c00[a]3e08[5]00[a]42[5]3c00[a]22[4]140800[a]42[3]5a664200[a]422418[2]244200[a]41221408[3]00[a]7e040810207e00[9]18243c7e5a3c[2]6600[10]0810[2]20e0c000[2]30d0f0[6]30d0f0[7]fefffcfeff[3]f0fefffcfeff[3]00[a]01030206[2]0c00[8]0fffbf3f7f[2]ff[2]4f50607f00[4]4f50607f00[4]ff00[2]ff00[4]ff00[2]ff00[4]f90503ff00[4]f90503ff00[4]30ff[3]f0207f[2]30ff[3]f0207f[2]8f80407f00[4]8f80407f00[4]ff[8]00[8]ff[4]00[14]077f4f8f[5]00[8]ff[8]00[2]c06030188cc400[2]c06030188cc400[8]f8fce6[2]e7[4]00[8]071f3f5f9f[4]00[8]ff[6]fe[2]00[8]f8c6c182[2]04[2]0800[8]3f7fffdf9f[4]860488f800[4]860488f800[c]fe[2]c1a190fffcd800[8]e0f0b89c[2]8c[3]0c0919[2]3b33276f0c0919[2]3b33276fff[10]fcfbf8f0f1e1[2]c3fcfbf8f0f1e1[2]c300[4]ff[4]00[8]9fa0c0ff00[4]9fa0c0ff00[c]8f[2]cf77340f00[a]ff[5]7fbf00[9]ff[4]fe[2]fd00[9]e7f7fe1e3cf800[a]9f[5]bfff7f00[8]fe[2]c1a190fffcdf00[8]0810[2]20e0c0fc0200[8]9f[5]a0ff4000[8]ff0f[3]ff00ff00[9]ff[5]00ff00[9]8c[4]ccf8[3]fcf8c06030188cc4fcf8c06030188cc44f48f0ff00[4]4f48f0ff00[4]e6160cf800[4]e6160cf800[c]f1[5]f9fdff00[8]f8f6f1[6]00ff[3]00[2]ff[2]00ff[3]00[2]ff[2]7fbf5f9f[5]7fbf5f9f[5]fefdfaf9[5]fefdfaf9[5]00[8]0d191b3337674fff807fff[3]bf9f[2]807fff[3]bf9f[2]3fdff0ff[4]f03fdff0ff[4]f0e4fa0cfafcfafc0ee4fa0cfafcfafc0e78bf5f9f[5]78bf5f9f[5]fefdfbfdf9[4]fefdfbfdf9[4]7ffffc00[5]7ffffc00[5]f1c00103[2]06[2]0cf1c00103[2]06[2]0cf3ff[2]fcfeff[3]f3ff[2]fcfeff[3]1f7f9f[6]1f7f9f[6]ff0100ff00[4]ff0100ff00[c]ff[4]0f[3]ff01fdfefd1e0dfefb01fdfefd1e0dfefb3f2f4f[6]3f2f4f[6]9f3fff[6]9f3fff[6]f9[10]00[8]ff[5]fe[2]ff9f[10]00[90]0c1c1838300060[2]00[8]ffe7d7f7[3]c1ff00[8]ffc3bdfdc3bf81ff00[178]ff83bd[2]83bf[2]ff00[48]ffbd[5]c3ff00[609]03071617[2]33300003071617[2]333000c000[4]e000[2]c000f070[2]e0002b3f01[2]03[3]002b3f01[2]03[3]00e0[2]d0a030b8fc00e0[2]d0a030b8fc0001[2]02[2]05[2]090801[2]02[2]05[2]090880[2]c0[2]e0[2]f01080[2]c0[2]e0[2]f01009[5]19[2]2909[5]19[2]2910f0b030b018f8fc10f0b030b018f8fcb9[3]f9a9[2]f4f5b9[3]f9a9[2]f4f5f7[2]fff5[3]6feff7[2]fff5[3]6fef00[2]3c3f7f7c7d[2]071f3f7ffffcfd[2]00[3]e0f038[2]bce0f8fcfeff3fbf[2]00[c]18ff[2]8a00[c]18ff[2]8bff[2]00[16]ff[2]00[6]2b3a2a3a2d3d1f152b3a2a3a2d3d1f15c068[2]1ce0[4]c068[2]1ce0[4]2a3d070f667038002a3d070f66703800e060[3]70787c00e060[3]70787c0009[10]f0[5]50[3]f0[5]50[3]2959[2]89b9[4]2959[2]89b9[4]fcf4f6[2]f1f7[3]fcf4f6[2]f1f7[3]555289b9b800[3]555289b9b800[3]eacb91971700[3]eacb91971700[3]7c7f[2]3f[3]00[2]fcfff17c7f[2]3f073efef8fcf0e000[2]3fffe71efc[2]f8e000[8]ba8abab8ff[2]1800[9]bb9bbb89ff[2]1800ff[2]00[6]ff[2]00[16]2a3e00[6]2a3e00[6]e0[2]c000c0e0f000e0[2]c000c0e0f0002a3e00281c206c102a3e00[6]f0[2]3000383c00[2]f0[2]3000383c00[3]071f3f7f[2]ff[2]00071f3f7f[2]ff[2]00e0f89c8ec6e7[2]00e0f89c8ec6e7[2]00[2]092e4f33f1fc00[2]092e4f33f1fc00[3]2080e4f07400[3]2080e4f07400121a6b5f3ff93600121a6b5f3ff936004094eafffe9f6c004094eafffe9f6c00[3]031ffcff0300[3]031ffcff0308[2]7cfe8301ff5108[2]7cfe8301ff51030607[2]047b94d5030607[2]047b94d58040[2]c040bc525a8040[2]c040bc525a0c1f13[2]3f4cd0df0c1f13[2]3f4cd0df60f098[2]f46e9fff60f098[2]f46e9fff18243c7e5a3c[2]6600[b]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f3ffdfe3f800[10]ff[2]7f[2]3f1f0700ff[2]7f[2]3f1f0700ff[2]fe[2]fcf8e000ff[2]fe[2]fcf8e000f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b8402000f6793f4d0f160a00f6793f4d0f160a006e9ffefdf4e844006e9ffefdf4e8440003fffc1f0300[3]03fffc1f0300[3]51ff0183fe7c08[2]51ff0183fe7c08[2]f47b040704070300f47b0407040703005ebc40c040[2]80005ebc40c040[2]8000df7f3f130c00[3]df7f3f130c00[3]fffefcc83000[3]fffefcc83000[3]01070d3f7fd97f3f01070d3f7fd97f3f80e0b0fcfe9bfefc80e0b0fcfe9bfefc00[20]071f3f7f[2]ff[3]071f3f7f[2]ff[3]e0f8fc9e8ec7e7[2]e0f8fc9e8ec7e7[2]00[2]082e4f33f1fc00[2]082e4f33f1fc00[2]801088e2f07600[2]801088e2f07600022957ff7ff93600022957ff7ff936004858d6fafc9f6c004858d6fafc9f6c00[3]031ffcff0f00[3]031ffcff0b08[2]7cfe8331ff4508[2]7cfe8331ff4503040507047b94b503040507047b94b580c0[3]40bc525680c0[3]40bc5256060f19[2]2f76f9ff060f19[2]2f76f9ff30f8c8[2]fc320bfb30f8c8[2]fc320bfb01070d3f7fce7f3f01070d3f7fce7f3f80e0b0fcfe73fefc80e0b0fcfe73fefc00[20]ff[3]7f[2]3f1f07ff[3]7f[2]3f1f07ff[3]fe[2]fcf8e0ff[3]fe[2]fcf8e0f1c7797531190e00f1c7797531190e00d2e0e4f2b900a410d2e0e4f2b900a41076f97fbf2f17220076f97fbf2f1722006f9efcb2f06850006f9efcb2f06850000ffffc1f0300[3]0bfffc1f0300[3]45ff3183fe7c08[2]45ff3183fe7c08[2]f47b040704050300f47b0407040503005ebc40c040c080005ebc40c040c08000ff7f3f130c00[3]ff7f3f130c00[3]fbfefcc83000[3]fbfefcc83000[6]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f2fcdce2f800[a]0304050f0b1000[a]80c0[2]e0a01000[c]1f20489c00[c]f008247200[3]071f3f5f8f00[b]80e0f0e8c400[16]0f3800[e]f03c00[7]0f00[7]0f00[7]e000[7]e000[43]03050b1f1e00[3]100204000100[3]c0e0f0f878002000[2]0400[2]8000[8]10207098bff87000[9]10081c26ee3e1c00[9]de41c18347201f00[9]f6040682c408f000d0703f1f0f070300[9]2c38f0e0c08000[12]60c3c7cfff7f3f00[9]7eff[4]fefc001f3f2040[2]80ff001f3f2040[2]80ff00b078fc7c7838f000b078fc7c7838f000[41]1e1f0f070300[3]0100[2]080400[3]78f8f0e0c000[3]8000[5]2000[e3]070f1d3b3e3c0004080022044000[3]e0f0f8bc5c3c0008040200402000[e1]3c3a3d1f0f0700[3]040220100800[2]3c5c1cf8f0e000[3]20e000[2]020600[e3]071c30206040081000408000[2]0600[2]e0380c04060204080100[4]6000[e0]406020301c0700[2]01000200[3]50200206040c38e000[2]8000[3]0100080400[23e0]
+CHRMain=00[10]2f7fffddfb7b71212f7fffddfb7b7121bdff[2]f7ebddad04bdff[2]f7ebddad044cfeff3efffe9c084cfeff3efffe9c0801[2]02[2]05[2]090800[8]80[2]c0[2]e0[2]f01000[8]09[8]00[8]f0[5]50[3]00[8]09[5]19[2]2900[8]10f0b030b018f8fc00[8]2959[2]89b9[4]00[8]fcf4f6[2]f1f7[3]00[8]b9[3]f9a9[2]f4f500[8]f7[2]fff5[3]6fef00[8]555289b9b8[4]00[8]eacb919717[4]00[9]3c464a52623c00[a]182808[3]3e00[a]3c42023c407e00[a]3c420c02423c00[a]081828487e0800[a]7e407c02423c00[a]3e407c42[2]3c00[a]3e02040810[2]00[a]3c423c42[2]3c00[a]3c42[2]3e023c00[9]3c4299a1[2]99423c00[9]3c42[2]7e42[2]00[a]7c427c42[2]3c00[a]3c4240[2]423c00[a]7c42[4]7c00[a]7c407040[2]7c00[a]3c40[2]7040[2]00[a]3c42404e423c00[a]42[3]7e42[2]00[a]3e08[4]3e00[a]02[3]42[2]3c00[a]44487048444200[a]40[5]7e00[a]42665a42[3]00[a]4262524a464200[a]3c42[4]3c00[a]7c42[2]7c40[2]00[a]3c42[3]3c0600[a]3c42[2]7c444200[a]3e403c02[2]7c00[a]3e08[5]00[a]42[5]3c00[a]22[4]140800[a]42[3]5a664200[a]422418[2]244200[a]41221408[3]00[a]7e040810207e00[9]18243c7e5a3c[2]6600[10]0810[2]20e0c000[2]30d0f0[6]30d0f0[7]fefffcfeff[3]f0fefffcfeff[3]00[a]01030206[2]0c00[8]0fffbf3f7f[2]ff[2]4f50607f00[4]4f50607f00[4]ff00[2]ff00[4]ff00[2]ff00[4]f90503ff00[4]f90503ff00[4]30ff[3]f0207f[2]30ff[3]f0207f[2]8f80407f00[4]8f80407f00[4]ff[8]00[8]ff[4]00[14]077f4f8f[5]00[8]ff[8]00[2]c06030188cc400[2]c06030188cc400[8]f8fce6[2]e7[4]00[8]071f3f5f9f[4]00[8]ff[6]fe[2]00[8]f8c6c182[2]04[2]0800[8]3f7fffdf9f[4]860488f800[4]860488f800[c]fe[2]c1a190fffcd800[8]e0f0b89c[2]8c[3]0c0919[2]3b33276f0c0919[2]3b33276fff[10]fcfbf8f0f1e1[2]c3fcfbf8f0f1e1[2]c300[4]ff[4]00[8]9fa0c0ff00[4]9fa0c0ff00[c]8f[2]cf77340f00[a]ff[5]7fbf00[9]ff[4]fe[2]fd00[9]e7f7fe1e3cf800[a]9f[5]bfff7f00[8]fe[2]c1a190fffcdf00[8]0810[2]20e0c0fc0200[8]9f[5]a0ff4000[8]ff0f[3]ff00ff00[9]ff[5]00ff00[9]8c[4]ccf8[3]fcf8c06030188cc4fcf8c06030188cc44f48f0ff00[4]4f48f0ff00[4]e6160cf800[4]e6160cf800[c]f1[5]f9fdff00[8]f8f6f1[6]00ff[3]00[2]ff[2]00ff[3]00[2]ff[2]7fbf5f9f[5]7fbf5f9f[5]fefdfaf9[5]fefdfaf9[5]00[8]0d191b3337674fff807fff[3]bf9f[2]807fff[3]bf9f[2]3fdff0ff[4]f03fdff0ff[4]f0e4fa0cfafcfafc0ee4fa0cfafcfafc0e78bf5f9f[5]78bf5f9f[5]fefdfbfdf9[4]fefdfbfdf9[4]7ffffc00[5]7ffffc00[5]f1c00103[2]06[2]0cf1c00103[2]06[2]0cf3ff[2]fcfeff[3]f3ff[2]fcfeff[3]1f7f9f[6]1f7f9f[6]ff0100ff00[4]ff0100ff00[c]ff[4]0f[3]ff01fdfefd1e0dfefb01fdfefd1e0dfefb3f2f4f[6]3f2f4f[6]9f3fff[6]9f3fff[6]f9[10]00[8]ff[5]fe[2]ff9f[10]00[90]0c1c1838300060[2]00[8]ffe7d7f7[3]c1ff00[8]ffc3bdfdc3bf81ff00[178]ff83bd[2]83bf[2]ff00[48]ffbd[5]c3ff00[609]03071617[2]33300003071617[2]333000c000[4]e000[2]c000f070[2]e0002b3f01[2]03[3]002b3f01[2]03[3]00e0[2]d0a030b8fc00e0[2]d0a030b8fc0001[2]02[2]05[2]090801[2]02[2]05[2]090880[2]c0[2]e0[2]f01080[2]c0[2]e0[2]f01009[5]19[2]2909[5]19[2]2910f0b030b018f8fc10f0b030b018f8fcb9[3]f9a9[2]f4f5b9[3]f9a9[2]f4f5f7[2]fff5[3]6feff7[2]fff5[3]6fef00[2]3c3f7f7c7d[2]071f3f7ffffcfd[2]00[3]e0f038[2]bce0f8fcfeff3fbf[2]00[c]18ff[2]8a00[c]18ff[2]8bff[2]00[16]ff[2]00[6]2b3a2a3a2d3d1f152b3a2a3a2d3d1f15c068[2]1ce0[4]c068[2]1ce0[4]2a3d070f667038002a3d070f66703800e060[3]70787c00e060[3]70787c0009[10]f0[5]50[3]f0[5]50[3]2959[2]89b9[4]2959[2]89b9[4]fcf4f6[2]f1f7[3]fcf4f6[2]f1f7[3]555289b9b800[3]555289b9b800[3]eacb91971700[3]eacb91971700[3]7c7f[2]3f[3]00[2]fcfff17c7f[2]3f073efef8fcf0e000[2]3fffe71efc[2]f8e000[8]ba8abab8ff[2]1800[9]bb9bbb89ff[2]1800ff[2]00[6]ff[2]00[16]2a3e00[6]2a3e00[6]e0[2]c000c0e0f000e0[2]c000c0e0f0002a3e00281c206c102a3e00[6]f0[2]3000383c00[2]f0[2]3000383c00[3]071f3f7f[2]ff[2]00071f3f7f[2]ff[2]00e0f89c8ec6e7[2]00e0f89c8ec6e7[2]00[2]092e4f33f1fc00[2]092e4f33f1fc00[3]2080e4f07400[3]2080e4f07400121a6b5f3ff93600121a6b5f3ff936004094eafffe9f6c004094eafffe9f6c00[3]031ffcff0300[3]031ffcff0308[2]7cfe8301ff5108[2]7cfe8301ff51030607[2]047b94d5030607[2]047b94d58040[2]c040bc525a8040[2]c040bc525a0c1f13[2]3f4cd0df0c1f13[2]3f4cd0df60f098[2]f46e9fff60f098[2]f46e9fff18243c7e5a3c[2]6600[b]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f3ffdfe3f800[10]ff[2]7f[2]3f1f0700ff[2]7f[2]3f1f0700ff[2]fe[2]fcf8e000ff[2]fe[2]fcf8e000f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b8402000f6793f4d0f160a00f6793f4d0f160a006e9ffefdf4e844006e9ffefdf4e8440003fffc1f0300[3]03fffc1f0300[3]51ff0183fe7c08[2]51ff0183fe7c08[2]f47b040704070300f47b0407040703005ebc40c040[2]80005ebc40c040[2]8000df7f3f130c00[3]df7f3f130c00[3]fffefcc83000[3]fffefcc83000[3]01070d3f7fd97f3f01070d3f7fd97f3f80e0b0fcfe9bfefc80e0b0fcfe9bfefc555289b9b858a850555289b9b800[3]eacb9197171a150aeacb91971700[3]071f3f7f[2]ff[3]071f3f7f[2]ff[3]e0f8fc9e8ec7e7[2]e0f8fc9e8ec7e7[2]00[2]082e4f33f1fc00[2]082e4f33f1fc00[2]801088e2f07600[2]801088e2f07600022957ff7ff93600022957ff7ff936004858d6fafc9f6c004858d6fafc9f6c00[3]031ffcff0f00[3]031ffcff0b08[2]7cfe8331ff4508[2]7cfe8331ff4503040507047b94b503040507047b94b580c0[3]40bc525680c0[3]40bc5256060f19[2]2f76f9ff060f19[2]2f76f9ff30f8c8[2]fc320bfb30f8c8[2]fc320bfb01070d3f7fce7f3f01070d3f7fce7f3f80e0b0fcfe73fefc80e0b0fcfe73fefc00[20]ff[3]7f[2]3f1f07ff[3]7f[2]3f1f07ff[3]fe[2]fcf8e0ff[3]fe[2]fcf8e0f1c7797531190e00f1c7797531190e00d2e0e4f2b900a410d2e0e4f2b900a41076f97fbf2f17220076f97fbf2f1722006f9efcb2f06850006f9efcb2f06850000ffffc1f0300[3]0bfffc1f0300[3]45ff3183fe7c08[2]45ff3183fe7c08[2]f47b040704050300f47b0407040503005ebc40c040c080005ebc40c040c08000ff7f3f130c00[3]ff7f3f130c00[3]fbfefcc83000[3]fbfefcc83000[6]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f2fcdce2f800[a]0304050f0b1000[a]80c0[2]e0a01000[c]1f20489c00[c]f008247200[3]071f3f5f8f00[b]80e0f0e8c400[16]0f3800[e]f03c00[7]0f00[7]0f00[7]e000[7]e000[43]03050b1f1e00[3]100204000100[3]c0e0f0f878002000[2]0400[2]8000[8]10207098bff87000[9]10081c26ee3e1c00[9]de41c18347201f00[9]f6040682c408f000d0703f1f0f070300[9]2c38f0e0c08000[12]60c3c7cfff7f3f00[9]7eff[4]fefc001f3f2040[2]80ff001f3f2040[2]80ff00b078fc7c7838f000b078fc7c7838f000[41]1e1f0f070300[3]0100[2]080400[3]78f8f0e0c000[3]8000[5]2000[e3]070f1d3b3e3c0004080022044000[3]e0f0f8bc5c3c0008040200402000[e1]3c3a3d1f0f0700[3]040220100800[2]3c5c1cf8f0e000[3]20e000[2]020600[e3]071c30206040081000408000[2]0600[2]e0380c04060204080100[4]6000[e0]406020301c0700[2]01000200[3]50200206040c38e000[2]8000[3]0100080400[23e0]
-CHRUndo=00[10]2f7fffddfb7b71212f7fffddfb7b7121bdff[2]f7ebddad04bdff[2]f7ebddad044cfeff3efffe9c084cfeff3efffe9c0801[2]02[2]05[2]090800[8]80[2]c0[2]e0[2]f01000[8]09[8]00[8]f0[5]50[3]00[8]09[5]19[2]2900[8]10f0b030b018f8fc00[8]2959[2]89b9[4]00[8]fcf4f6[2]f1f7[3]00[8]b9[3]f9a9[2]f4f500[8]f7[2]fff5[3]6fef00[8]555289b9b8[4]00[8]eacb919717[4]00[9]3c464a52623c00[a]182808[3]3e00[a]3c42023c407e00[a]3c420c02423c00[a]081828487e0800[a]7e407c02423c00[a]3e407c42[2]3c00[a]3e02040810[2]00[a]3c423c42[2]3c00[a]3c42[2]3e023c00[9]3c4299a1[2]99423c00[9]3c42[2]7e42[2]00[a]7c427c42[2]3c00[a]3c4240[2]423c00[a]7c42[4]7c00[a]7c407040[2]7c00[a]3c40[2]7040[2]00[a]3c42404e423c00[a]42[3]7e42[2]00[a]3e08[4]3e00[a]02[3]42[2]3c00[a]44487048444200[a]40[5]7e00[a]42665a42[3]00[a]4262524a464200[a]3c42[4]3c00[a]7c42[2]7c40[2]00[a]3c42[3]3c0600[a]3c42[2]7c444200[a]3e403c02[2]7c00[a]3e08[5]00[a]42[5]3c00[a]22[4]140800[a]42[3]5a664200[a]422418[2]244200[a]41221408[3]00[a]7e040810207e00[9]18243c7e5a3c[2]6600[10]0810[2]20e0c000[2]30d0f0[6]30d0f0[7]fefffcfeff[3]f0fefffcfeff[3]00[a]01030206[2]0c00[8]0fffbf3f7f[2]ff[2]4f50607f00[4]4f50607f00[4]ff00[2]ff00[4]ff00[2]ff00[4]f90503ff00[4]f90503ff00[4]30ff[3]f0207f[2]30ff[3]f0207f[2]8f80407f00[4]8f80407f00[4]ff[8]00[8]ff[4]00[14]077f4f8f[5]00[8]ff[8]00[2]c06030188cc400[2]c06030188cc400[8]f8fce6[2]e7[4]00[8]071f3f5f9f[4]00[8]ff[6]fe[2]00[8]f8c6c182[2]04[2]0800[8]3f7fffdf9f[4]860488f800[4]860488f800[c]fe[2]c1a190fffcd800[8]e0f0b89c[2]8c[3]0c0919[2]3b33276f0c0919[2]3b33276fff[10]fcfbf8f0f1e1[2]c3fcfbf8f0f1e1[2]c300[4]ff[4]00[8]9fa0c0ff00[4]9fa0c0ff00[c]8f[2]cf77340f00[a]ff[5]7fbf00[9]ff[4]fe[2]fd00[9]e7f7fe1e3cf800[a]9f[5]bfff7f00[8]fe[2]c1a190fffcdf00[8]0810[2]20e0c0fc0200[8]9f[5]a0ff4000[8]ff0f[3]ff00ff00[9]ff[5]00ff00[9]8c[4]ccf8[3]fcf8c06030188cc4fcf8c06030188cc44f48f0ff00[4]4f48f0ff00[4]e6160cf800[4]e6160cf800[c]f1[5]f9fdff00[8]f8f6f1[6]00ff[3]00[2]ff[2]00ff[3]00[2]ff[2]7fbf5f9f[5]7fbf5f9f[5]fefdfaf9[5]fefdfaf9[5]00[8]0d191b3337674fff807fff[3]bf9f[2]807fff[3]bf9f[2]3fdff0ff[4]f03fdff0ff[4]f0e4fa0cfafcfafc0ee4fa0cfafcfafc0e78bf5f9f[5]78bf5f9f[5]fefdfbfdf9[4]fefdfbfdf9[4]7ffffc00[5]7ffffc00[5]f1c00103[2]06[2]0cf1c00103[2]06[2]0cf3ff[2]fcfeff[3]f3ff[2]fcfeff[3]1f7f9f[6]1f7f9f[6]ff0100ff00[4]ff0100ff00[c]ff[4]0f[3]ff01fdfefd1e0dfefb01fdfefd1e0dfefb3f2f4f[6]3f2f4f[6]9f3fff[6]9f3fff[6]f9[10]00[8]ff[5]fe[2]ff9f[10]00[90]0c1c1838300070[2]00[8]ffe7d7f7[3]c1ff00[8]ffc3bdfdc3bf81ff00[178]ff83bd[2]83bf[2]ff00[48]ffbd[5]c3ff00[609]03071617[2]33300003071617[2]333000c000[4]e000[2]c000f070[2]e0002b3f01[2]03[3]002b3f01[2]03[3]00e0[2]d0a030b8fc00e0[2]d0a030b8fc0001[2]02[2]05[2]090801[2]02[2]05[2]090880[2]c0[2]e0[2]f01080[2]c0[2]e0[2]f01009[5]19[2]2909[5]19[2]2910f0b030b018f8fc10f0b030b018f8fcb9[3]f9a9[2]f4f5b9[3]f9a9[2]f4f5f7[2]fff5[3]6feff7[2]fff5[3]6fef00[2]3c3f7f7c7d[2]071f3f7ffffcfd[2]00[3]e0f038[2]bce0f8fcfeff3fbf[2]00[c]18ff[2]8a00[c]18ff[2]8bff[2]00[16]ff[2]00[6]2b3a2a3a2d3d1f152b3a2a3a2d3d1f15c068[2]1ce0[4]c068[2]1ce0[4]2a3d070f667038002a3d070f66703800e060[3]70787c00e060[3]70787c0009[10]f0[5]50[3]f0[5]50[3]2959[2]89b9[4]2959[2]89b9[4]fcf4f6[2]f1f7[3]fcf4f6[2]f1f7[3]555289b9b800[3]555289b9b800[3]eacb91971700[3]eacb91971700[3]7c7f[2]3f[3]00[2]fcfff17c7f[2]3f073efef8fcf0e000[2]3fffe71efc[2]f8e000[8]ba8abab8ff[2]1800[9]bb9bbb89ff[2]1800ff[2]00[6]ff[2]00[16]2a3e00[6]2a3e00[6]e0[2]c000c0e0f000e0[2]c000c0e0f0002a3e00281c206c102a3e00[6]f0[2]3000383c00[2]f0[2]3000383c00[3]071f3f7f[2]ff[2]00071f3f7f[2]ff[2]00e0f89c8ec6e7[2]00e0f89c8ec6e7[2]00[2]092e4f33f1fc00[2]092e4f33f1fc00[3]2080e4f07400[3]2080e4f07400121a6b5f3ff93600121a6b5f3ff936004094eafffe9f6c004094eafffe9f6c00[3]031ffcff0300[3]031ffcff0308[2]7cfe8301ff5108[2]7cfe8301ff51030607[2]047b94d5030607[2]047b94d58040[2]c040bc525a8040[2]c040bc525a0c1f13[2]3f4cd0df0c1f13[2]3f4cd0df60f098[2]f46e9fff60f098[2]f46e9fff18243c7e5a3c[2]6600[b]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f3ffdfe3f800[10]ff[2]7f[2]3f1f0700ff[2]7f[2]3f1f0700ff[2]fe[2]fcf8e000ff[2]fe[2]fcf8e000f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b8402000f6793f4d0f160a00f6793f4d0f160a006e9ffefdf4e844006e9ffefdf4e8440003fffc1f0300[3]03fffc1f0300[3]51ff0183fe7c08[2]51ff0183fe7c08[2]f47b040704070300f47b0407040703005ebc40c040[2]80005ebc40c040[2]8000df7f3f130c00[3]df7f3f130c00[3]fffefcc83000[3]fffefcc83000[3]01070d3f7fd97f3f01070d3f7fd97f3f80e0b0fcfe9bfefc80e0b0fcfe9bfefc00[20]071f3f7f[2]ff[3]071f3f7f[2]ff[3]e0f8fc9e8ec7e7[2]e0f8fc9e8ec7e7[2]00[2]082e4f33f1fc00[2]082e4f33f1fc00[2]801088e2f07600[2]801088e2f07600022957ff7ff93600022957ff7ff936004858d6fafc9f6c004858d6fafc9f6c00[3]031ffcff0f00[3]031ffcff0b08[2]7cfe8331ff4508[2]7cfe8331ff4503040507047b94b503040507047b94b580c0[3]40bc525680c0[3]40bc5256060f19[2]2f76f9ff060f19[2]2f76f9ff30f8c8[2]fc320bfb30f8c8[2]fc320bfb01070d3f7fce7f3f01070d3f7fce7f3f80e0b0fcfe73fefc80e0b0fcfe73fefc00[20]ff[3]7f[2]3f1f07ff[3]7f[2]3f1f07ff[3]fe[2]fcf8e0ff[3]fe[2]fcf8e0f1c7797531190e00f1c7797531190e00d2e0e4f2b900a410d2e0e4f2b900a41076f97fbf2f17220076f97fbf2f1722006f9efcb2f06850006f9efcb2f06850000ffffc1f0300[3]0bfffc1f0300[3]45ff3183fe7c08[2]45ff3183fe7c08[2]f47b040704050300f47b0407040503005ebc40c040c080005ebc40c040c08000ff7f3f130c00[3]ff7f3f130c00[3]fbfefcc83000[3]fbfefcc83000[6]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f2fcdce2f800[a]0304050f0b1000[a]80c0[2]e0a01000[c]1f20489c00[c]f008247200[3]071f3f5f8f00[b]80e0f0e8c400[16]0f3800[e]f03c00[7]0f00[7]0f00[7]e000[7]e000[43]03050b1f1e00[3]100204000100[3]c0e0f0f878002000[2]0400[2]8000[8]10207098bff87000[9]10081c26ee3e1c00[9]de41c18347201f00[9]f6040682c408f000d0703f1f0f070300[9]2c38f0e0c08000[12]60c3c7cfff7f3f00[9]7eff[4]fefc001f3f2040[2]80ff001f3f2040[2]80ff00b078fc7c7838f000b078fc7c7838f000[41]1e1f0f070300[3]0100[2]080400[3]78f8f0e0c000[3]8000[5]2000[e3]070f1d3b3e3c0004080022044000[3]e0f0f8bc5c3c0008040200402000[e1]3c3a3d1f0f0700[3]040220100800[2]3c5c1cf8f0e000[3]20e000[2]020600[e3]071c30206040081000408000[2]0600[2]e0380c04060204080100[4]6000[e0]406020301c0700[2]01000200[3]50200206040c38e000[2]8000[3]0100080400[23e0]
+CHRUndo=00[10]2f7fffddfb7b71212f7fffddfb7b7121bdff[2]f7ebddad04bdff[2]f7ebddad044cfeff3efffe9c084cfeff3efffe9c0801[2]02[2]05[2]090800[8]80[2]c0[2]e0[2]f01000[8]09[8]00[8]f0[5]50[3]00[8]09[5]19[2]2900[8]10f0b030b018f8fc00[8]2959[2]89b9[4]00[8]fcf4f6[2]f1f7[3]00[8]b9[3]f9a9[2]f4f500[8]f7[2]fff5[3]6fef00[8]555289b9b8[4]00[8]eacb919717[4]00[9]3c464a52623c00[a]182808[3]3e00[a]3c42023c407e00[a]3c420c02423c00[a]081828487e0800[a]7e407c02423c00[a]3e407c42[2]3c00[a]3e02040810[2]00[a]3c423c42[2]3c00[a]3c42[2]3e023c00[9]3c4299a1[2]99423c00[9]3c42[2]7e42[2]00[a]7c427c42[2]3c00[a]3c4240[2]423c00[a]7c42[4]7c00[a]7c407040[2]7c00[a]3c40[2]7040[2]00[a]3c42404e423c00[a]42[3]7e42[2]00[a]3e08[4]3e00[a]02[3]42[2]3c00[a]44487048444200[a]40[5]7e00[a]42665a42[3]00[a]4262524a464200[a]3c42[4]3c00[a]7c42[2]7c40[2]00[a]3c42[3]3c0600[a]3c42[2]7c444200[a]3e403c02[2]7c00[a]3e08[5]00[a]42[5]3c00[a]22[4]140800[a]42[3]5a664200[a]422418[2]244200[a]41221408[3]00[a]7e040810207e00[9]18243c7e5a3c[2]6600[10]0810[2]20e0c000[2]30d0f0[6]30d0f0[7]fefffcfeff[3]f0fefffcfeff[3]00[a]01030206[2]0c00[8]0fffbf3f7f[2]ff[2]4f50607f00[4]4f50607f00[4]ff00[2]ff00[4]ff00[2]ff00[4]f90503ff00[4]f90503ff00[4]30ff[3]f0207f[2]30ff[3]f0207f[2]8f80407f00[4]8f80407f00[4]ff[8]00[8]ff[4]00[14]077f4f8f[5]00[8]ff[8]00[2]c06030188cc400[2]c06030188cc400[8]f8fce6[2]e7[4]00[8]071f3f5f9f[4]00[8]ff[6]fe[2]00[8]f8c6c182[2]04[2]0800[8]3f7fffdf9f[4]860488f800[4]860488f800[c]fe[2]c1a190fffcd800[8]e0f0b89c[2]8c[3]0c0919[2]3b33276f0c0919[2]3b33276fff[10]fcfbf8f0f1e1[2]c3fcfbf8f0f1e1[2]c300[4]ff[4]00[8]9fa0c0ff00[4]9fa0c0ff00[c]8f[2]cf77340f00[a]ff[5]7fbf00[9]ff[4]fe[2]fd00[9]e7f7fe1e3cf800[a]9f[5]bfff7f00[8]fe[2]c1a190fffcdf00[8]0810[2]20e0c0fc0200[8]9f[5]a0ff4000[8]ff0f[3]ff00ff00[9]ff[5]00ff00[9]8c[4]ccf8[3]fcf8c06030188cc4fcf8c06030188cc44f48f0ff00[4]4f48f0ff00[4]e6160cf800[4]e6160cf800[c]f1[5]f9fdff00[8]f8f6f1[6]00ff[3]00[2]ff[2]00ff[3]00[2]ff[2]7fbf5f9f[5]7fbf5f9f[5]fefdfaf9[5]fefdfaf9[5]00[8]0d191b3337674fff807fff[3]bf9f[2]807fff[3]bf9f[2]3fdff0ff[4]f03fdff0ff[4]f0e4fa0cfafcfafc0ee4fa0cfafcfafc0e78bf5f9f[5]78bf5f9f[5]fefdfbfdf9[4]fefdfbfdf9[4]7ffffc00[5]7ffffc00[5]f1c00103[2]06[2]0cf1c00103[2]06[2]0cf3ff[2]fcfeff[3]f3ff[2]fcfeff[3]1f7f9f[6]1f7f9f[6]ff0100ff00[4]ff0100ff00[c]ff[4]0f[3]ff01fdfefd1e0dfefb01fdfefd1e0dfefb3f2f4f[6]3f2f4f[6]9f3fff[6]9f3fff[6]f9[10]00[8]ff[5]fe[2]ff9f[10]00[90]0c1c1838300060[2]00[8]ffe7d7f7[3]c1ff00[8]ffc3bdfdc3bf81ff00[178]ff83bd[2]83bf[2]ff00[48]ffbd[5]c3ff00[609]03071617[2]33300003071617[2]333000c000[4]e000[2]c000f070[2]e0002b3f01[2]03[3]002b3f01[2]03[3]00e0[2]d0a030b8fc00e0[2]d0a030b8fc0001[2]02[2]05[2]090801[2]02[2]05[2]090880[2]c0[2]e0[2]f01080[2]c0[2]e0[2]f01009[5]19[2]2909[5]19[2]2910f0b030b018f8fc10f0b030b018f8fcb9[3]f9a9[2]f4f5b9[3]f9a9[2]f4f5f7[2]fff5[3]6feff7[2]fff5[3]6fef00[2]3c3f7f7c7d[2]071f3f7ffffcfd[2]00[3]e0f038[2]bce0f8fcfeff3fbf[2]00[c]18ff[2]8a00[c]18ff[2]8bff[2]00[16]ff[2]00[6]2b3a2a3a2d3d1f152b3a2a3a2d3d1f15c068[2]1ce0[4]c068[2]1ce0[4]2a3d070f667038002a3d070f66703800e060[3]70787c00e060[3]70787c0009[10]f0[5]50[3]f0[5]50[3]2959[2]89b9[4]2959[2]89b9[4]fcf4f6[2]f1f7[3]fcf4f6[2]f1f7[3]555289b9b800[3]555289b9b800[3]eacb91971700[3]eacb91971700[3]7c7f[2]3f[3]00[2]fcfff17c7f[2]3f073efef8fcf0e000[2]3fffe71efc[2]f8e000[8]ba8abab8ff[2]1800[9]bb9bbb89ff[2]1800ff[2]00[6]ff[2]00[16]2a3e00[6]2a3e00[6]e0[2]c000c0e0f000e0[2]c000c0e0f0002a3e00281c206c102a3e00[6]f0[2]3000383c00[2]f0[2]3000383c00[3]071f3f7f[2]ff[2]00071f3f7f[2]ff[2]00e0f89c8ec6e7[2]00e0f89c8ec6e7[2]00[2]092e4f33f1fc00[2]092e4f33f1fc00[3]2080e4f07400[3]2080e4f07400121a6b5f3ff93600121a6b5f3ff936004094eafffe9f6c004094eafffe9f6c00[3]031ffcff0300[3]031ffcff0308[2]7cfe8301ff5108[2]7cfe8301ff51030607[2]047b94d5030607[2]047b94d58040[2]c040bc525a8040[2]c040bc525a0c1f13[2]3f4cd0df0c1f13[2]3f4cd0df60f098[2]f46e9fff60f098[2]f46e9fff18243c7e5a3c[2]6600[b]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f3ffdfe3f800[10]ff[2]7f[2]3f1f0700ff[2]7f[2]3f1f0700ff[2]fe[2]fcf8e000ff[2]fe[2]fcf8e000f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b8402000f6793f4d0f160a00f6793f4d0f160a006e9ffefdf4e844006e9ffefdf4e8440003fffc1f0300[3]03fffc1f0300[3]51ff0183fe7c08[2]51ff0183fe7c08[2]f47b040704070300f47b0407040703005ebc40c040[2]80005ebc40c040[2]8000df7f3f130c00[3]df7f3f130c00[3]fffefcc83000[3]fffefcc83000[3]01070d3f7fd97f3f01070d3f7fd97f3f80e0b0fcfe9bfefc80e0b0fcfe9bfefc555289b9b858a850555289b9b800[3]eacb91971712150aeacb91971700[3]071f3f7f[2]ff[3]071f3f7f[2]ff[3]e0f8fc9e8ec7e7[2]e0f8fc9e8ec7e7[2]00[2]082e4f33f1fc00[2]082e4f33f1fc00[2]801088e2f07600[2]801088e2f07600022957ff7ff93600022957ff7ff936004858d6fafc9f6c004858d6fafc9f6c00[3]031ffcff0f00[3]031ffcff0b08[2]7cfe8331ff4508[2]7cfe8331ff4503040507047b94b503040507047b94b580c0[3]40bc525680c0[3]40bc5256060f19[2]2f76f9ff060f19[2]2f76f9ff30f8c8[2]fc320bfb30f8c8[2]fc320bfb01070d3f7fce7f3f01070d3f7fce7f3f80e0b0fcfe73fefc80e0b0fcfe73fefc00[20]ff[3]7f[2]3f1f07ff[3]7f[2]3f1f07ff[3]fe[2]fcf8e0ff[3]fe[2]fcf8e0f1c7797531190e00f1c7797531190e00d2e0e4f2b900a410d2e0e4f2b900a41076f97fbf2f17220076f97fbf2f1722006f9efcb2f06850006f9efcb2f06850000ffffc1f0300[3]0bfffc1f0300[3]45ff3183fe7c08[2]45ff3183fe7c08[2]f47b040704050300f47b0407040503005ebc40c040c080005ebc40c040c08000ff7f3f130c00[3]ff7f3f130c00[3]fbfefcc83000[3]fbfefcc83000[6]1f6ff7031f00[3]1f6ff7031f003ef8f3ffdfe3f8003ef8f2fcdce2f800[a]0304050f0b1000[a]80c0[2]e0a01000[c]1f20489c00[c]f008247200[3]071f3f5f8f00[b]80e0f0e8c400[16]0f3800[e]f03c00[7]0f00[7]0f00[7]e000[7]e000[43]03050b1f1e00[3]100204000100[3]c0e0f0f878002000[2]0400[2]8000[8]10207098bff87000[9]10081c26ee3e1c00[9]de41c18347201f00[9]f6040682c408f000d0703f1f0f070300[9]2c38f0e0c08000[12]60c3c7cfff7f3f00[9]7eff[4]fefc001f3f2040[2]80ff001f3f2040[2]80ff00b078fc7c7838f000b078fc7c7838f000[41]1e1f0f070300[3]0100[2]080400[3]78f8f0e0c000[3]8000[5]2000[e3]070f1d3b3e3c0004080022044000[3]e0f0f8bc5c3c0008040200402000[e1]3c3a3d1f0f0700[3]040220100800[2]3c5c1cf8f0e000[3]20e000[2]020600[e3]071c30206040081000408000[2]0600[2]e0380c04060204080100[4]6000[e0]406020301c0700[2]01000200[3]50200206040c38e000[2]8000[3]0100080400[23e0]
-CHRCopy=ff83bd[2]83bf[2]ff00[b]2080e4f07400[3]2080e4f074f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b84020009fa0c0ff00[4]9fa0c0ff00[4]f90503ff00[4]f90503ff00[4]807fff[3]bf9f[2]807fff[3]bf9f[2]30d0f0[6]30d0f0[6]00[10]9f[10]f0fefffcfeff[3]f0fefffcfeff[3]00[2]c06030188cc400[2]c06030188cc48f80407f00[4]8f80407f00[4]ff00[2]ff00[4]ff00[2]ff00[4]e6160cf800[4]e6160cf800[24]9fa0c0ff00[4]9fa0c0ff00[4]f90503ff00[4]f90503ff00[1c]4f48f0ff00[c]ff0100ff00[c]860488f800[c]9fa0c0ff00[c]f90503ff00[c]ff[8]00[8]fcfbf8f0f1e1[2]c300[8]1f7f9f[6]00[8]f9[8]00[8]9f[8]00[8]f0fefffcfeff[3]00[a]c06030188cc400[8]4f48f0ff00[c]ff0100ff00[c]860488f800[c]9fa0c0ff00[c]f90503ff00[c]8f80601f00[c]ff00[2]ff00[c]e4140cfc00[a]44aa00[6]993380[6]558880[6]991180[6]44aa00[6]881100[5]0145a800[6]88132040[2]80[2]00548a200040008000893300[6]44aa000200040008993300[6]558800[6]991114[4]10[2]44aa04[3]00[2]01881100[6]45a800[6]881304000201[2]00548a040002000100893300[5]2a44aa00[5]44993300[3cd0]
+CHRCopy=2a3e00281c206c102a3e00[9]2080e4f07400[3]2080e4f074f1c7797531190e00f1c7797531190e00d6e1e4f2b8402000d6e1e4f2b84020009fa0c0ff00[4]9fa0c0ff00[4]f90503ff00[4]f90503ff00[4]807fff[3]bf9f[2]807fff[3]bf9f[2]30d0f0[6]30d0f0[6]00[10]9f[10]f0fefffcfeff[3]f0fefffcfeff[3]00[2]c06030188cc400[2]c06030188cc48f80407f00[4]8f80407f00[4]ff00[2]ff00[4]ff00[2]ff00[4]e6160cf800[4]e6160cf800[24]9fa0c0ff00[4]9fa0c0ff00[4]f90503ff00[4]f90503ff00[1c]4f48f0ff00[c]ff0100ff00[c]860488f800[c]9fa0c0ff00[c]f90503ff00[c]ff[8]00[8]fcfbf8f0f1e1[2]c300[8]1f7f9f[6]00[8]f9[8]00[8]9f[8]00[8]f0fefffcfeff[3]00[a]c06030188cc400[8]4f48f0ff00[c]ff0100ff00[c]860488f800[c]9fa0c0ff00[c]f90503ff00[c]8f80601f00[c]ff00[2]ff00[c]e4140cfc00[a]44aa00[6]993380[6]558880[6]991180[6]44aa00[6]881100[5]0145a800[6]88132040[2]80[2]00548a200040008000893300[6]44aa000200040008993300[6]558800[6]991114[4]10[2]44aa04[3]00[2]01881100[6]45a800[6]881304000201[2]00548a040002000100893300[5]2a44aa00[5]44993300[3cd0]
NameTable=00[44]112f2a00[3]3500[4]222300[6]3500[2]122f2a00[11]7700[1e]2a1b2f2d1f1e00[93]040500[10]0103[4]020300[7]060700[1e]080900[4]211b271f0029301f2c00[e]0103[4]020300[27]0a0b00[1e]0c0d00[1c]0103[2]020300[4b]aa00[1f]ba00[15]040500[1e]060700[1e]080900[1e]0a0b00[1e]0c0d00[1e]0e0f00[9]0103[1e]0200[c4]112f4000[8]222300[9]122f4000[43]36[20]26[21]27[1e]26[2]00[1e]26[2]00[2]2829[2]250044452a002829[2]25002b29[2]4c535029610044452a00[2]26[2]00[2]383934350054553a0038393435003b3c3d5c657570600054325800[2]26[2]00[3]636400[2]66676800[2]636400[2]696a6b6c3e62[2]7100665900[3]26[2]00[2]72737400[2]766d5d00[2]767400[2]7674004d4e4f6e740076522400[2]26[2]00[2]51565700[2]3f565f00[2]375700[2]3757005e6f313757003f565f00[2]26[2]00[1e]26[41]00[8a]110040481b2c1f4600211b491f00[53]120040481b2c1f4600211b491f00[a9]
@@ -331,14 +331,14 @@ MetatileSet_8x8_props=00[2000]
MetatileSet_8x8_propsUndo=00[2000]
-MetatileSetLabels_2x2=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-MetatileSetLabels_2x2Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+MetatileSetLabels_2x2=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+MetatileSetLabels_2x2Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-MetatileSetLabels_4x4=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-MetatileSetLabels_4x4Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+MetatileSetLabels_4x4=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+MetatileSetLabels_4x4Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-MetatileSetLabels_8x8=Unlabeled,Unlabeled
-MetatileSetLabels_8x8Undo=Unlabeled,Unlabeled
+MetatileSetLabels_8x8=Unlabeled,Unlabeled
+MetatileSetLabels_8x8Undo=Unlabeled,Unlabeled
CHRBankLabels=Unlabeled,Unlabeled,Unlabeled,Unlabeled
@@ -503,18 +503,18 @@ Checkpoint_MetatileSet_8x8_props=00[2000]
Checkpoint_MetatileSet_8x8_propsUndo=00[2000]
-Checkpoint_MetatileSetLabels_2x2=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-Checkpoint_MetatileSetLabels_2x2Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_2x2=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_2x2Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-Checkpoint_MetatileSetLabels_4x4=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-Checkpoint_MetatileSetLabels_4x4Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_4x4=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_4x4Undo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-Checkpoint_MetatileSetLabels_8x8=Unlabeled,Unlabeled
-Checkpoint_MetatileSetLabels_8x8Undo=Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_8x8=Unlabeled,Unlabeled
+Checkpoint_MetatileSetLabels_8x8Undo=Unlabeled,Unlabeled
-Checkpoint_CHRBankLabels=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_CHRBankLabels=Unlabeled,Unlabeled,Unlabeled,Unlabeled
-Checkpoint_CHRBankLabelsUndo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
+Checkpoint_CHRBankLabelsUndo=Unlabeled,Unlabeled,Unlabeled,Unlabeled
Checkpoint_32_NTSC_MsprDuration=00000006[100]
diff --git a/src/background.s b/src/background.s
index 0facde6..369def9 100644
--- a/src/background.s
+++ b/src/background.s
@@ -107,4 +107,58 @@
;; End of the list.
.byte $FF
+
+ ;; Clear out the shuttle from the background.
+ ;;
+ ;; NOTE: this should only be called from NMI code.
+ .proc clear_shuttle
+ ;; The low part of the rocket.
+ bit PPU::m_status
+ ldx #$2B
+ stx PPU::m_address
+ ldx #$15
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ ;; High part of the rocket.
+ bit PPU::m_status
+ ldy #$2A
+ sty PPU::m_address
+ ldx #$75
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ bit PPU::m_status
+ sty PPU::m_address
+ ldx #$95
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ bit PPU::m_status
+ sty PPU::m_address
+ ldx #$B5
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ ;; Middle part of the rocket.
+ bit PPU::m_status
+ sty PPU::m_address
+ ldx #$D5
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ bit PPU::m_status
+ sty PPU::m_address
+ ldx #$F5
+ stx PPU::m_address
+ sta PPU::m_data
+ sta PPU::m_data
+
+ rts
+ .endproc
.endscope
diff --git a/src/driver.s b/src/driver.s
index ab63b5f..3372f9a 100644
--- a/src/driver.s
+++ b/src/driver.s
@@ -57,11 +57,14 @@
;; Bitmap of various boolean values lumped together.
;;
- ;; |SP-- ----|
+ ;; |SP-- -MDT|
;; |
- ;; |- S: whether sprites have already been moved out in the
+ ;; |- S: whether Sprites have already been moved out in the
;; | 'move_sprites_out' situation.
- ;; |- P: whether the pause message on the HUD has to be toggled.
+ ;; |- P: whether the Pause message on the HUD has to be toggled.
+ ;; |- M: the shuttle should Move. Only used coupled with T.
+ ;; |- D: the taking off animation should be moving downwards.
+ ;; |- T: the rocket is Taking off.
zp_flags = $38
;; Initialization routine that is to be called before enabling NMIs back for
@@ -171,6 +174,16 @@
.endproc
.proc update
+ ;; Are we in the shuttle transition?
+ lda Driver::zp_flags
+ and #$01
+ beq @check_player_timer
+
+ ;; Yes! Then just handle the shuttle animation and move into sprite
+ ;; cycling.
+ JAL Driver::handle_shuttle
+
+ @check_player_timer:
;; If the player timer is over, jump to the game immediately. Otherwise
;; decrement the counter.
lda zp_player_timer
@@ -301,8 +314,21 @@
;; over with the game screen.
lda Globals::zp_flags
and #$10
+ bne @player_got_toasted
+
+ ;; Nope, the player is just fine. Just an extra check: do we have all
+ ;; shuttle parts?
+ lda Items::zp_collected
+ cmp #9
+ bne @sprite_cycling
+
+ ;; Yes, we do! Then we check if the player is colliding with the shuttle
+ ;; platform. If so it's time to blast off
+ jsr Items::player_in_shuttle
beq @sprite_cycling
+ JAL Driver::init_take_off
+ @player_got_toasted:
;; Invalidate bullets and enemies if we haven't already.
bit Driver::zp_flags
bmi @check_explosions
@@ -338,25 +364,10 @@
;; Invalidate items, which were skipped on move_sprites_out() on purpose
;; to keep them after each death. But since we are about to go to the
;; title screen, now they are no longer useful.
- lda #$FF
- ldx #0
- ldy #Items::POOL_CAPACITY
- @items_reset_loop:
- sta Items::zp_pool_base, x
- NEXT_ITEM_INDEX_X
- dey
- bne @items_reset_loop
+ jsr Items::invalidate_all
@reset_timers:
- ;; Reset the player's timer to enter the game screen again.
- lda #PLAYER_TIMER_VALUE
- sta zp_player_timer
-
- ;; Restart the blinking animation.
- lda #BLINKING_TIME
- sta Driver::zp_blink_timer
- lda #$80
- sta Driver::zp_blink_status
+ jsr Driver::reset_timers
@sprite_cycling:
__fallthrough__ sprite_cycling
@@ -644,6 +655,258 @@
.endproc
.endif
+ ;; Reset all timers which are relevant for entering a new screen.
+ .proc reset_timers
+ ;; Reset the player's timer to enter the game screen again.
+ lda #PLAYER_TIMER_VALUE
+ sta zp_player_timer
+
+ ;; Restart the blinking animation.
+ lda #BLINKING_TIME
+ sta Driver::zp_blink_timer
+ lda #$80
+ sta Driver::zp_blink_status
+
+ rts
+ .endproc
+
+ ;; Initialize the "take off" animation. From this point forward the
+ ;; Drivers::update() function will no longer go through its normal route
+ ;; and it will just call Drivers::handle_shuttle().
+ ;;
+ ;; Hence, this function sets/unsets all the relevant flags, and sets
+ ;; 'OAM::m_sprites' to only contain the sprites for the animation. The 'ppu'
+ ;; and 'shuttle' flags will also be touched so any background elements from
+ ;; the shuttle are also cleared out.
+ .proc init_take_off
+ ;;;
+ ;; Manually create all 12 sprites that make up the shuttle in the take
+ ;; off animation. This is seemingly a lot of code, but it's just sprite
+ ;; initialization over and over.
+
+ ;; Y screen coordinates.
+ lda #Background::GROUND_Y_COORD - 48
+ sta OAM::m_sprites
+ sta OAM::m_sprites + 4
+
+ lda #Background::GROUND_Y_COORD - 40
+ sta OAM::m_sprites + 8
+ sta OAM::m_sprites + 12
+
+ lda #Background::GROUND_Y_COORD - 32
+ sta OAM::m_sprites + 16
+ sta OAM::m_sprites + 20
+
+ lda #Background::GROUND_Y_COORD - 24
+ sta OAM::m_sprites + 24
+ sta OAM::m_sprites + 28
+
+ lda #Background::GROUND_Y_COORD - 16
+ sta OAM::m_sprites + 32
+ sta OAM::m_sprites + 36
+
+ lda #Background::GROUND_Y_COORD - 8
+ sta OAM::m_sprites + 40
+ sta OAM::m_sprites + 44
+
+ ;; Tile IDs
+ lda #$04
+ sta OAM::m_sprites + 1
+ lda #$05
+ sta OAM::m_sprites + 5
+
+ lda #$14
+ sta OAM::m_sprites + 9
+ lda #$15
+ sta OAM::m_sprites + 13
+
+ lda #$06
+ sta OAM::m_sprites + 17
+ lda #$07
+ sta OAM::m_sprites + 21
+
+ lda #$16
+ sta OAM::m_sprites + 25
+ lda #$17
+ sta OAM::m_sprites + 29
+
+ lda #$08
+ sta OAM::m_sprites + 33
+ lda #$09
+ sta OAM::m_sprites + 37
+
+ lda #$42
+ sta OAM::m_sprites + 41
+ lda #$43
+ sta OAM::m_sprites + 45
+
+ ;; Zero out attributes
+ lda #0
+ sta OAM::m_sprites + 2
+ sta OAM::m_sprites + 6
+ sta OAM::m_sprites + 10
+ sta OAM::m_sprites + 14
+ sta OAM::m_sprites + 18
+ sta OAM::m_sprites + 22
+ sta OAM::m_sprites + 26
+ sta OAM::m_sprites + 30
+ sta OAM::m_sprites + 34
+ sta OAM::m_sprites + 38
+ sta OAM::m_sprites + 42
+ sta OAM::m_sprites + 46
+
+ ;; X screen coordinates.
+ lda #Items::DROPPING_SCREEN_X
+ sta OAM::m_sprites + 3
+ sta OAM::m_sprites + 11
+ sta OAM::m_sprites + 19
+ sta OAM::m_sprites + 27
+ sta OAM::m_sprites + 35
+ sta OAM::m_sprites + 43
+
+ lda #Items::DROPPING_SCREEN_X + 8
+ sta OAM::m_sprites + 7
+ sta OAM::m_sprites + 15
+ sta OAM::m_sprites + 23
+ sta OAM::m_sprites + 31
+ sta OAM::m_sprites + 39
+ sta OAM::m_sprites + 47
+
+ ;;;
+ ;; Clear out the rest of the sprites. Note that this is done manually
+ ;; and not via the rest of helper functions because it's faster and it
+ ;; touches 'OAM::m_sprites' directly.
+
+ ldx #(12 * 4) ; NOTE: 12 sprites from the shuttle.
+ lda #$FF
+ @clear_loop:
+ sta OAM::m_sprites, x
+ inx
+ inx
+ inx
+ inx
+ bne @clear_loop
+
+ ;;;
+ ;; Flags and stuff.
+
+ ;; Enable the 'T' flag. That is, we signal to the Driver::update()
+ ;; function that the "take off" animation is going on and it should call
+ ;; Driver::handle_shuttle() instead of going the regular route.
+ ;;
+ ;; NOTE: all other flags are cleared out on purpose as they are no
+ ;; longer relevant.
+ lda #1
+ sta Driver::zp_flags
+
+ ;; Force the shuttle to be removed from the background (see interrupt.s
+ ;; for the specific handling for this).
+ lda #0
+ sta Items::zp_collected
+
+ ;; Enable the 'ppu' and the 'shuttle' flags. This, coupled with the
+ ;; previous zeroing out of 'Items::zp_collected', makes the background
+ ;; shuttle disappear in favor of the animated meta-sprite.
+ lda Globals::zp_flags
+ ora #%01100000
+ sta Globals::zp_flags
+
+ rts
+ .endproc
+
+ ;; Handle the "take off" animation from the shuttle. That is, move it
+ ;; upwards/downwards depending on the 'D' bit, and check for "collisions" on
+ ;; certain spots where the animation should flip or be over.
+ .proc handle_shuttle
+ ;; Move the shuttle every other frame.
+ lda Driver::zp_flags
+ eor #$04
+ sta Driver::zp_flags
+ and #$04
+ beq @end
+
+ ;; Move all sprites from the shuttle up/down depending on the 'D' flag.
+ ldx #0
+ @loop:
+ ;; To always check whether the 'D' flag is set on each sprite is
+ ;; admittedly not the most performant thing to do. But it's easy and
+ ;; this function is literally the only thing that will be done
+ ;; computing-wise, so whatever...
+ lda Driver::zp_flags
+ and #$02
+ beq @up
+ inc OAM::m_sprites, x
+ jmp @next
+ @up:
+ dec OAM::m_sprites, x
+
+ @next:
+ ;; The rocket is made up of 12 sprites, and each one takes 4 bytes on
+ ;; OAM space.
+ inx
+ inx
+ inx
+ inx
+ cpx #(12 * 4)
+ bne @loop
+
+ ;; Is the shuttle at a limit when it should either flip the 'D' bit or
+ ;; declare the animation to be over?
+ lda Driver::zp_flags
+ and #$02
+ lsr
+ tax
+ lda limits, x
+ cmp OAM::m_sprites
+ bne @end
+
+ ;; Flip the 'D' bit. If doing so results on a zero bit, then we know we
+ ;; are back at the ground and hence we should stop the
+ ;; animation. Otherwise we should store the result so we move downwards
+ ;; next time.
+ lda Driver::zp_flags
+ eor #$02
+ tax
+ and #$02
+ bne @set
+
+ ;; The animation is over. Reset the flags to the expected 'S' one. Not
+ ;; that we care too much about it, but at least we will be consistent
+ ;; with player's death and other scenarios like that.
+ lda #$80
+ sta Driver::zp_flags
+
+ ;; Increase the level :)
+ inc Globals::zp_level
+ lda Globals::zp_level
+ and #%00000111
+ sta Globals::zp_level_kind
+
+ ;; Just like we did in Drivers::switch(), we re-initialize some things
+ ;; like timers and the items. Note that re-setting the timers will force
+ ;; the Drivers::update() function to re-initialize most things
+ ;; (e.g. enemies).
+ jsr Driver::reset_timers
+ jsr Items::init_level
+
+ ;; Enable the 'ppu' and the 'shuttle' flags, so the shuttle is back into
+ ;; the background.
+ lda Globals::zp_flags
+ ora #%01100000
+ sta Globals::zp_flags
+
+ rts
+
+ @set:
+ stx Driver::zp_flags
+
+ @end:
+ rts
+
+ limits:
+ .byte Background::UPPER_MARGIN_Y_COORD, Background::GROUND_Y_COORD - 48
+ .endproc
+
;; Toggle the "Paused" message from the (not quite) HUD.
;;
;; NOTE: only call this function from NMI code.
diff --git a/src/interrupts.s b/src/interrupts.s
index 2c78099..6c7e75b 100644
--- a/src/interrupts.s
+++ b/src/interrupts.s
@@ -103,8 +103,18 @@
tax
and #%00100000
beq @game_status
+
+ ;; Yes! Then, if there are no collected items, we just clear out the shuttle
+ ;; entirely (i.e. it's the shuttle take off animation), otherwise we go into
+ ;; the usual route.
+ lda Items::zp_collected
+ bne @do_update_shuttle
+ jsr Background::clear_shuttle
+ jmp @unset_shuttle_flag
+@do_update_shuttle:
jsr Items::update_shuttle
+@unset_shuttle_flag:
;; And unset the flag.
lda Globals::zp_flags
and #%11011111
diff --git a/src/items.s b/src/items.s
index de0a28e..947e96e 100644
--- a/src/items.s
+++ b/src/items.s
@@ -91,6 +91,10 @@
;; Coordinate where the dropping of items takes place.
DROPPING_SCREEN_X = $A8
+ ;; Coordinates where the player is allowed to enter into the shuttle to take
+ ;; off.
+ ENTER_SCREEN_Y = $A8
+
;; Y screen coordinates in order for various parts to be considered as
;; "collected".
MID_SHUTTLE_Y = $A7
@@ -866,6 +870,35 @@
rts
.endproc
+ ;; Sets 1 to the 'a' register if the player is "entering" the shuttle, 0
+ ;; otherwise.
+ ;;
+ ;; NOTE: this function does not check on whether that makes sense (e.g. is
+ ;; the player allowed to do it?). That's up to the caller to decide.
+ .proc player_in_shuttle
+ lda Items::zp_player_screen_x
+
+ cmp #DROPPING_SCREEN_X - 8
+ bcs @maybe
+ jmp @no
+ @maybe:
+ cmp #DROPPING_SCREEN_X + 8
+ bcc @check_vertical
+ jmp @no
+
+ @check_vertical:
+ lda Items::zp_player_screen_y
+ cmp #ENTER_SCREEN_Y
+ bcc @no
+
+ @yes:
+ lda #1
+ rts
+ @no:
+ lda #0
+ rts
+ .endproc
+
;; Let go the item from the player if there is one being grabbed.
.proc let_go_on_death
;; First of all, we need do check if the player was actually holding an
@@ -938,30 +971,28 @@
rts
.endproc
+ ;; Invalidate all items from the screen.
+ .proc invalidate_all
+ lda #$FF
+ ldx #0
+ ldy #Items::POOL_CAPACITY
+
+ @items_reset_loop:
+ sta Items::zp_pool_base, x
+
+ NEXT_ITEM_INDEX_X
+ dey
+ bne @items_reset_loop
+
+ rts
+ .endproc
+
;; Prepare the background scenary for items. Namely, the rocket parts which
;; belong to the background.
;;
;; NOTE: this has to be called with the PPU disabled.
.proc prepare_background_scene
- ;; The low part of the rocket.
- bit PPU::m_status
- lda #$2A
- sta PPU::m_address
- lda #$F5
- sta PPU::m_address
- ldx #$0C
- stx PPU::m_data
- inx
- stx PPU::m_data
-
- lda #$2B
- sta PPU::m_address
- lda #$15
- sta PPU::m_address
- inx
- stx PPU::m_data
- inx
- stx PPU::m_data
+ jsr draw_low_part_shuttle
lda Globals::zp_level_kind
beq @end
@@ -974,7 +1005,12 @@
rts
.endproc
- ;; Update the background scenary for the shuttle.
+ ;; Update the background scenery for the shuttle. This has to take into
+ ;; account not just the background elements, but also the attributes for
+ ;; each case to account for the fuel getting in. It also handles the basic
+ ;; case of having just the low part as we might come from a previous level
+ ;; which has "dirtied" out the attributes. All in all, the implementation is
+ ;; not the sexiest thing ever, but it gets the job done :)
;;
;; NOTE: this has to be called with the PPU disabled.
.proc update_shuttle
@@ -1001,7 +1037,7 @@
sta PPU::m_address
lda #%10101010
sta PPU::m_data
- bne @end
+ jmp @end
@half_high_middle:
lda Items::zp_collected
@@ -1014,7 +1050,7 @@
sta PPU::m_address
lda #%10100010
sta PPU::m_data
- bne @end
+ jmp @end
@low_middle:
lda Items::zp_collected
@@ -1053,15 +1089,51 @@
sta PPU::m_address
lda #%10101010
sta PPU::m_data
+ bne @end
@just_top:
cmp #3
bcc @just_middle
jsr draw_high_part_shuttle
+ ;; Set the attributes to the default one just in case we are switching
+ ;; from a previous level.
+ bit PPU::m_status
+ lda #$2B
+ sta PPU::m_address
+ lda #$E5
+ sta PPU::m_address
+ lda #0
+ sta PPU::m_data
+
@just_middle:
jsr draw_middle_part_shuttle
+ ;; Set the attributes to the default one just in case we are switching
+ ;; from a previous level.
+ bit PPU::m_status
+ lda #$2B
+ sta PPU::m_address
+ lda #$ED
+ sta PPU::m_address
+ lda #0
+ sta PPU::m_data
+
+ ;; NOTE: just in case we move into the next level and we need to
+ ;; reconstruct the low part of the shuttle after the "take off"
+ ;; animation cleared it away.
+ jsr draw_low_part_shuttle
+
+ ;; Set the attributes to the default one just in case we are switching
+ ;; from a previous level.
+ bit PPU::m_status
+ lda #$2B
+ sta PPU::m_address
+ lda #$F5
+ sta PPU::m_address
+ lda #0
+ sta PPU::m_data
+
@end:
rts
.endproc
@@ -1119,4 +1191,31 @@
rts
.endproc
+
+ ;; Update the background scenary to show the low part of the shuttle.
+ ;;
+ ;; NOTE: this has to be called with the PPU disabled.
+ .proc draw_low_part_shuttle
+ ;; The low part of the rocket.
+ bit PPU::m_status
+ lda #$2A
+ sta PPU::m_address
+ lda #$F5
+ sta PPU::m_address
+ ldx #$0C
+ stx PPU::m_data
+ inx
+ stx PPU::m_data
+
+ lda #$2B
+ sta PPU::m_address
+ lda #$15
+ sta PPU::m_address
+ inx
+ stx PPU::m_data
+ inx
+ stx PPU::m_data
+
+ rts
+ .endproc
.endscope
diff --git a/src/over.s b/src/over.s
index e5855e3..ab13d76 100644
--- a/src/over.s
+++ b/src/over.s
@@ -152,52 +152,8 @@
dex
bne @clear_ground_loop
- ;; The low part of the rocket.
- bit PPU::m_status
- ldx #$2B
- stx PPU::m_address
- ldx #$15
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
-
- ;; High part of the rocket.
- bit PPU::m_status
- ldy #$2A
- sty PPU::m_address
- ldx #$75
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
-
- bit PPU::m_status
- sty PPU::m_address
- ldx #$95
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
-
- bit PPU::m_status
- sty PPU::m_address
- ldx #$B5
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
-
- ;; Middle part of the rocket.
- bit PPU::m_status
- sty PPU::m_address
- ldx #$D5
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
-
- bit PPU::m_status
- sty PPU::m_address
- ldx #$F5
- stx PPU::m_address
- sta PPU::m_data
- sta PPU::m_data
+ ;; Clear the shuttle from the background.
+ jsr Background::clear_shuttle
rts
.endproc