diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..d22b58a --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +java -jar mdl.jar netherearth-annotated.asm -bin netherearth-annotated.bin -asm+:html netherearth-annotated.html -asm+:no-reindent -tap La600_start Nether netherearth-annotated.tap diff --git a/mdl.jar b/mdl.jar new file mode 100644 index 0000000..048fd07 Binary files /dev/null and b/mdl.jar differ diff --git a/netherearth-annotated-data.asm b/netherearth-annotated-data.asm new file mode 100644 index 0000000..f7826b1 --- /dev/null +++ b/netherearth-annotated-data.asm @@ -0,0 +1,1179 @@ +L6780_graphic_patterns: + ; Each block of 8 bytes correspods to a character. So, this includes + ; a definition of the font being used, the first character is ' ': + ; these tags inside comments are used to visualize the gfx using MDL with the "-mdl-asm+:html" flag. + db #00, #00, #00, #00, #00, #00, #00, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #18, #18, #18, #18, #00, #18, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #36, #6c, #00, #00, #00, #00, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #24, #7e, #24, #24, #7e, #24, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #18, #3e, #78, #3c, #1e, #1e, #7c, #18 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #66, #4c, #18, #32, #66, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #38, #44, #4c, #38, #6e, #46, #3b, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #18, #30, #00, #00, #00, #00, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #04, #0c, #18, #18, #18, #18, #0c, #04 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #20, #30, #18, #18, #18, #18, #30, #20 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #14, #08, #3e, #08, #14, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #08, #08, #3e, #08, #08, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #00, #00, #0c, #0c, #0c, #08 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #00, #00, #3e, #00, #00, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #00, #00, #00, #18, #18, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #06, #0c, #18, #30, #60, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #36, #77, #67, #6b, #73, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #0c, #3c, #1c, #1c, #1c, #1c, #1c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #3c, #76, #36, #04, #08, #7e, #7e, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #34, #76, #06, #04, #26, #76, #34, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #17, #17, #37, #77, #77, #07, #07, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #7f, #70, #66, #07, #37, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #16, #36, #70, #74, #76, #76, #34, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #7e, #7e, #02, #0c, #1c, #38, #78, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #36, #77, #77, #36, #77, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #36, #77, #77, #37, #07, #76, #34, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #18, #18, #00, #18, #18, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #18, #18, #00, #18, #18, #10 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #08, #18, #30, #60, #30, #18, #08 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #00, #3e, #00, #3e, #00, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #20, #30, #18, #0c, #18, #30, #20 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #2c, #6e, #6e, #0c, #00, #0c, #0c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #3e, #59, #45, #5d, #55, #5d, #3e, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #3e, #77, #77, #77, #7f, #77, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #76, #77, #76, #74, #76, #77, #76, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #17, #33, #71, #70, #71, #33, #17, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #74, #76, #77, #77, #77, #76, #74, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #71, #70, #76, #70, #71, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #71, #70, #76, #70, #70, #70, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #17, #33, #71, #70, #77, #37, #16, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #77, #77, #7f, #77, #77, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #1c, #1c, #1c, #1c, #1c, #1c, #1c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #07, #07, #07, #07, #37, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #76, #74, #70, #74, #76, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #70, #70, #70, #70, #71, #73, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #63, #77, #7f, #7f, #77, #77, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #67, #77, #7f, #7f, #7f, #77, #73, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #36, #77, #77, #77, #77, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #74, #76, #76, #76, #74, #70, #70, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #36, #77, #77, #77, #77, #7e, #37, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #74, #76, #76, #76, #74, #76, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #37, #79, #7c, #3e, #1f, #4f, #76, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #7f, #5d, #5d, #1c, #1c, #1c, #1c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #77, #77, #77, #77, #77, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #63, #63, #63, #63, #77, #3e, #1c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #6b, #6b, #6b, #6b, #77, #7f, #36, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #77, #36, #14, #36, #77, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #77, #36, #3e, #1c, #1c, #1c, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #77, #4f, #1f, #3e, #7c, #79, #77, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #0e, #0c, #0c, #0c, #0c, #0e, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #60, #30, #18, #0c, #06, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #70, #10, #10, #10, #10, #70, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #10, #38, #54, #10, #10, #10, #00 ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + db #00, #00, #00, #00, #00, #00, #00, #ff ; mdl-asm+:html:gfx(bitmap,pre,1,8,2) + +L6980_isometric_graphics: + ; These are definitions of the different isometric pieces (bipod, cannon, etc.) + ; The first two bytes of each graphic are: + ; - height (in pixels) + ; - width (in bytes) + ; The rest of the data shuold be height*width*2 bytes, where each pair of bytes + ; represents 8 pixels. The first is the "and mask", and the second the "or" mask, as + ; usual in ZX Spectrum graphics. + ; Graphics are stored upside down, since the game renders them starting at the bottom. +L6980_iso_graphic_0: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1b, #03, #ff, #00, #7f, #80, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #fc, #02 + db #07, #f8, #ff, #00, #fc, #02, #01, #be, #ff, #00, #f8, #05, #00, #9f, #7f, #80 + db #f8, #04, #00, #fb, #1f, #e0, #f8, #06, #00, #79, #07, #f8, #f8, #04, #00, #9f + db #01, #be, #f8, #04, #00, #a7, #00, #9f, #fc, #03, #00, #29, #00, #fb, #ef, #10 + db #00, #ca, #00, #79, #c3, #3c, #c0, #32, #00, #9f, #80, #5f, #f0, #0c, #00, #a7 + db #80, #57, #3c, #c3, #00, #29, #00, #b3, #0f, #f0, #01, #ca, #00, #9f, #03, #7c + db #c1, #32, #00, #cf, #00, #3f, #f3, #0c, #00, #93, #00, #f7, #3f, #c0, #00, #94 + db #00, #f3, #1f, #e0, #80, #65, #00, #3f, #1f, #60, #e0, #19, #00, #4f, #1f, #20 + db #f8, #06, #00, #53, #1f, #e0, #fe, #01, #00, #94, #1f, #e0, #ff, #00, #80, #65 + db #1f, #20, #ff, #00, #e0, #19, #3f, #40, #ff, #00, #f8, #06, #3f, #40, #ff, #00 + db #fe, #01, #7f, #80 +L6a24_iso_graphic_1: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1b, #04, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00 + db #ff, #00, #ff, #00, #c0, #2f, #7f, #80, #ff, #00, #ff, #00, #c0, #2b, #1f, #e0 + db #ff, #00, #ff, #00, #80, #59, #07, #f8, #ff, #00, #ff, #00, #80, #4f, #01, #be + db #ff, #00, #ff, #00, #80, #67, #00, #9f, #7f, #80, #ff, #00, #80, #49, #00, #fb + db #1f, #e0, #ff, #00, #80, #4a, #00, #79, #0f, #f0, #ff, #00, #c0, #32, #00, #9f + db #0f, #b0, #fe, #01, #f0, #0c, #00, #a7, #0f, #90, #fc, #03, #3c, #c3, #00, #29 + db #0f, #f0, #f8, #05, #0f, #f0, #00, #ca, #0f, #70, #f8, #05, #03, #7c, #c0, #32 + db #0f, #90, #f0, #0b, #00, #3f, #f0, #0c, #1f, #a0, #f0, #09, #00, #f7, #3c, #c3 + db #1f, #20, #f0, #0c, #00, #f3, #0f, #f0, #3f, #c0, #f0, #09, #00, #3f, #03, #7c + db #ff, #00, #f0, #09, #00, #4f, #01, #3e, #ff, #00, #f8, #06, #00, #53, #01, #f6 + db #ff, #00, #fe, #01, #00, #94, #01, #f2, #ff, #00, #ff, #00, #80, #65, #01, #3e + db #ff, #00, #ff, #00, #e0, #19, #01, #4e, #ff, #00, #ff, #00, #f8, #06, #01, #52 + db #ff, #00, #ff, #00, #fe, #01, #03, #94, #ff, #00, #ff, #00, #ff, #00, #83, #64 + db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00 +L6afe_iso_graphic_2: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #03, #ff, #00, #3f, #c0, #ff, #00, #fe, #01, #0f, #b0, #ff, #00, #fe, #01 + db #03, #cc, #ff, #00, #fc, #02, #03, #b4, #ff, #00, #fc, #02, #03, #cc, #ff, #00 + db #f8, #07, #03, #34, #cf, #30, #f8, #07, #03, #8c, #83, #6c, #f0, #0a, #03, #64 + db #80, #73, #f0, #0b, #07, #18, #00, #ad, #e0, #1c, #07, #c8, #00, #b3, #e0, #1e + db #0e, #31, #00, #cd, #c0, #29, #0e, #91, #00, #e3, #c0, #2c, #1c, #62, #00, #99 + db #80, #73, #1c, #22, #01, #c6, #80, #78, #38, #c7, #01, #32, #00, #a6, #38, #47 + db #03, #8c, #00, #b1, #70, #8a, #03, #64, #00, #cc, #70, #8b, #07, #18, #00, #e3 + db #e0, #1c, #07, #c8, #00, #99, #e0, #1e, #0f, #30, #01, #c6, #c0, #29, #0f, #90 + db #c1, #32, #c0, #2c, #1f, #60, #f3, #0c, #c0, #33, #1f, #20, #ff, #00, #c0, #38 + db #3f, #c0, #ff, #00, #c0, #26, #3f, #40, #ff, #00, #c0, #31, #7f, #80, #ff, #00 + db #f0, #0c, #7f, #80, #ff, #00, #fc, #03, #ff, #00 +L6ba8_iso_graphic_3: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #e0, #1b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #1c, #3f, #c0, #ff, #00, #ff, #00, #c0, #2b, #3f, #40 + db #ff, #00, #ff, #00, #c0, #2c, #3f, #c0, #ff, #00, #ff, #00, #80, #73, #3c, #43 + db #ff, #00, #ff, #00, #80, #78, #38, #c6, #3f, #c0, #ff, #00, #00, #a6, #38, #47 + db #0f, #30, #ff, #00, #00, #b1, #70, #8a, #0f, #d0, #fe, #01, #00, #cc, #70, #8b + db #0f, #30, #fe, #01, #00, #e3, #e0, #1c, #0f, #d0, #fc, #02, #00, #99, #e0, #1e + db #0f, #30, #fc, #02, #01, #c6, #c0, #29, #0f, #90, #f8, #07, #01, #32, #c0, #2c + db #1f, #60, #f8, #07, #03, #8c, #80, #73, #1f, #20, #f0, #0a, #03, #64, #80, #78 + db #3f, #c0, #f0, #0b, #07, #18, #00, #a6, #3f, #40, #f0, #0c, #07, #c8, #00, #b1 + db #7f, #80, #f0, #0e, #0e, #31, #00, #cc, #7f, #80, #f0, #09, #0e, #91, #00, #e3 + db #ff, #00, #f0, #0c, #1c, #62, #00, #99, #ff, #00, #fc, #03, #1c, #22, #01, #c6 + db #ff, #00, #ff, #00, #3c, #c3, #01, #32, #ff, #00, #ff, #00, #fc, #03, #03, #8c + db #ff, #00, #ff, #00, #fc, #02, #03, #64, #ff, #00, #ff, #00, #fc, #03, #07, #18 + db #ff, #00, #ff, #00, #ff, #00, #07, #c8, #ff, #00, #ff, #00, #ff, #00, #cf, #30 + db #ff, #00 +L6c8a_iso_graphic_4: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #03, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fe, #01 + db #1f, #60, #ff, #00, #fc, #03, #07, #58, #ff, #00, #fc, #03, #01, #56, #ff, #00 + db #f8, #07, #00, #d5, #7f, #80, #f8, #06, #00, #55, #1f, #60, #f8, #06, #00, #35 + db #07, #58, #f8, #04, #00, #15, #03, #54, #e0, #1e, #00, #0d, #03, #54, #e0, #17 + db #00, #1d, #03, #54, #c0, #35, #00, #98, #03, #fc, #c0, #35, #00, #78, #03, #84 + db #80, #7d, #00, #78, #07, #88, #80, #65, #00, #78, #07, #88, #80, #63, #00, #7c + db #0f, #f0, #80, #41, #00, #73, #7f, #80, #80, #60, #00, #f0, #3f, #c0, #e0, #11 + db #00, #a1, #3f, #40, #f0, #09, #00, #b1, #3f, #c0, #f8, #07, #00, #8f, #3f, #40 + db #fc, #03, #00, #8a, #7f, #80, #fc, #03, #00, #88, #7f, #80, #fc, #03, #00, #cf + db #ff, #00, #fc, #03, #07, #38, #ff, #00, #fc, #03, #07, #08, #ff, #00, #fc, #02 + db #0f, #10, #ff, #00, #fc, #03, #0f, #10, #ff, #00, #ff, #00, #1f, #e0, #ff, #00 + db #ff, #00, #df, #20, #ff, #00 +L6d40_iso_graphic_5: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00 + db #ff, #00, #ff, #00, #e1, #16, #ff, #00, #ff, #00, #ff, #00, #c0, #35, #7f, #80 + db #ff, #00, #ff, #00, #c0, #35, #1f, #60, #ff, #00, #ff, #00, #80, #7d, #07, #58 + db #ff, #00, #ff, #00, #80, #65, #01, #56, #ff, #00, #ff, #00, #80, #63, #00, #55 + db #7f, #80, #ff, #00, #80, #41, #00, #55, #3f, #40, #fe, #01, #00, #e0, #00, #d5 + db #3f, #40, #fe, #01, #00, #71, #00, #d5, #3f, #40, #fc, #03, #00, #59, #00, #8f + db #3f, #c0, #fc, #03, #00, #57, #00, #88, #3f, #40, #f8, #07, #00, #d7, #00, #88 + db #7f, #80, #f8, #06, #00, #57, #00, #88, #7f, #80, #f8, #06, #00, #37, #00, #cf + db #ff, #00, #f8, #04, #00, #17, #07, #38, #ff, #00, #f8, #06, #00, #0f, #03, #0c + db #ff, #00, #fe, #01, #00, #1a, #03, #14, #ff, #00, #ff, #00, #00, #9b, #03, #1c + db #ff, #00, #ff, #00, #80, #78, #03, #f4, #ff, #00, #ff, #00, #c0, #38, #07, #a8 + db #ff, #00, #ff, #00, #c0, #38, #07, #88, #ff, #00, #ff, #00, #c0, #3c, #0f, #f0 + db #ff, #00, #ff, #00, #c0, #33, #7f, #80, #ff, #00, #ff, #00, #c0, #30, #7f, #80 + db #ff, #00, #ff, #00, #c0, #21, #ff, #00, #ff, #00, #ff, #00, #c0, #31, #ff, #00 + db #ff, #00, #ff, #00, #f0, #0e, #ff, #00, #ff, #00, #ff, #00, #fc, #02, #ff, #00 + db #ff, #00 +L6e32_iso_graphic_6: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fe, #01 + db #1f, #60, #ff, #00, #fc, #03, #07, #58, #ff, #00, #fc, #03, #03, #54, #ff, #00 + db #f8, #07, #02, #d5, #7f, #80, #f8, #06, #02, #75, #1f, #60, #f0, #0e, #00, #1f + db #07, #58, #f0, #0e, #00, #07, #03, #54, #e0, #1e, #00, #07, #03, #d4, #e0, #1c + db #00, #0e, #03, #74, #c0, #3c, #00, #0e, #03, #1c, #c0, #3f, #00, #0e, #03, #04 + db #80, #7c, #00, #de, #03, #04, #80, #7c, #00, #3c, #07, #08, #80, #7c, #00, #1c + db #07, #08, #80, #5c, #00, #1f, #07, #08, #80, #7e, #00, #1c, #0f, #d0, #e0, #19 + db #00, #9c, #0f, #30, #e0, #18, #00, #7c, #0f, #10, #e0, #10, #00, #1c, #0f, #10 + db #e0, #18, #00, #3e, #0f, #10, #f8, #06, #00, #39, #0f, #90, #fe, #01, #20, #d8 + db #0f, #70, #ff, #00, #a0, #50, #0f, #10, #ff, #00, #e0, #18, #1f, #20, #ff, #00 + db #f8, #06, #1f, #20, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #ff, #00, #bf, #40 +L6ee2_iso_graphic_7: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00 + db #ff, #00, #ff, #00, #e1, #16, #ff, #00, #ff, #00, #ff, #00, #c0, #35, #7f, #80 + db #ff, #00, #ff, #00, #c0, #35, #3f, #40, #ff, #00, #ff, #00, #80, #7d, #27, #58 + db #ff, #00, #ff, #00, #80, #67, #21, #56, #ff, #00, #ff, #00, #00, #e1, #00, #f5 + db #7f, #80, #ff, #00, #00, #e0, #00, #75, #3f, #40, #fe, #01, #00, #e0, #00, #7d + db #3f, #40, #fe, #01, #00, #c0, #00, #e7, #3f, #40, #fc, #03, #00, #c0, #00, #e1 + db #3f, #c0, #fc, #03, #00, #f0, #00, #e0, #3f, #40, #f8, #07, #00, #cd, #00, #e0 + db #3f, #40, #f8, #07, #00, #c3, #00, #c0, #7f, #80, #f8, #07, #00, #c1, #00, #c0 + db #7f, #80, #f8, #05, #00, #c1, #00, #f0, #7f, #80, #f8, #07, #00, #e1, #00, #cd + db #ff, #00, #fe, #01, #00, #99, #00, #c3, #ff, #00, #fe, #01, #00, #87, #00, #c1 + db #ff, #00, #fe, #01, #00, #01, #00, #c1, #ff, #00, #fe, #01, #00, #83, #00, #e1 + db #ff, #00, #ff, #00, #80, #63, #00, #99, #ff, #00, #ff, #00, #e2, #1d, #00, #87 + db #ff, #00, #ff, #00, #fa, #05, #00, #01, #ff, #00, #ff, #00, #fe, #01, #01, #82 + db #ff, #00, #ff, #00, #ff, #00, #81, #62, #ff, #00, #ff, #00, #ff, #00, #e3, #1c + db #ff, #00, #ff, #00, #ff, #00, #fb, #04, #ff, #00 +L6fcc_iso_graphic_8: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #ff, #00 + db #0f, #f0, #ff, #00, #fe, #01, #03, #bc, #ff, #00, #fe, #01, #01, #0e, #ff, #00 + db #fc, #03, #01, #42, #3f, #c0, #fc, #02, #00, #2a, #0f, #f0, #fc, #03, #00, #f5 + db #03, #bc, #ff, #00, #00, #f5, #01, #0e, #f3, #0c, #c0, #3b, #01, #42, #f0, #0f + db #c0, #32, #01, #2a, #e0, #1b, #00, #cf, #03, #f4, #e0, #10, #00, #c3, #03, #f4 + db #c0, #34, #00, #98, #07, #f8, #c0, #22, #00, #a6, #1f, #20, #c0, #3f, #00, #22 + db #3f, #40, #f0, #0f, #00, #42, #1f, #e0, #fc, #02, #00, #64, #1f, #a0, #fc, #03 + db #00, #1d, #1f, #a0, #ff, #00, #00, #c1, #3f, #40, #ff, #00, #c0, #33, #3f, #40 + db #ff, #00, #f0, #0f, #7f, #80, #ff, #00, #fd, #02, #ff, #00 +L7058_iso_graphic_9: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #17, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00 + db #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00, #e0, #1b, #3f, #c0 + db #ff, #00, #ff, #00, #e0, #10, #1f, #e0, #ff, #00, #ff, #00, #c0, #34, #13, #2c + db #ff, #00, #ff, #00, #c0, #22, #00, #af, #ff, #00, #ff, #00, #c0, #3f, #00, #5b + db #3f, #c0, #ff, #00, #f0, #0f, #00, #50, #1f, #e0, #ff, #00, #3c, #c3, #00, #b4 + db #1f, #20, #ff, #00, #0c, #f3, #00, #22, #1f, #a0, #fe, #01, #00, #bc, #00, #ff + db #3f, #40, #fe, #01, #00, #0c, #00, #3f, #3f, #40, #fc, #03, #00, #49, #00, #8f + db #7f, #80, #fc, #02, #00, #2a, #01, #62, #ff, #00, #fc, #03, #00, #f2, #03, #24 + db #ff, #00, #ff, #00, #00, #f4, #01, #2e, #ff, #00, #ff, #00, #c0, #26, #01, #4a + db #ff, #00, #ff, #00, #c0, #31, #01, #da, #ff, #00, #ff, #00, #f0, #0c, #03, #14 + db #ff, #00, #ff, #00, #fc, #03, #03, #34, #ff, #00, #ff, #00, #ff, #00, #07, #f8 + db #ff, #00, #ff, #00, #ff, #00, #df, #20, #ff, #00 +L7112_iso_graphic_10: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01 + db #03, #ac, #ff, #00, #fe, #01, #00, #ab, #ff, #00, #fc, #03, #00, #aa, #3f, #c0 + db #fc, #02, #00, #aa, #0f, #b0, #f8, #07, #00, #ea, #03, #ac, #f8, #05, #00, #3a + db #00, #ab, #f0, #0f, #00, #0e, #00, #ab, #f0, #0a, #00, #03, #01, #ae, #e0, #1e + db #00, #60, #01, #fa, #e0, #14, #00, #98, #03, #34, #c0, #3c, #00, #86, #03, #14 + db #c0, #29, #00, #01, #07, #a8, #80, #79, #00, #01, #07, #28, #80, #52, #00, #01 + db #07, #78, #00, #f3, #00, #82, #03, #5c, #00, #a4, #00, #62, #1f, #a0, #00, #e4 + db #00, #1c, #1f, #a0, #00, #c8, #00, #05, #3f, #40, #00, #c8, #00, #09, #3f, #40 + db #00, #8c, #00, #0b, #3f, #c0, #00, #c3, #00, #12, #1f, #e0, #c0, #30, #00, #d5 + db #ff, #00, #f0, #0c, #01, #27, #ff, #00, #fc, #03, #01, #0a, #ff, #00, #ff, #00 + db #03, #cc, #ff, #00, #ff, #00, #c7, #38, #ff, #00 +L71bc_iso_graphic_11: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #1a, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #0f, #b0 + db #ff, #00, #ff, #00, #c0, #3a, #03, #ac, #ff, #00, #ff, #00, #c0, #2a, #00, #ab + db #ff, #00, #ff, #00, #80, #7e, #00, #aa, #3f, #c0, #ff, #00, #80, #53, #00, #aa + db #0f, #b0, #ff, #00, #00, #f0, #00, #ea, #0f, #b0, #ff, #00, #00, #a0, #00, #3a + db #1f, #e0, #fe, #01, #00, #e6, #00, #0f, #1f, #a0, #fe, #01, #00, #49, #00, #83 + db #3f, #40, #fc, #03, #00, #c8, #00, #61, #3f, #40, #fc, #02, #00, #90, #00, #1a + db #7f, #80, #f8, #07, #00, #90, #00, #12, #7f, #80, #f8, #05, #00, #20, #00, #17 + db #7f, #80, #f0, #0f, #00, #38, #00, #25, #3f, #c0, #f0, #0a, #00, #46, #01, #2a + db #ff, #00, #f0, #0e, #00, #41, #01, #ca, #ff, #00, #f0, #0c, #00, #80, #03, #54 + db #ff, #00, #f0, #0c, #00, #80, #03, #94, #ff, #00, #f0, #08, #00, #c0, #03, #bc + db #ff, #00, #f0, #0c, #00, #31, #01, #2e, #ff, #00, #fc, #03, #00, #0d, #0f, #50 + db #ff, #00, #ff, #00, #00, #c2, #1f, #70, #ff, #00, #ff, #00, #c0, #30, #1f, #a0 + db #ff, #00, #ff, #00, #f0, #0c, #3f, #c0, #ff, #00, #ff, #00, #fc, #03, #7f, #80 + db #ff, #00 +L729e_iso_graphic_12: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01 + db #03, #3c, #ff, #00, #fe, #01, #00, #17, #ff, #00, #fc, #02, #00, #1d, #3f, #c0 + db #fc, #02, #00, #0d, #0f, #70, #f8, #04, #00, #0d, #03, #5c, #e0, #1c, #00, #05 + db #00, #57, #f0, #0f, #00, #47, #00, #55, #f0, #09, #00, #c9, #00, #d5, #e0, #14 + db #00, #48, #00, #75, #e0, #12, #00, #12, #00, #1d, #c0, #21, #00, #15, #00, #87 + db #00, #e0, #00, #a4, #00, #61, #80, #7a, #00, #a8, #01, #1a, #80, #4e, #00, #48 + db #01, #12, #00, #c2, #00, #50, #03, #14, #00, #f0, #00, #90, #03, #24, #80, #50 + db #00, #ac, #07, #28, #c0, #29, #00, #23, #07, #48, #c0, #29, #00, #40, #0f, #d0 + db #e0, #1a, #00, #40, #0f, #90, #e0, #1a, #00, #80, #1f, #a0, #f0, #0c, #00, #e1 + db #1f, #20, #f8, #06, #00, #19, #3f, #40, #fe, #01, #00, #86, #3f, #40, #ff, #00 + db #80, #62, #7f, #80, #ff, #00, #e0, #18, #7f, #80, #ff, #00, #f8, #07, #ff, #00 + db #ff, #00, #fe, #01, #ff, #00 +L7354_iso_graphic_13: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #13, #3f, #c0, #ff, #00, #ff, #00, #e0, #11, #0f, #70 + db #ff, #00, #ff, #00, #c0, #21, #03, #dc, #ff, #00, #ff, #00, #c0, #20, #00, #d7 + db #ff, #00, #ff, #00, #80, #40, #00, #d5, #3f, #c0, #fe, #01, #00, #c0, #00, #55 + db #0f, #70, #ff, #00, #00, #f4, #00, #75, #0f, #50, #ff, #00, #00, #9c, #00, #9d + db #0f, #50, #fe, #01, #00, #44, #00, #87, #0f, #50, #fe, #01, #00, #21, #00, #21 + db #0f, #d0, #fc, #02, #00, #11, #00, #58, #0f, #70, #f0, #0e, #00, #0a, #00, #46 + db #0f, #10, #f8, #07, #00, #aa, #00, #81, #1f, #a0, #f8, #04, #00, #e4, #00, #81 + db #1f, #20, #f0, #0c, #00, #25, #00, #01, #3f, #40, #f0, #0f, #00, #09, #00, #02 + db #3f, #40, #f8, #05, #00, #0a, #00, #c2, #7f, #80, #fc, #02, #00, #92, #00, #34 + db #7f, #80, #fc, #02, #00, #94, #00, #0d, #ff, #00, #fe, #01, #00, #a4, #00, #09 + db #ff, #00, #fe, #01, #00, #a8, #01, #0a, #ff, #00, #ff, #00, #00, #ce, #01, #12 + db #ff, #00, #ff, #00, #80, #61, #03, #94, #ff, #00, #ff, #00, #e0, #18, #03, #64 + db #ff, #00, #ff, #00, #f8, #06, #07, #28, #ff, #00, #ff, #00, #fe, #01, #07, #88 + db #ff, #00, #ff, #00, #ff, #00, #8f, #70, #ff, #00, #ff, #00, #ff, #00, #ef, #10 + db #ff, #00 +L7446_iso_graphic_14: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01 + db #03, #8c, #ff, #00, #fe, #01, #00, #87, #ff, #00, #fc, #03, #00, #04, #3f, #c0 + db #fc, #03, #00, #09, #0f, #30, #f8, #07, #00, #09, #03, #0c, #f8, #07, #00, #32 + db #00, #0b, #f0, #0a, #00, #32, #00, #11, #f0, #0a, #00, #32, #00, #13, #e0, #1b + db #00, #04, #00, #63, #e0, #1c, #00, #c4, #01, #62, #c0, #2c, #00, #34, #01, #66 + db #c0, #29, #00, #8c, #01, #06, #80, #69, #00, #63, #01, #06, #80, #72, #00, #18 + db #03, #c4, #00, #b2, #00, #0e, #03, #34, #00, #a4, #00, #09, #03, #8c, #00, #a4 + db #00, #10, #07, #48, #00, #c8, #00, #10, #07, #48, #00, #c8, #00, #20, #0f, #90 + db #00, #98, #00, #20, #0f, #90, #00, #c6, #00, #41, #1f, #20, #c0, #31, #00, #c1 + db #1f, #20, #f0, #0c, #00, #62, #3f, #40, #fc, #03, #00, #1a, #3f, #40, #ff, #00 + db #00, #c4, #7f, #80, #ff, #00, #c0, #30, #7f, #80, #ff, #00, #f0, #0d, #ff, #00 + db #ff, #00, #fc, #03, #ff, #00 +L74fc_iso_graphic_15: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #70 + db #ff, #00, #ff, #00, #c0, #30, #03, #4c, #ff, #00, #ff, #00, #c0, #30, #00, #93 + db #ff, #00, #ff, #00, #80, #70, #00, #90, #3f, #c0, #ff, #00, #80, #73, #00, #20 + db #0f, #b0, #ff, #00, #00, #a3, #00, #21, #0f, #10, #ff, #00, #00, #a3, #00, #21 + db #0f, #30, #fe, #01, #00, #b0, #00, #46, #0f, #30, #fe, #01, #00, #cc, #00, #46 + db #1f, #20, #fc, #02, #00, #c3, #00, #46, #1f, #60, #fc, #02, #00, #98, #00, #c0 + db #1f, #60, #f8, #06, #00, #96, #00, #30, #1f, #60, #f8, #07, #00, #21, #00, #8c + db #3f, #40, #f0, #0b, #00, #20, #00, #e3, #3f, #40, #f0, #0a, #00, #40, #00, #98 + db #3f, #c0, #f0, #0a, #00, #41, #00, #04, #7f, #80, #f0, #0c, #00, #81, #00, #04 + db #7f, #80, #f0, #0c, #00, #82, #00, #09, #ff, #00, #f0, #09, #00, #82, #00, #09 + db #ff, #00, #f0, #0c, #00, #64, #01, #12, #ff, #00, #fc, #03, #00, #1c, #01, #12 + db #ff, #00, #ff, #00, #00, #c6, #03, #24, #ff, #00, #ff, #00, #c0, #31, #03, #a4 + db #ff, #00, #ff, #00, #f0, #0c, #07, #48, #ff, #00, #ff, #00, #fc, #03, #07, #08 + db #ff, #00, #ff, #00, #ff, #00, #0f, #d0, #ff, #00, #ff, #00, #ff, #00, #cf, #30 + db #ff, #00 +L75ee_iso_graphic_16: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #19, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #f0, #ff, #00, #fe, #01 + db #03, #fc, #ff, #00, #fe, #01, #00, #ff, #ff, #00, #fc, #02, #00, #df, #3f, #c0 + db #fc, #02, #00, #f7, #0f, #f0, #f8, #06, #00, #fd, #03, #fc, #f8, #07, #00, #3f + db #00, #7f, #f0, #0b, #00, #0f, #00, #df, #f0, #0a, #00, #63, #00, #f7, #e0, #1a + db #00, #58, #00, #fd, #e0, #1c, #00, #86, #00, #3f, #c0, #2c, #00, #83, #00, #8f + db #c0, #29, #00, #04, #00, #63, #80, #69, #00, #04, #01, #12, #80, #72, #00, #08 + db #01, #12, #00, #f1, #00, #88, #03, #24, #00, #cc, #00, #70, #03, #24, #c0, #33 + db #00, #18, #07, #48, #f0, #0e, #00, #c6, #07, #48, #f0, #07, #00, #31, #0f, #90 + db #f1, #04, #00, #cc, #0f, #10, #ff, #00, #e0, #3b, #1f, #20, #ff, #00, #c0, #1d + db #1f, #e0, #ff, #00, #c0, #13, #7f, #80 +L7686_iso_graphic_17: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #19, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #ff, #00 + db #ff, #00, #ff, #00, #e0, #1f, #3f, #c0, #ff, #00, #ff, #00, #e0, #1f, #0f, #f0 + db #ff, #00, #ff, #00, #c0, #2d, #03, #fc, #ff, #00, #ff, #00, #c0, #2f, #00, #7f + db #ff, #00, #ff, #00, #80, #6f, #00, #df, #3f, #c0, #ff, #00, #80, #73, #00, #f7 + db #0f, #f0, #ff, #00, #00, #b0, #00, #fd, #0f, #f0, #ff, #00, #00, #a6, #00, #3f + db #0f, #70, #fe, #01, #00, #a5, #00, #8f, #0f, #d0, #fe, #01, #00, #c8, #00, #63 + db #0f, #f0, #fc, #02, #00, #c8, #00, #38, #0f, #f0, #fc, #02, #00, #90, #00, #46 + db #0f, #30, #f8, #06, #00, #90, #00, #41, #1f, #20, #f8, #07, #00, #20, #00, #81 + db #1f, #20, #f0, #0f, #00, #18, #00, #82, #3f, #40, #f0, #0c, #00, #c7, #00, #02 + db #3f, #40, #fc, #03, #00, #31, #00, #84, #7f, #80, #ff, #00, #00, #ec, #00, #64 + db #7f, #80, #ff, #00, #00, #73, #00, #19, #ff, #00, #ff, #00, #10, #4c, #00, #c1 + db #ff, #00, #ff, #00, #dc, #03, #01, #b2, #ff, #00, #ff, #00, #fc, #01, #01, #de + db #ff, #00, #ff, #00, #fc, #01, #07, #38, #ff, #00 +L7750_iso_graphic_18: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1b, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01 + db #ff, #00, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #fc, #02, #0f, #b0, #ff, #00 + db #fc, #02, #03, #8c, #ff, #00, #fc, #03, #00, #03, #ff, #00, #fe, #01, #00, #08 + db #3f, #c0, #ff, #00, #00, #c8, #0f, #30, #ff, #00, #00, #f0, #03, #8c, #ff, #00 + db #00, #ec, #01, #82, #fe, #01, #00, #43, #00, #09, #fe, #01, #00, #c0, #00, #c9 + db #fc, #02, #00, #b0, #00, #31, #bc, #43, #00, #8c, #31, #4e, #88, #75, #00, #63 + db #3f, #40, #00, #af, #00, #18, #7f, #80, #00, #a6, #00, #c6, #7f, #80, #00, #c6 + db #00, #31, #ff, #00, #80, #44, #00, #0d, #ff, #00, #c0, #33, #01, #02, #ff, #00 + db #f0, #0c, #00, #c3, #ff, #00, #fc, #03, #00, #34, #7f, #80, #ff, #00, #00, #cc + db #3f, #40, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #f0, #0c, #3f, #40, #ff, #00 + db #fc, #03, #7f, #80 +L77f4_iso_graphic_19: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1b, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ef, #10, #ff, #00, #ff, #00, #ff, #00, #e3, #1c, #ff, #00 + db #ff, #00, #ff, #00, #c0, #2b, #ff, #00, #ff, #00, #ff, #00, #c0, #28, #3f, #c0 + db #ff, #00, #ff, #00, #c0, #30, #0f, #30, #ff, #00, #ff, #00, #e0, #10, #03, #8c + db #ff, #00, #ff, #00, #f0, #0c, #00, #83, #ff, #00, #ff, #00, #f0, #0f, #00, #08 + db #3f, #c0, #ff, #00, #f0, #0e, #00, #c8, #1f, #20, #ff, #00, #e0, #14, #00, #30 + db #0f, #90, #ff, #00, #e0, #1c, #00, #0c, #0f, #90, #ff, #00, #c0, #2b, #00, #03 + db #0f, #10, #fb, #04, #c0, #38, #03, #c4, #1f, #e0, #f8, #07, #80, #56, #03, #34 + db #ff, #00, #f0, #0a, #00, #f1, #07, #88, #ff, #00, #f0, #0a, #00, #6c, #07, #68 + db #ff, #00, #f0, #0c, #00, #63, #0f, #10, #ff, #00, #f8, #04, #00, #40, #0f, #d0 + db #ff, #00, #fc, #03, #00, #30, #1f, #20, #ff, #00, #ff, #00, #00, #cc, #0f, #30 + db #ff, #00, #ff, #00, #c0, #33, #07, #48, #ff, #00, #ff, #00, #f0, #0c, #03, #c4 + db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4 + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00 +L78ce_iso_graphic_20: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #ff, #00 + db #0f, #90, #ff, #00, #ff, #00, #07, #88, #ff, #00, #fe, #01, #07, #88, #ff, #00 + db #fe, #01, #07, #48, #ff, #00, #fc, #02, #03, #3c, #f3, #0c, #fc, #02, #00, #17 + db #e1, #12, #f8, #04, #00, #3d, #20, #d1, #f8, #05, #00, #37, #00, #71, #f0, #08 + db #00, #fd, #00, #e9, #f0, #08, #00, #4f, #01, #46, #e0, #10, #00, #93, #01, #c2 + db #e0, #14, #00, #94, #03, #e4, #c0, #23, #00, #25, #03, #34, #c0, #21, #00, #29 + db #07, #28, #80, #42, #00, #4a, #07, #28, #80, #52, #00, #52, #0f, #50, #00, #8e + db #00, #94, #0f, #50, #02, #85, #00, #a4, #1f, #a0, #07, #88, #80, #68, #1f, #a0 + db #87, #48, #e0, #19, #3f, #40, #cf, #30, #f0, #0d, #3f, #40, #ff, #00, #e0, #12 + db #7f, #80, #ff, #00, #e0, #10, #7f, #80, #ff, #00, #e0, #11, #ff, #00, #ff, #00 + db #f0, #09, #ff, #00, #ff, #00, #f9, #06, #ff, #00 +L7978_iso_graphic_21: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #ff, #00 + db #ff, #00, #ff, #00, #f0, #09, #ff, #00, #ff, #00, #ff, #00, #f0, #08, #7f, #80 + db #ff, #00, #ff, #00, #e0, #18, #7f, #80, #ff, #00, #ff, #00, #e0, #14, #7f, #80 + db #ff, #00, #ff, #00, #c0, #23, #3f, #c0, #3f, #c0, #ff, #00, #c0, #21, #0e, #71 + db #1f, #20, #ff, #00, #80, #43, #02, #dd, #0f, #10, #ff, #00, #80, #53, #00, #77 + db #0f, #10, #ff, #00, #00, #8f, #00, #de, #0f, #90, #ff, #00, #00, #84, #00, #f4 + db #1f, #60, #fe, #01, #00, #09, #00, #3c, #1f, #20, #fe, #01, #00, #49, #00, #4e + db #3f, #40, #fc, #02, #00, #32, #00, #53, #3f, #40, #fc, #02, #00, #12, #00, #92 + db #7f, #80, #f8, #04, #00, #24, #00, #a2, #7f, #80, #f8, #05, #00, #25, #00, #25 + db #ff, #00, #f0, #08, #00, #e9, #00, #45, #ff, #00, #f0, #08, #20, #5a, #01, #4a + db #ff, #00, #f0, #08, #78, #86, #01, #8a, #ff, #00, #f8, #04, #7e, #81, #03, #94 + db #ff, #00, #fc, #03, #ff, #00, #03, #d4, #ff, #00, #ff, #00, #fe, #01, #07, #28 + db #ff, #00, #ff, #00, #fe, #01, #07, #08, #ff, #00, #ff, #00, #fe, #01, #0f, #10 + db #ff, #00, #ff, #00, #ff, #00, #0f, #90, #ff, #00, #ff, #00, #ff, #00, #9f, #60 + db #ff, #00 +L7a5a_iso_graphic_22: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #8f, #70, #ff, #00, #ff, #00 + db #03, #8c, #ff, #00, #fe, #01, #00, #03, #ff, #00, #fc, #02, #00, #20, #3f, #c0 + db #fc, #02, #00, #a4, #0f, #b0, #f8, #04, #00, #a4, #0f, #90, #f8, #04, #00, #04 + db #07, #88, #f0, #0a, #00, #70, #07, #88, #f0, #09, #00, #8c, #07, #88, #e0, #16 + db #00, #03, #0f, #90, #e0, #12, #00, #00, #0f, #90, #c0, #24, #00, #61, #1f, #20 + db #c0, #34, #00, #19, #1f, #20, #c0, #28, #00, #03, #3f, #c0, #80, #48, #00, #03 + db #0f, #f0, #80, #71, #00, #87, #0f, #70, #80, #50, #00, #65, #0f, #d0, #80, #60 + db #00, #08, #0f, #70, #80, #60, #00, #0c, #0f, #10, #80, #46, #00, #13, #1f, #20 + db #80, #41, #03, #9c, #1f, #e0, #80, #40, #1f, #20, #ff, #00, #c0, #20, #1f, #20 + db #ff, #00, #e0, #10, #3f, #40, #ff, #00, #f0, #0c, #3f, #40, #ff, #00, #fc, #03 + db #7f, #80, #ff, #00, #ff, #00, #7f, #80, #ff, #00 +L7b04_iso_graphic_23: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1c, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f8, #07, #ff, #00 + db #ff, #00, #ff, #00, #f0, #08, #3f, #c0, #ff, #00, #ff, #00, #e0, #10, #0f, #30 + db #ff, #00, #ff, #00, #c0, #22, #03, #0c, #ff, #00, #ff, #00, #c0, #2a, #00, #4b + db #ff, #00, #ff, #00, #80, #4a, #00, #49, #ff, #00, #ff, #00, #80, #40, #00, #48 + db #7f, #80, #ff, #00, #00, #a7, #00, #08, #7f, #80, #ff, #00, #00, #98, #00, #c8 + db #7f, #80, #fe, #01, #00, #60, #00, #39, #ff, #00, #fe, #01, #00, #20, #00, #09 + db #ff, #00, #fc, #02, #00, #46, #01, #12, #ff, #00, #fc, #03, #00, #41, #01, #92 + db #ff, #00, #fc, #02, #00, #80, #03, #3c, #ff, #00, #f8, #04, #00, #80, #00, #3f + db #ff, #00, #f8, #07, #00, #18, #00, #77, #ff, #00, #f8, #05, #00, #06, #00, #5d + db #ff, #00, #f8, #06, #00, #00, #00, #87, #ff, #00, #f8, #06, #00, #00, #00, #c1 + db #ff, #00, #f8, #04, #00, #61, #01, #32, #ff, #00, #f8, #04, #00, #19, #31, #ce + db #ff, #00, #f8, #04, #01, #02, #ff, #00, #ff, #00, #fc, #02, #01, #02, #ff, #00 + db #ff, #00, #fe, #01, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4, #ff, #00 + db #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00 + db #ff, #00 +L7be6_iso_graphic_24: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #c0, #39, #3f, #c0 + db #ff, #00, #80, #43, #0f, #30, #ff, #00, #80, #43, #07, #08, #ff, #00, #00, #95 + db #07, #48, #f3, #0c, #00, #85, #03, #44, #f0, #0f, #00, #09, #03, #54, #e0, #1f + db #00, #c9, #03, #14, #e0, #1d, #00, #f1, #03, #c4, #e0, #1f, #00, #72, #03, #34 + db #e0, #1b, #00, #d2, #03, #0c, #e0, #10, #00, #f4, #03, #0c, #e0, #18, #00, #34 + db #03, #04, #f8, #06, #00, #29, #03, #84, #f8, #05, #00, #a8, #03, #64, #fc, #02 + db #00, #d0, #03, #04, #fc, #03, #00, #10, #07, #08, #fe, #01, #00, #26, #07, #08 + db #fe, #01, #00, #21, #0f, #90, #fe, #01, #00, #40, #0f, #10, #fe, #01, #00, #40 + db #1f, #20, #fe, #01, #00, #98, #1f, #20, #fe, #01, #00, #86, #3f, #40, #fe, #01 + db #00, #00, #3f, #40, #ff, #00, #00, #e1, #7f, #80, #ff, #00, #e1, #1e, #ff, #00 +L7c96_iso_graphic_25: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #8f, #70 + db #ff, #00, #ff, #00, #fc, #03, #03, #9c, #ff, #00, #ff, #00, #f8, #04, #00, #33 + db #ff, #00, #ff, #00, #f8, #04, #00, #30, #7f, #80, #ff, #00, #f0, #09, #00, #54 + db #7f, #80, #ff, #00, #30, #c8, #00, #54, #3f, #40, #ff, #00, #00, #f0, #00, #95 + db #3f, #40, #fe, #01, #00, #fc, #00, #91, #3f, #40, #fe, #01, #00, #df, #00, #1c + db #3f, #40, #fe, #01, #00, #f7, #00, #23, #3f, #40, #fe, #01, #00, #bd, #00, #20 + db #3f, #c0, #fe, #01, #00, #0f, #00, #40, #3f, #c0, #fe, #01, #00, #83, #00, #40 + db #3f, #40, #ff, #00, #80, #62, #00, #98, #3f, #40, #ff, #00, #80, #5a, #00, #86 + db #3f, #40, #ff, #00, #c0, #2d, #00, #00, #3f, #40, #ff, #00, #c0, #31, #00, #00 + db #7f, #80, #ff, #00, #e0, #12, #00, #60, #7f, #80, #ff, #00, #e0, #12, #00, #19 + db #ff, #00, #ff, #00, #e0, #14, #00, #01, #ff, #00, #ff, #00, #e0, #14, #01, #02 + db #ff, #00, #ff, #00, #e0, #19, #01, #82, #ff, #00, #ff, #00, #e0, #18, #03, #64 + db #ff, #00, #ff, #00, #e0, #10, #03, #04, #ff, #00, #ff, #00, #f0, #0e, #07, #18 + db #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00 +L7d80_iso_graphic_26: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #9c, #63, #ff, #00, #fe, #01, #00, #9e, #3f, #c0, #f8, #06, #00, #06 + db #3f, #40, #f0, #0c, #00, #4f, #3f, #40, #f0, #0b, #00, #0c, #1f, #e0, #e0, #18 + db #00, #dc, #0f, #90, #e0, #1a, #00, #19, #0f, #10, #c0, #2a, #00, #b9, #0f, #50 + db #c0, #2a, #00, #b2, #0f, #10, #c0, #28, #00, #b2, #0f, #d0, #c0, #2c, #00, #24 + db #0f, #30, #c0, #33, #00, #35, #0f, #10, #c0, #30, #00, #cd, #0f, #50, #c0, #22 + db #00, #31, #0f, #50, #c0, #22, #00, #0c, #0f, #50, #c0, #24, #00, #23, #0f, #10 + db #c0, #24, #00, #20, #0f, #d0, #c0, #20, #00, #42, #0f, #30, #e0, #10, #00, #42 + db #1f, #20, #e0, #10, #00, #04, #1f, #20, #f0, #0c, #00, #04, #3f, #40, #fc, #03 + db #00, #00, #3f, #40, #ff, #00, #00, #e1, #7f, #80, #ff, #00, #e1, #1e, #ff, #00 +L7e30_iso_graphic_27: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #cf, #30 + db #ff, #00, #ff, #00, #e0, #19, #03, #ec, #ff, #00, #ff, #00, #80, #60, #03, #64 + db #ff, #00, #ff, #00, #00, #c4, #03, #f4, #ff, #00, #ff, #00, #00, #b0, #01, #ce + db #ff, #00, #fe, #01, #00, #8d, #00, #c9, #ff, #00, #fe, #01, #00, #a1, #00, #91 + db #ff, #00, #fc, #02, #00, #ab, #00, #95, #ff, #00, #fc, #02, #00, #ab, #00, #21 + db #ff, #00, #fc, #02, #00, #8b, #00, #2d, #ff, #00, #fc, #02, #00, #c2, #00, #43 + db #ff, #00, #fc, #03, #00, #33, #00, #51, #ff, #00, #fc, #03, #00, #0c, #00, #d5 + db #ff, #00, #fc, #02, #00, #23, #00, #15, #ff, #00, #fc, #02, #00, #20, #00, #c5 + db #ff, #00, #fc, #02, #00, #42, #00, #31, #ff, #00, #fc, #02, #00, #42, #00, #0d + db #ff, #00, #fc, #02, #00, #04, #00, #23, #ff, #00, #fe, #01, #00, #04, #01, #22 + db #ff, #00, #fe, #01, #00, #00, #01, #42, #ff, #00, #ff, #00, #00, #c0, #03, #44 + db #ff, #00, #ff, #00, #c0, #30, #03, #04, #ff, #00, #ff, #00, #f0, #0e, #07, #18 + db #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00 +L7f1a_iso_graphic_28: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1a, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #8f, #70, #ff, #00, #fe, #01, #03, #8c, #ff, #00, #fc, #02, #00, #03, #ff, #00 + db #fc, #02, #00, #20, #3f, #c0, #f8, #05, #00, #24, #0f, #30, #f8, #05, #00, #04 + db #07, #08, #f0, #08, #00, #70, #07, #48, #f0, #0d, #00, #8c, #03, #54, #e0, #1a + db #00, #03, #03, #14, #e0, #1a, #00, #20, #03, #c4, #c0, #2c, #00, #20, #03, #34 + db #e0, #1c, #00, #42, #03, #0c, #e0, #18, #00, #42, #03, #0c, #f0, #0c, #00, #04 + db #03, #24, #fc, #03, #00, #04, #03, #24, #fe, #01, #00, #c0, #03, #44, #fe, #01 + db #00, #f0, #03, #44, #fc, #03, #00, #8c, #07, #08, #fc, #03, #0c, #93, #07, #08 + db #fc, #03, #0f, #10, #0f, #d0, #fc, #03, #1f, #20, #cf, #30, #fc, #02, #1f, #20 + db #ff, #00, #fc, #03, #3f, #40, #ff, #00, #ff, #00, #3f, #c0, #ff, #00 +L7fb8_iso_graphic_29: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1a, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #ff, #00, #e0, #18, #3f, #c0 + db #ff, #00, #ff, #00, #c0, #20, #0f, #30, #ff, #00, #ff, #00, #c0, #22, #03, #0c + db #ff, #00, #ff, #00, #80, #52, #00, #43, #ff, #00, #ff, #00, #80, #50, #00, #40 + db #7f, #80, #ff, #00, #00, #87, #00, #04, #7f, #80, #ff, #00, #00, #d8, #00, #c5 + db #3f, #40, #fe, #01, #00, #a0, #00, #31, #3f, #40, #fe, #01, #00, #a2, #00, #0c + db #3f, #40, #fc, #02, #00, #c2, #00, #03, #3f, #40, #fe, #01, #00, #c4, #00, #20 + db #3f, #c0, #fe, #01, #00, #84, #00, #20, #3f, #c0, #ff, #00, #00, #c0, #00, #42 + db #3f, #40, #ff, #00, #c0, #30, #00, #42, #3f, #40, #ff, #00, #e0, #1c, #00, #04 + db #3f, #40, #ff, #00, #e0, #1f, #00, #04, #3f, #40, #ff, #00, #c0, #38, #00, #c0 + db #7f, #80, #ff, #00, #c0, #39, #c0, #30, #7f, #80, #ff, #00, #c0, #31, #f0, #0d + db #ff, #00, #ff, #00, #c1, #32, #fc, #03, #ff, #00, #ff, #00, #c1, #22, #ff, #00 + db #ff, #00, #ff, #00, #c3, #34, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00 + db #ff, #00 +L808a_iso_graphic_30: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #e3, #1c, #ff, #00, #ff, #00, #00, #fb, #ff, #00, #fc, #03, #00, #f8, #3f, #c0 + db #fc, #03, #00, #da, #0f, #30, #f8, #07, #00, #78, #0f, #10, #f8, #07, #00, #da + db #0f, #50, #f0, #0b, #00, #78, #07, #18, #f0, #0b, #00, #fc, #07, #58, #e0, #13 + db #00, #e3, #07, #18, #e0, #13, #00, #00, #03, #dc, #c0, #24, #00, #7e, #03, #3c + db #c0, #25, #00, #ff, #03, #9c, #c0, #29, #00, #3f, #03, #dc, #c0, #2a, #00, #1e + db #03, #cc, #c0, #32, #00, #1c, #03, #6c, #c0, #36, #00, #38, #03, #2c, #c0, #27 + db #00, #ec, #03, #24, #c0, #27, #00, #c4, #07, #68, #c0, #27, #00, #ef, #07, #c8 + db #e0, #17, #00, #3f, #0f, #d0, #e0, #12, #00, #0f, #0f, #90, #e0, #13, #00, #0f + db #1f, #a0, #f0, #09, #00, #8f, #1f, #20, #f0, #0c, #00, #7c, #3f, #40, #fc, #03 + db #00, #00, #3f, #c0, #ff, #00, #00, #c7, #ff, #00, #ff, #00, #c7, #38, #ff, #00 +L813a_iso_graphic_31: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #ff, #00, #f0, #0f, #0f, #b0 + db #ff, #00, #ff, #00, #c0, #3f, #03, #8c, #ff, #00, #ff, #00, #c0, #3d, #00, #a3 + db #ff, #00, #ff, #00, #80, #77, #00, #81, #ff, #00, #ff, #00, #80, #7d, #00, #a5 + db #ff, #00, #ff, #00, #00, #b7, #00, #81, #7f, #80, #ff, #00, #00, #bf, #00, #c5 + db #7f, #80, #fe, #01, #00, #3e, #00, #31, #7f, #80, #fe, #01, #00, #30, #00, #0d + db #3f, #c0, #fc, #02, #00, #47, #00, #e3, #3f, #c0, #fc, #02, #00, #5f, #00, #f9 + db #3f, #c0, #fc, #02, #00, #93, #00, #fd, #3f, #c0, #fc, #02, #00, #a1, #00, #ec + db #3f, #c0, #fc, #03, #00, #21, #00, #c6, #3f, #c0, #fc, #03, #00, #63, #00, #82 + db #3f, #c0, #fc, #02, #00, #7e, #00, #c2, #3f, #40, #fc, #02, #00, #7c, #00, #46 + db #7f, #80, #fc, #02, #00, #7e, #00, #fc, #7f, #80, #fe, #01, #00, #73, #00, #fd + db #ff, #00, #fe, #01, #00, #20, #00, #f9, #ff, #00, #fe, #01, #00, #30, #01, #fa + db #ff, #00, #ff, #00, #00, #98, #01, #f2, #ff, #00, #ff, #00, #00, #c7, #03, #c4 + db #ff, #00, #ff, #00, #c0, #30, #03, #0c, #ff, #00, #ff, #00, #f0, #0c, #0f, #70 + db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00 +L8224_iso_graphic_32: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6 + db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01 + db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20 + db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #18 + db #3f, #40, #f0, #0c, #00, #3c, #3f, #40, #f0, #0c, #00, #7c, #7f, #80, #f0, #08 + db #00, #6c, #7f, #80, #f0, #0c, #00, #5f, #ff, #00, #fc, #03, #00, #7d, #7f, #80 + db #ff, #00, #01, #fa, #ff, #00, #ff, #00, #81, #72, #ff, #00, #ff, #00, #e3, #1c + db #ff, #00 +L82b6_iso_graphic_33: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c + db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00 + db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62 + db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a1 + db #03, #84, #ff, #00, #00, #c3, #03, #c4, #ff, #00, #00, #c7, #07, #c8, #ff, #00 + db #00, #86, #07, #c8, #ff, #00, #00, #c5, #0f, #f0, #ff, #00, #c0, #37, #07, #d8 + db #ff, #00, #f0, #0f, #1f, #a0, #ff, #00, #f8, #07, #1f, #20, #ff, #00, #fe, #01 + db #3f, #c0 +L8348_iso_graphic_34: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6 + db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01 + db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20 + db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #18 + db #3f, #40, #f0, #0c, #00, #2c, #3f, #40, #f0, #0d, #00, #8e, #7f, #80, #f0, #08 + db #00, #6e, #7f, #80, #f0, #0c, #00, #1f, #ff, #00, #fc, #03, #00, #4d, #ff, #00 + db #ff, #00, #01, #de, #ff, #00, #ff, #00, #81, #5a, #ff, #00, #ff, #00, #c3, #34 + db #ff, #00 +L83da_iso_graphic_35: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c + db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00 + db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62 + db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a1 + db #03, #84, #ff, #00, #00, #c2, #03, #c4, #ff, #00, #00, #d8, #07, #e8, #ff, #00 + db #00, #86, #07, #e8, #ff, #00, #00, #c1, #0f, #f0, #ff, #00, #c0, #34, #0f, #d0 + db #ff, #00, #f0, #0d, #1f, #e0, #ff, #00, #f8, #05, #1f, #a0, #ff, #00, #fc, #03 + db #3f, #40 +L846c_iso_graphic_36: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6 + db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01 + db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20 + db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #3c + db #3f, #40, #f0, #0c, #00, #64, #3f, #40, #f0, #0c, #00, #ca, #7f, #80, #f0, #08 + db #00, #da, #7f, #80, #f0, #0c, #00, #d3, #ff, #00, #fc, #03, #00, #c3, #ff, #00 + db #ff, #00, #01, #e6, #ff, #00, #ff, #00, #c1, #3a, #ff, #00, #ff, #00, #f3, #0c + db #ff, #00 +L84fe_iso_graphic_37: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c + db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00 + db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62 + db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a3 + db #03, #c4, #ff, #00, #00, #c6, #03, #44, #ff, #00, #00, #cc, #07, #a8, #ff, #00 + db #00, #8d, #07, #a8, #ff, #00, #00, #cd, #0f, #30, #ff, #00, #c0, #3c, #0f, #30 + db #ff, #00, #f0, #0e, #1f, #60, #ff, #00, #fc, #03, #1f, #a0, #ff, #00, #ff, #00 + db #3f, #c0 +L8590_iso_graphic_38: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6 + db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01 + db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20 + db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #1c, #1f, #60, #f0, #0a, #00, #3e + db #3f, #40, #f0, #0c, #00, #76, #3f, #40, #f0, #0c, #00, #7a, #7f, #80, #f0, #08 + db #00, #7e, #7f, #80, #f0, #0c, #00, #7f, #ff, #00, #fc, #03, #00, #3d, #ff, #00 + db #ff, #00, #01, #da, #ff, #00, #ff, #00, #81, #72, #ff, #00, #ff, #00, #f3, #0c + db #ff, #00 +L8622_iso_graphic_39: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c + db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00 + db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62 + db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #61, #01, #c6, #ff, #00, #00, #a3 + db #03, #e4, #ff, #00, #00, #c7, #03, #64, #ff, #00, #00, #c7, #07, #a8, #ff, #00 + db #00, #87, #07, #e8, #ff, #00, #00, #c7, #0f, #f0, #ff, #00, #c0, #33, #0f, #d0 + db #ff, #00, #f0, #0d, #1f, #a0, #ff, #00, #f8, #07, #1f, #20, #ff, #00, #ff, #00 + db #3f, #c0 +L86b4_iso_graphic_40: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0b, #03, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #e3, #1c, #ff, #00, #ff, #00 + db #f7, #08, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #f1, #0e, #ff, #00 + db #ff, #00, #f0, #09, #3f, #c0, #ff, #00, #f0, #0f, #1f, #20, #ff, #00, #f0, #0f + db #1f, #e0, #ff, #00, #f0, #09, #1f, #e0, #ff, #00, #f0, #0f, #1f, #20, #ff, #00 + db #fe, #01, #1f, #e0 +L86f8_iso_graphic_41: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0b, #04, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #3f, #c0 + db #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #ff, #00, #03, #9c + db #ff, #00, #ff, #00, #ff, #00, #01, #f2, #ff, #00, #ff, #00, #ff, #00, #01, #fe + db #ff, #00, #ff, #00, #ff, #00, #01, #9e, #ff, #00, #ff, #00, #ff, #00, #01, #f2 + db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00 +L8752_iso_graphic_42: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0b, #03, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #e3, #1c, #ff, #00, #ff, #00 + db #f7, #08, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #f1, #0e, #ff, #00 + db #ff, #00, #f0, #0d, #3f, #c0, #ff, #00, #f0, #0a, #1f, #a0, #ff, #00, #f0, #0d + db #1f, #60, #ff, #00, #f0, #0a, #1f, #a0, #ff, #00, #f0, #0f, #1f, #60, #ff, #00 + db #fe, #01, #1f, #e0 +L8796_iso_graphic_43: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0b, #04, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #3f, #c0 + db #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #ff, #00, #03, #dc + db #ff, #00, #ff, #00, #ff, #00, #01, #aa, #ff, #00, #ff, #00, #ff, #00, #01, #d6 + db #ff, #00, #ff, #00, #ff, #00, #01, #aa, #ff, #00, #ff, #00, #ff, #00, #01, #f6 + db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00 +L87f0_iso_graphic_44: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #11, #03, #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00 + db #01, #86, #ff, #00, #ff, #00, #00, #b1, #7f, #80, #fe, #01, #00, #38, #1f, #60 + db #fe, #01, #00, #79, #07, #18, #fc, #02, #00, #71, #07, #c8, #fc, #02, #00, #fb + db #0f, #d0, #f8, #04, #00, #ff, #0f, #90, #f8, #05, #00, #ef, #1f, #a0, #f0, #09 + db #00, #c7, #1f, #20, #f0, #0c, #00, #4f, #3f, #40, #fc, #03, #00, #0e, #3f, #40 + db #ff, #00, #00, #c6, #7f, #80, #ff, #00, #c0, #30, #7f, #80, #ff, #00, #f0, #0d + db #ff, #00, #ff, #00, #fc, #03, #ff, #00 +L8858_iso_graphic_45: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #11, #04, #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #f8, #05, #7f, #80 + db #ff, #00, #ff, #00, #f0, #08, #1f, #60, #ff, #00, #ff, #00, #f0, #0b, #07, #18 + db #ff, #00, #ff, #00, #e0, #13, #01, #86, #ff, #00, #ff, #00, #e0, #17, #00, #91 + db #7f, #80, #ff, #00, #c0, #27, #00, #1c, #7f, #80, #ff, #00, #c0, #2f, #00, #bd + db #ff, #00, #ff, #00, #80, #4f, #00, #f9, #ff, #00, #ff, #00, #80, #5e, #01, #fa + db #ff, #00, #ff, #00, #00, #9c, #01, #72, #ff, #00, #ff, #00, #00, #c4, #03, #f4 + db #ff, #00, #ff, #00, #c0, #30, #03, #e4, #ff, #00, #ff, #00, #f0, #0c, #07, #68 + db #ff, #00, #ff, #00, #fc, #03, #07, #08, #ff, #00, #ff, #00, #ff, #00, #0f, #d0 + db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00 +L88e2_iso_graphic_46: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #10, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03 + db #3f, #c0, #fe, #01, #1f, #e0, #ff, #00, #0f, #f0, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00, #f0, #0f, #ff, #00, #f8, #07 + db #7f, #80 +L8924_iso_graphic_47: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #10, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #c3, #3c, #ff, #00, #e1, #1e, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #0f, #f0, #ff, #00 + db #87, #78 +L8966_iso_graphic_48: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00 + db #ff, #00, #e7, #18, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #c7, #38 + db #df, #20, #ff, #00, #cf, #30, #9f, #60, #ff, #00, #df, #20, #1f, #e0, #ff, #00 + db #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #7f, #80 +L89b6_iso_graphic_49: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #0d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #fc, #03 + db #7d, #82, #ff, #00, #fc, #03, #f9, #06, #ff, #00, #fd, #02, #f1, #0e, #ff, #00 + db #ff, #00, #f1, #0e, #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #f7, #08 +L8a06_iso_graphic_50: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00 + db #ff, #00, #0f, #f0, #ff, #00, #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #f0, #0f + db #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #0f, #f0, #ff, #00 + db #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00, #ff, #00, #e1, #1e, #ff, #00 + db #ff, #00, #f8, #07, #7f, #80, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #ff, #00 + db #87, #78, #ff, #00, #ff, #00, #e1, #1e, #ff, #00, #ff, #00, #f8, #07, #7f, #80 + db #ff, #00, #fe, #01, #7f, #80 +L8a8c_iso_graphic_51: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #16, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #ff, #00 + db #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #f0 + db #ff, #00, #ff, #00, #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f + db #ff, #00, #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #ff, #00 + db #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #fe, #01, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00 + db #ff, #00, #ff, #00, #87, #78, #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00 + db #ff, #00, #ff, #00, #f8, #07, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #1f, #e0 + db #ff, #00, #ff, #00, #ff, #00, #87, #78, #ff, #00, #ff, #00, #ff, #00, #e7, #18 + db #ff, #00 +L8b3e_iso_graphic_52: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #cf, #30, #ff, #00 + db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #ff, #00, #3f, #c0 + db #ff, #00, #ff, #00, #3f, #c0, #f3, #0c, #fe, #01, #7f, #80, #f3, #0c, #fe, #01 + db #7f, #80, #e7, #18, #fc, #03, #ff, #00, #e7, #18, #fc, #03, #ff, #00, #cf, #30 + db #f9, #06, #ff, #00, #cf, #30, #f9, #06, #ff, #00, #9f, #60, #f3, #0c, #ff, #00 + db #9f, #60, #f3, #0c, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #3f, #c0, #ff, #00 + db #fe, #01, #7f, #80, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fc, #03, #ff, #00 + db #ff, #00, #fc, #03, #ff, #00 +L8bc4_iso_graphic_53: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #16, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03, #ff, #00 + db #ff, #00, #ff, #00, #fc, #03, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #ff, #00 + db #ff, #00, #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00 + db #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #3f, #c0, #ff, #00, #e7, #18, #ff, #00 + db #3f, #c0, #ff, #00, #e7, #18, #fe, #01, #7f, #80, #ff, #00, #cf, #30, #fe, #01 + db #7f, #80, #ff, #00, #cf, #30, #fc, #03, #ff, #00, #ff, #00, #9f, #60, #fc, #03 + db #ff, #00, #ff, #00, #9f, #60, #f9, #06, #ff, #00, #ff, #00, #3f, #c0, #f9, #06 + db #ff, #00, #ff, #00, #3f, #c0, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f3, #0c + db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00, #ff, #00, #ff, #00, #e7, #18 + db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00, #cf, #30 + db #ff, #00 +L8c76_iso_graphic_54: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #ff, #00 + db #ff, #00, #fb, #04, #bf, #40, #ff, #00, #fd, #02, #ef, #10, #ff, #00, #ff, #00 + db #3b, #c4, #ff, #00, #fd, #02, #de, #21, #ff, #00, #ff, #00, #73, #8c, #bf, #40 + db #ff, #00, #dd, #22, #ef, #10, #ff, #00, #f7, #08, #3f, #c0, #ff, #00, #fd, #02 + db #df, #20, #ff, #00, #ff, #00, #7f, #80 +L8cde_iso_graphic_55: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ef, #10 + db #ff, #00, #ff, #00, #bb, #44, #ff, #00, #ff, #00, #de, #21, #ff, #00, #ff, #00 + db #f3, #0c, #bf, #40, #ff, #00, #dd, #22, #ef, #10, #ff, #00, #f7, #08, #3b, #c4 + db #ff, #00, #fd, #02, #de, #21, #ff, #00, #ff, #00, #73, #8c, #ff, #00, #ff, #00 + db #dd, #22, #ff, #00, #ff, #00, #f7, #08 +L8d46_iso_graphic_56: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #fe, #01 + db #bf, #40, #ff, #00, #f5, #0a, #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00 + db #eb, #14, #ff, #00, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #d7, #28, #ff, #00 + db #ff, #00, #fd, #02, #ff, #00, #ff, #00, #af, #50, #ff, #00, #ff, #00, #eb, #14 + db #ff, #00, #ff, #00, #5f, #a0, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #fe, #01 + db #bf, #40, #ff, #00, #ff, #00, #af, #50, #ff, #00 +L8dc0_iso_graphic_57: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #af, #50, #ff, #00, #ff, #00 + db #eb, #14, #ff, #00, #ff, #00, #5f, #a0, #ff, #00, #ff, #00, #f7, #08, #ff, #00 + db #fe, #01, #bf, #40, #ff, #00, #ff, #00, #af, #50, #ff, #00, #fd, #02, #7f, #80 + db #ff, #00, #ff, #00, #df, #20, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #fe, #01 + db #bf, #40, #ff, #00, #f5, #0a, #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00 + db #eb, #14, #ff, #00, #ff, #00, #fa, #05, #ff, #00 + + +L8e3a_iso_additional_graphic_0: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00 + db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #01, #a2, #ff, #00 + db #ff, #00, #fc, #03, #01, #8a, #ff, #00, #ff, #00, #fc, #03, #00, #c3, #cf, #30 + db #ff, #00, #f8, #07, #00, #32, #43, #ac, #ff, #00, #f8, #07, #00, #0e, #00, #63 + db #ff, #00, #f8, #06, #00, #02, #00, #68, #7f, #80, #f8, #06, #00, #04, #00, #62 + db #7f, #80, #e0, #1c, #00, #06, #00, #70, #7f, #80, #e0, #16, #00, #31, #00, #cc + db #7f, #80, #c0, #37, #00, #2c, #00, #43, #7f, #80, #c0, #37, #00, #73, #00, #00 + db #7f, #80, #80, #76, #00, #4c, #00, #c1, #ff, #00, #80, #7e, #00, #c3, #00, #21 + db #ff, #00, #00, #e4, #00, #80, #01, #e2, #ff, #00, #00, #e1, #00, #80, #01, #32 + db #ff, #00, #00, #c1, #00, #08, #03, #5c, #ff, #00, #00, #c3, #00, #1c, #0b, #74 + db #ff, #00, #00, #82, #00, #08, #0f, #b0, #ff, #00, #00, #c3, #00, #08, #0f, #d0 + db #ff, #00, #c0, #31, #00, #c9, #0f, #70, #ff, #00, #f1, #0e, #c0, #29, #0f, #10 + db #ff, #00, #fd, #02, #c0, #2a, #1f, #20, #ff, #00, #ff, #00, #c0, #2a, #1f, #20 + db #ff, #00, #ff, #00, #c0, #28, #3f, #40, #ff, #00, #ff, #00, #e0, #08, #3f, #40 + db #ff, #00, #ff, #00, #e0, #0b, #7f, #80, #ff, #00, #ff, #00, #e3, #08, #7f, #80 + db #ff, #00 +L8f2c_iso_additional_graphic_1: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #1f, #20 + db #ff, #00, #ff, #00, #c0, #38, #1f, #a0, #ff, #00, #ff, #00, #c0, #3c, #0c, #33 + db #ff, #00, #ff, #00, #80, #73, #04, #2a, #3f, #c0, #ff, #00, #80, #70, #00, #e6 + db #0f, #30, #ff, #00, #80, #60, #00, #26, #07, #88, #ff, #00, #80, #60, #00, #46 + db #07, #28, #fe, #01, #00, #c0, #00, #67, #07, #08, #fe, #01, #00, #63, #00, #1c + db #07, #c8, #fc, #03, #00, #72, #00, #c4, #07, #38, #fc, #03, #00, #77, #00, #30 + db #07, #08, #f8, #07, #00, #64, #00, #cc, #0f, #10, #f8, #07, #00, #ec, #00, #32 + db #0f, #10, #f0, #0e, #00, #48, #00, #0e, #1f, #20, #f0, #0e, #00, #18, #00, #03 + db #1f, #20, #f0, #0c, #00, #10, #00, #85, #3f, #c0, #f0, #0c, #00, #31, #00, #c7 + db #bf, #40, #f0, #08, #00, #20, #00, #8b, #ff, #00, #f0, #0c, #00, #30, #00, #8d + db #ff, #00, #fc, #03, #00, #1c, #00, #97, #ff, #00, #ff, #00, #1c, #e2, #00, #91 + db #ff, #00, #ff, #00, #dc, #22, #01, #a2, #ff, #00, #ff, #00, #fc, #02, #01, #a2 + db #ff, #00, #ff, #00, #fc, #02, #03, #84, #ff, #00, #ff, #00, #fe, #00, #03, #84 + db #ff, #00, #ff, #00, #fe, #00, #07, #b8, #ff, #00, #ff, #00, #fe, #00, #37, #88 + db #ff, #00 +L901e_iso_additional_graphic_2: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #bf, #40, #ff, #00, #ff, #00 + db #0f, #f0, #ff, #00, #ff, #00, #03, #fc, #ff, #00, #fe, #01, #03, #fc, #ff, #00 + db #fe, #01, #03, #fc, #ff, #00, #fc, #03, #01, #fe, #ef, #10, #fe, #01, #00, #ff + db #43, #bc, #ff, #00, #00, #ff, #00, #ff, #ff, #00, #00, #ff, #00, #ff, #f6, #09 + db #00, #ff, #01, #fe, #f2, #0d, #00, #ff, #01, #fe, #e0, #1f, #00, #ff, #03, #fc + db #e0, #1f, #00, #ff, #13, #ec, #c0, #3f, #00, #ff, #3f, #c0, #c0, #3f, #00, #ff + db #3f, #c0, #c0, #3f, #00, #ff, #7f, #80, #f0, #0f, #80, #7f, #3f, #c0, #fd, #02 + db #e0, #1f, #1f, #e0, #ff, #00, #f0, #0f, #1f, #e0, #ff, #00, #f0, #0f, #3f, #c0 + db #ff, #00, #f0, #0f, #3f, #c0, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00 + db #7f, #80 +L90b0_iso_additional_graphic_3: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fb, #04, #ff, #00 + db #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0 + db #ff, #00, #ff, #00, #e0, #1f, #3f, #c0, #ff, #00, #ff, #00, #e0, #1f, #3f, #c0 + db #ff, #00, #ff, #00, #c0, #3f, #1e, #e1, #ff, #00, #ff, #00, #e0, #1f, #04, #fb + db #3f, #c0, #ff, #00, #f0, #0f, #00, #ff, #0f, #f0, #ff, #00, #f0, #0f, #00, #ff + db #0f, #f0, #ff, #00, #60, #9f, #00, #ff, #1f, #e0, #ff, #00, #20, #df, #00, #ff + db #1f, #e0, #fe, #01, #00, #ff, #00, #ff, #3f, #c0, #fe, #01, #00, #ff, #01, #fe + db #3f, #c0, #fc, #03, #00, #ff, #03, #fc, #ff, #00, #fc, #03, #00, #ff, #03, #fc + db #ff, #00, #fc, #03, #00, #ff, #07, #f8, #ff, #00, #ff, #00, #08, #f7, #03, #fc + db #ff, #00, #ff, #00, #de, #21, #01, #fe, #ff, #00, #ff, #00, #ff, #00, #01, #fe + db #ff, #00, #ff, #00, #ff, #00, #03, #fc, #ff, #00, #ff, #00, #ff, #00, #03, #fc + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00 +L9172_iso_additional_graphic_4: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #15, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #bc, #43, #ff, #00 + db #ff, #00, #7d, #82, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #f7, #08, #bf, #40, #fe, #01 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00, #ff, #00, #bf, #40, #ff, #00, #b7, #48, #ff, #00, #ff, #00, #cf, #30 + db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #fc, #03, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ef, #10, #ff, #00 +L91f2_iso_additional_graphic_5: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #97, #68, #d7, #28, #ff, #00, #cf, #30, #e7, #18, #fd, #02 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #cf, #30, #bf, #40, #ff, #00, #ff, #00 + db #ff, #00, #f4, #0b, #ff, #00, #ff, #00, #fd, #02, #f9, #06, #7f, #80, #ff, #00 + db #fd, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #f7, #08, #ff, #00 +L9278_iso_additional_graphic_6: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #15, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #9f, #60, #ff, #00, #ff, #00, #bf, #40, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #bf, #40, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #fa, #05, #ff, #00, #f7, #08, #f9, #06, #f7, #08, #fe, #01 + db #bf, #40, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #bf, #40 + db #f9, #06, #f5, #0a, #ff, #00, #fd, #02, #f9, #06, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #f7, #08, #bf, #40, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #fb, #04, #7f, #80, #ff, #00, #fc, #03, #ff, #00 +L92f8_iso_additional_graphic_7: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #f8, #07, #fe, #01 + db #7f, #80, #fd, #02, #fe, #01, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #d7, #28, #ff, #00, #fd, #02, #ef, #10, #9f, #60 + db #ff, #00, #ff, #00, #df, #20, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #fc, #03, #7f, #80, #ff, #00, #fe, #01, #f7, #08, #ff, #00, #ff, #00 + db #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #7f, #80 +L9372_iso_additional_graphic_8: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #19, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #00, #ff, #00, #ff, #00 + db #0f, #00, #ff, #00, #fe, #00, #03, #00, #ff, #00, #fe, #00, #00, #44, #ff, #00 + db #fe, #00, #00, #48, #7f, #80, #fe, #01, #00, #21, #6f, #00, #fe, #01, #00, #02 + db #07, #10, #fe, #01, #00, #12, #03, #20, #ff, #00, #00, #a4, #03, #a4, #ff, #00 + db #00, #88, #07, #88, #e3, #08, #80, #4a, #0f, #50, #e0, #05, #c2, #31, #5f, #a0 + db #c1, #12, #c3, #04, #c7, #00, #81, #48, #c0, #29, #c7, #28, #80, #51, #81, #12 + db #ef, #10, #c1, #26, #01, #4c, #ff, #00, #c7, #28, #00, #80, #3f, #40, #ef, #10 + db #80, #48, #3f, #80, #ff, #00, #c0, #25, #1f, #20, #ff, #00, #e0, #11, #3f, #40 + db #ff, #00, #e0, #12, #3f, #40, #ff, #00, #f0, #08, #7f, #80, #ff, #00, #f0, #0b + db #ff, #00, #ff, #00, #fb, #04, #ff, #00 +L940a_iso_additional_graphic_9: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #1a, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #df, #00, #ff, #00, #ff, #00, #83, #20, #ff, #00 + db #ff, #00, #80, #10, #ff, #00, #ff, #00, #00, #11, #1f, #00, #ff, #00, #00, #52 + db #07, #08, #f8, #01, #00, #28, #0f, #10, #f0, #00, #00, #84, #1f, #60, #f0, #0a + db #00, #83, #1f, #80, #f8, #04, #00, #4c, #1f, #20, #fc, #00, #00, #30, #0f, #c0 + db #c8, #02, #00, #03, #07, #08, #c0, #21, #00, #84, #07, #50, #e0, #10, #00, #78 + db #0f, #20, #e0, #14, #00, #01, #0f, #00, #f0, #09, #00, #06, #1f, #20, #f0, #08 + db #00, #a8, #1f, #a0, #f0, #08, #00, #90, #3f, #40, #f8, #04, #00, #51, #ff, #00 + db #f8, #05, #01, #22, #ff, #00, #f8, #05, #03, #04, #ff, #00, #f8, #04, #03, #84 + db #ff, #00, #fc, #03, #87, #68, #ff, #00, #ff, #00, #ef, #10, #ff, #00 +L94a8_iso_additional_graphic_10: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #0f, #90, #ff, #00, #ff, #00, #03, #48, #ff, #00, #fe, #00, #00, #48, #ff, #00 + db #fc, #02, #00, #48, #3f, #80, #fc, #01, #00, #21, #1f, #20, #f8, #05, #00, #20 + db #1f, #40, #f8, #04, #00, #21, #0f, #80, #fc, #02, #00, #12, #07, #08, #fc, #02 + db #00, #4c, #00, #31, #fe, #01, #00, #22, #01, #42, #e4, #10, #00, #c5, #03, #8c + db #f0, #0a, #00, #03, #07, #10, #f0, #09, #00, #29, #03, #04, #f8, #06, #00, #49 + db #07, #18, #fc, #02, #00, #45, #0f, #60, #fe, #01, #00, #92, #1f, #80, #fe, #01 + db #00, #08, #1f, #20, #fe, #01, #00, #23, #3f, #40, #ff, #00, #03, #ac, #7f, #80 + db #ff, #00, #8f, #50, #ff, #00, #ff, #00, #9f, #60, #ff, #00 +L9534_iso_additional_graphic_11: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #cf, #10, #ff, #00, #ff, #00 + db #87, #28, #ff, #00, #ff, #00, #e0, #19, #ff, #00, #ff, #00, #b9, #06, #ff, #00 + db #fc, #00, #07, #90, #8f, #40, #fc, #00, #03, #50, #c3, #24, #f8, #04, #01, #42 + db #c0, #29, #f8, #03, #00, #44, #c1, #22, #f0, #00, #00, #a4, #63, #94, #f0, #06 + db #00, #61, #e3, #14, #fe, #01, #00, #11, #f7, #08, #df, #20, #01, #92, #ff, #00 + db #c1, #12, #83, #74, #83, #44, #80, #49, #e7, #18, #07, #28, #c0, #28, #fe, #01 + db #07, #28, #c0, #24, #0f, #20, #0f, #90, #c0, #24, #03, #c4, #8f, #50, #e0, #11 + db #07, #18, #9f, #20, #e0, #10, #1a, #20, #3f, #80, #f0, #08, #30, #c3, #1f, #20 + db #f0, #09, #f0, #09, #3f, #40, #f9, #06, #f8, #04, #3f, #40, #ff, #00, #fc, #03 + db #7f, #80 +L95c6_iso_additional_graphic_12: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #f3, #0c, #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0 + db #ff, #00, #e0, #1f, #2f, #d0, #ff, #00, #c0, #3f, #27, #d8, #ff, #00, #c0, #3f + db #2f, #d0, #ff, #00, #c0, #3f, #af, #50, #ff, #00, #c0, #3f, #9f, #60, #ff, #00 + db #80, #7f, #9f, #60, #ff, #00, #82, #7d, #bf, #40, #ff, #00, #82, #7d, #7f, #80 + db #ff, #00, #02, #fd, #7f, #80, #ff, #00, #2a, #d5, #ff, #00, #ff, #00, #29, #d6 + db #ff, #00, #ff, #00, #29, #d6, #ff, #00, #ff, #00, #ab, #54, #ff, #00, #ff, #00 + db #c3, #3c, #ff, #00, #ff, #00, #ef, #10, #ff, #00 +L9640_iso_additional_graphic_13: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #15, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #f8, #07, #7f, #80, #ff, #00, #ff, #00, #f0, #0f, #1f, #e0 + db #ff, #00, #ff, #00, #e0, #1f, #07, #f8, #ff, #00, #ff, #00, #e0, #1f, #03, #fc + db #ff, #00, #ff, #00, #c8, #37, #00, #ff, #ff, #00, #ff, #00, #a8, #57, #00, #ff + db #3f, #c0, #ff, #00, #aa, #55, #00, #ff, #1f, #e0, #ff, #00, #ca, #35, #00, #ff + db #1f, #e0, #ff, #00, #f2, #0d, #40, #bf, #3f, #c0, #ff, #00, #fa, #05, #48, #b7 + db #3f, #c0, #ff, #00, #fc, #03, #4a, #b5, #7f, #80, #ff, #00, #ff, #00, #4a, #b5 + db #7f, #80, #ff, #00, #ff, #00, #8a, #75, #ff, #00, #ff, #00, #ff, #00, #f2, #0d + db #ff, #00, #ff, #00, #ff, #00, #fd, #02, #ff, #00 +L96ea_iso_additional_graphic_14: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #f3, #0c, #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0 + db #ff, #00, #e0, #1f, #2f, #d0, #ff, #00, #c0, #3f, #27, #d8, #ff, #00, #80, #7f + db #2f, #d0, #ff, #00, #80, #7f, #2f, #d0, #ff, #00, #00, #ff, #1f, #e0, #ff, #00 + db #00, #ff, #3f, #c0, #ff, #00, #00, #ff, #bf, #40, #ff, #00, #00, #ff, #bf, #40 + db #fe, #01, #02, #fd, #bf, #40, #fc, #03, #02, #fd, #bf, #40, #fc, #03, #02, #fd + db #7f, #80, #f8, #07, #02, #fd, #ff, #00, #f8, #07, #09, #f6, #ff, #00, #f0, #0f + db #09, #f6, #ff, #00, #fc, #03, #09, #f6, #ff, #00, #ff, #00, #0b, #f4, #ff, #00 + db #ff, #00, #c7, #38, #ff, #00, #ff, #00, #f7, #08, #ff, #00 +L9776_iso_additional_graphic_15: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #15, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00, #c3, #3c, #ff, #00 + db #ff, #00, #ff, #00, #81, #7e, #ff, #00, #ff, #00, #ff, #00, #80, #7f, #1f, #e0 + db #ff, #00, #ff, #00, #00, #ff, #07, #f8, #ff, #00, #ff, #00, #00, #ff, #01, #fe + db #ff, #00, #fe, #01, #40, #bf, #00, #ff, #ff, #00, #fe, #01, #50, #af, #00, #ff + db #7f, #80, #fc, #03, #51, #ae, #00, #ff, #1f, #e0, #ff, #00, #51, #ae, #00, #ff + db #1f, #e0, #ff, #00, #91, #6e, #40, #bf, #3f, #c0, #ff, #00, #e1, #1e, #50, #af + db #3f, #c0, #ff, #00, #fe, #01, #52, #ad, #7f, #80, #ff, #00, #ff, #00, #52, #ad + db #ff, #00, #ff, #00, #ff, #00, #92, #6d, #ff, #00, #ff, #00, #ff, #00, #e2, #1d + db #ff, #00, #ff, #00, #ff, #00, #fd, #02, #ff, #00 +L9820_iso_additional_graphic_16: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #fc, #03, #ff, #00, #ff, #00, #f8, #07, #3f, #c0, #ff, #00, #f0, #0f + db #1f, #e0, #ff, #00, #f0, #0f, #2f, #d0, #ff, #00, #c0, #3f, #af, #50, #ff, #00 + db #80, #7f, #9f, #60, #ff, #00, #00, #ff, #9f, #60, #ff, #00, #00, #ff, #bf, #40 + db #fe, #01, #02, #fd, #7f, #80, #fc, #03, #02, #fd, #7f, #80, #fc, #03, #02, #fd + db #7f, #80, #f8, #07, #02, #fd, #ff, #00, #f8, #07, #01, #fe, #ff, #00, #f0, #0f + db #09, #f6, #ff, #00, #fc, #03, #0b, #f4, #ff, #00, #ff, #00, #0b, #f4, #ff, #00 + db #ff, #00, #cb, #34, #ff, #00, #ff, #00, #f7, #08, #ff, #00 +L98ac_iso_additional_graphic_17: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00 + db #ff, #00, #c1, #3e, #ff, #00, #ff, #00, #80, #7f, #ff, #00, #ff, #00, #80, #7f + db #3f, #c0, #ff, #00, #00, #ff, #07, #f8, #ff, #00, #80, #7f, #03, #fc, #fe, #01 + db #a0, #5f, #03, #fc, #fe, #01, #a8, #57, #01, #fe, #fc, #03, #a9, #56, #0a, #f5 + db #ff, #00, #29, #d6, #2a, #d5, #ff, #00, #c9, #36, #29, #d6, #ff, #00, #f1, #0e + db #09, #f6, #ff, #00, #fe, #01, #73, #8c +L9914_iso_additional_graphic_18: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #20, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00 + db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #83, #ff, #00 + db #ff, #00, #fc, #02, #00, #80, #3f, #c0, #ff, #00, #fc, #02, #00, #8c, #0f, #30 + db #ff, #00, #f8, #06, #00, #8c, #03, #0c, #ff, #00, #f8, #06, #00, #c0, #00, #c3 + db #ff, #00, #f0, #0b, #00, #30, #00, #c0, #7f, #80, #f0, #0b, #00, #0c, #00, #0c + db #7f, #80, #e0, #1a, #00, #03, #00, #0c, #7f, #80, #e0, #1a, #00, #00, #00, #c0 + db #7f, #80, #c0, #2c, #00, #00, #00, #30, #7f, #80, #c0, #2c, #00, #00, #00, #0c + db #7f, #80, #80, #68, #00, #00, #00, #03, #7f, #80, #80, #68, #00, #00, #00, #00 + db #7f, #80, #00, #b0, #00, #00, #00, #01, #ff, #00, #00, #b0, #00, #00, #00, #01 + db #ff, #00, #00, #a0, #00, #00, #01, #02, #ff, #00, #00, #a0, #00, #00, #01, #02 + db #ff, #00, #00, #c0, #00, #00, #03, #04, #ff, #00, #00, #c0, #00, #00, #03, #04 + db #ff, #00, #00, #80, #00, #00, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08 + db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10 + db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20 + db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40 + db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00 +L9a16_iso_additional_graphic_19: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #20, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #30 + db #ff, #00, #ff, #00, #c0, #28, #03, #0c, #ff, #00, #ff, #00, #c0, #28, #00, #c3 + db #ff, #00, #ff, #00, #80, #68, #00, #c0, #3f, #c0, #ff, #00, #80, #6c, #00, #0c + db #0f, #30, #ff, #00, #00, #b3, #00, #0c, #07, #08, #ff, #00, #00, #b0, #00, #c0 + db #07, #c8, #fe, #01, #00, #a0, #00, #30, #07, #c8, #fe, #01, #00, #a0, #00, #0c + db #07, #08, #fc, #02, #00, #c0, #00, #03, #07, #08, #fc, #02, #00, #c0, #00, #00 + db #07, #c8, #f8, #06, #00, #80, #00, #00, #07, #38, #f8, #06, #00, #80, #00, #00 + db #07, #08, #f0, #0b, #00, #00, #00, #00, #0f, #10, #f0, #0b, #00, #00, #00, #00 + db #0f, #10, #f0, #0a, #00, #00, #00, #00, #1f, #20, #f0, #0a, #00, #00, #00, #00 + db #1f, #20, #f0, #0c, #00, #00, #00, #00, #3f, #40, #f0, #0c, #00, #00, #00, #00 + db #3f, #40, #f0, #08, #00, #00, #00, #00, #7f, #80, #f0, #0c, #00, #00, #00, #00 + db #7f, #80, #fc, #03, #00, #00, #00, #01, #ff, #00, #ff, #00, #00, #c0, #00, #01 + db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02 + db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4 + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00 +L9b18_iso_additional_graphic_20: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #28, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00 + db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #03, #84, #ff, #00 + db #ff, #00, #fc, #02, #03, #84, #ff, #00, #ff, #00, #fc, #02, #03, #84, #ef, #10 + db #ff, #00, #f8, #06, #03, #84, #e3, #1c, #ff, #00, #f8, #06, #01, #86, #c0, #33 + db #ff, #00, #f0, #0a, #00, #87, #40, #b0, #7f, #80, #f0, #0a, #00, #87, #00, #d0 + db #7f, #80, #e0, #1a, #00, #83, #00, #d0, #7f, #80, #e0, #1a, #00, #90, #00, #d0 + db #7f, #80, #c0, #2a, #00, #84, #00, #30, #7f, #80, #c0, #2a, #00, #91, #00, #00 + db #7f, #80, #80, #6a, #00, #84, #00, #40, #7f, #80, #80, #6a, #00, #c1, #00, #10 + db #7f, #80, #00, #ab, #00, #30, #00, #44, #7f, #80, #00, #ab, #00, #0c, #00, #10 + db #7f, #80, #00, #aa, #00, #03, #00, #04, #7f, #80, #00, #aa, #00, #00, #00, #c0 + db #7f, #80, #00, #ac, #00, #00, #00, #30, #7f, #80, #00, #ac, #00, #00, #00, #0c + db #7f, #80, #00, #a8, #00, #00, #00, #03, #7f, #80, #00, #a8, #00, #00, #00, #00 + db #7f, #80, #00, #b0, #00, #00, #00, #01, #ff, #00, #00, #b0, #00, #00, #00, #01 + db #ff, #00, #00, #a0, #00, #00, #01, #02, #ff, #00, #00, #a0, #00, #00, #01, #02 + db #ff, #00, #00, #c0, #00, #00, #03, #04, #ff, #00, #00, #c0, #00, #00, #03, #04 + db #ff, #00, #00, #80, #00, #00, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08 + db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10 + db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20 + db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40 + db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00 +L9c5a_iso_additional_graphic_21: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #28, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #3f, #40 + db #ff, #00, #ff, #00, #c0, #28, #3f, #40, #ff, #00, #ff, #00, #c0, #28, #3e, #41 + db #ff, #00, #ff, #00, #80, #68, #3e, #41, #3f, #c0, #ff, #00, #80, #68, #1c, #63 + db #0f, #30, #ff, #00, #00, #a8, #04, #7b, #07, #08, #ff, #00, #00, #a8, #00, #7d + db #07, #08, #fe, #01, #00, #a8, #00, #3d, #07, #08, #fe, #01, #00, #a9, #00, #0d + db #07, #08, #fc, #02, #00, #a8, #00, #43, #07, #08, #fc, #02, #00, #a9, #00, #10 + db #07, #08, #f8, #06, #00, #a8, #00, #44, #07, #08, #f8, #06, #00, #ac, #00, #11 + db #07, #08, #f0, #0a, #00, #b3, #00, #04, #07, #48, #f0, #0a, #00, #b0, #00, #c1 + db #07, #08, #f0, #0a, #00, #a0, #00, #30, #07, #48, #f0, #0a, #00, #a0, #00, #0c + db #07, #08, #f0, #0a, #00, #c0, #00, #03, #07, #08, #f0, #0a, #00, #c0, #00, #00 + db #07, #c8, #f0, #0a, #00, #80, #00, #00, #07, #38, #f0, #0a, #00, #80, #00, #00 + db #07, #08, #f0, #0b, #00, #00, #00, #00, #0f, #10, #f0, #0b, #00, #00, #00, #00 + db #0f, #10, #f0, #0a, #00, #00, #00, #00, #1f, #20, #f0, #0a, #00, #00, #00, #00 + db #1f, #20, #f0, #0c, #00, #00, #00, #00, #3f, #40, #f0, #0c, #00, #00, #00, #00 + db #3f, #40, #f0, #08, #00, #00, #00, #00, #7f, #80, #f0, #0c, #00, #00, #00, #00 + db #7f, #80, #fc, #03, #00, #00, #00, #01, #ff, #00, #ff, #00, #00, #c0, #00, #01 + db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02 + db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4 + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00 +L9d9c_iso_additional_graphic_22: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #19, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01 + db #0b, #d4, #ff, #00, #fe, #01, #08, #77, #ff, #00, #ff, #00, #18, #a4, #7f, #80 + db #ff, #00, #bc, #43, #cf, #30, #f8, #07, #cf, #30, #c3, #2c, #f8, #05, #82, #4d + db #81, #56, #f1, #0a, #83, #74, #81, #7a, #f1, #0a, #03, #9c, #c9, #36, #e1, #16 + db #0e, #d1, #7f, #80, #e3, #1c, #df, #20, #23, #dc, #ff, #00, #fb, #04, #e1, #16 + db #c7, #38, #39, #c6, #c1, #2a, #87, #48, #90, #6f, #e1, #16, #8c, #73, #f0, #09 + db #e7, #18, #88, #56, #61, #96, #bf, #40, #c8, #35, #21, #5a, #ff, #00, #f8, #06 + db #73, #8c, #17, #e8, #fc, #03, #7e, #81, #0f, #30, #ff, #00, #ff, #00, #0f, #d0 + db #ff, #00, #c9, #36, #9f, #60, #ff, #00, #c0, #2d, #df, #20, #ff, #00, #e1, #12 + db #ff, #00, #ff, #00, #f3, #0c, #ff, #00 +L9e34_iso_additional_graphic_23: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #ff, #00, #f0, #0a, #3f, #c0 + db #ff, #00, #ff, #00, #f8, #05, #33, #4c, #ff, #00, #ff, #00, #f8, #06, #61, #92 + db #ff, #00, #ff, #00, #dc, #23, #f1, #0a, #ff, #00, #ff, #00, #ff, #00, #db, #24 + db #9f, #60, #ff, #00, #f3, #0c, #ff, #00, #07, #d8, #ff, #00, #39, #c6, #8f, #70 + db #07, #a8, #fe, #01, #1f, #20, #87, #58, #8f, #50, #ff, #00, #33, #cc, #84, #4b + db #df, #20, #ff, #00, #f0, #0b, #cc, #32, #7f, #80, #fc, #03, #60, #9d, #fe, #01 + db #7f, #80, #f8, #04, #60, #97, #ff, #00, #ff, #00, #f8, #07, #e1, #1a, #e3, #1c + db #ff, #00, #f8, #05, #f9, #06, #c1, #2a, #ff, #00, #fd, #02, #ef, #10, #c3, #24 + db #ff, #00, #ff, #00, #3f, #c0, #87, #58, #ff, #00, #ff, #00, #d8, #27, #9f, #60 + db #ff, #00, #ff, #00, #fd, #02, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #fd, #02 + db #ff, #00, #ff, #00, #ff, #00, #a7, #58, #ff, #00, #ff, #00, #ff, #00, #cf, #30 + db #ff, #00 +L9ef6_iso_additional_graphic_24: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #19, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #6f, #90, #ff, #00, #ff, #00 + db #f7, #08, #ff, #00, #fe, #01, #5f, #a0, #ff, #00, #fc, #02, #47, #b8, #3f, #c0 + db #fc, #03, #c2, #2d, #3f, #40, #ff, #00, #82, #55, #6f, #90, #fd, #02, #c7, #28 + db #fc, #03, #fc, #03, #66, #99, #3e, #c1, #f8, #04, #3f, #40, #73, #8c, #f8, #05 + db #3f, #40, #e0, #1b, #f9, #06, #31, #ce, #e0, #15, #cf, #30, #e0, #15, #f1, #0a + db #ec, #13, #f0, #0b, #9b, #64, #fc, #02, #39, #c6, #8f, #50, #98, #67, #3f, #40 + db #0f, #90, #88, #54, #3f, #c0, #1f, #a0, #9c, #62, #71, #8e, #bf, #40, #fe, #01 + db #f0, #0b, #ff, #00, #ff, #00, #99, #66, #cf, #30, #ff, #00, #0f, #d0, #df, #20 + db #ff, #00, #8e, #51, #7f, #80, #ff, #00, #dc, #22, #3f, #40, #ff, #00, #fc, #03 + db #3f, #40, #ff, #00, #ff, #00, #7f, #80 +L9f8e_iso_additional_graphic_25: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03, #ff, #00 + db #ff, #00, #ff, #00, #fc, #02, #3f, #c0, #ff, #00, #ff, #00, #f8, #04, #7f, #80 + db #ff, #00, #ff, #00, #f8, #07, #e3, #1c, #ff, #00, #ff, #00, #fb, #04, #c1, #2a + db #ff, #00, #ff, #00, #8e, #71, #c1, #2a, #ff, #00, #ff, #00, #87, #58, #e3, #14 + db #ff, #00, #ff, #00, #df, #20, #37, #c8, #8f, #70, #ff, #00, #ff, #00, #0e, #b1 + db #0f, #90, #fe, #01, #79, #86, #87, #48, #9f, #60, #fe, #01, #30, #49, #cf, #30 + db #ff, #00, #fc, #02, #11, #ae, #fc, #03, #7f, #80, #fe, #01, #3b, #44, #0c, #f2 + db #7f, #80, #fe, #01, #7f, #80, #0e, #91, #ff, #00, #fb, #04, #e3, #1c, #9f, #60 + db #ff, #00, #ff, #00, #c1, #22, #b3, #4c, #ff, #00, #ff, #00, #61, #9a, #fd, #02 + db #ff, #00, #ff, #00, #fb, #04, #ef, #10, #ff, #00, #ff, #00, #ff, #00, #c3, #2c + db #ff, #00, #ff, #00, #fe, #01, #41, #b6, #ff, #00, #ff, #00, #ff, #00, #41, #aa + db #ff, #00, #ff, #00, #ff, #00, #c3, #34, #ff, #00, #ff, #00, #ff, #00, #e7, #18 + db #ff, #00 +La050_iso_additional_graphic_26: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #24, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00 + db #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #0f, #f0, #fe, #01, #03, #ac, #fe, #01 + db #00, #d7, #fc, #02, #00, #ab, #fc, #03, #00, #d5, #f8, #06, #00, #ab, #f8, #05 + db #00, #d5, #f8, #06, #00, #ab, #f8, #05, #00, #d5, #f8, #07, #00, #3b, #f8, #05 + db #00, #0d, #f8, #06, #00, #63, #f8, #06, #01, #5a, #f8, #04, #01, #ea, #f8, #06 + db #03, #dc, #fe, #01, #03, #ec, #ff, #00, #07, #d8, #ff, #00, #07, #e8, #ff, #00 + db #07, #d8, #ff, #00, #07, #e8, #ff, #00, #07, #f8, #ff, #00, #07, #b8, #ff, #00 + db #0f, #f0, #ff, #00, #cf, #30, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00 + db #df, #20, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00 + db #df, #20 +La0e2_iso_additional_graphic_27: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #20, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00 + db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #a3, #ff, #00 + db #ff, #00, #fc, #03, #00, #a8, #3f, #c0, #ff, #00, #fc, #03, #00, #aa, #0f, #30 + db #ff, #00, #f8, #07, #00, #8a, #03, #8c, #ff, #00, #f8, #07, #00, #c2, #00, #a3 + db #ff, #00, #f0, #0f, #00, #30, #00, #a8, #7f, #80, #f0, #0f, #00, #0c, #00, #2a + db #7f, #80, #e0, #1e, #00, #03, #00, #0a, #7f, #80, #e0, #1e, #00, #00, #00, #c2 + db #7f, #80, #c0, #3c, #00, #00, #00, #30, #7f, #80, #c0, #3c, #00, #00, #00, #0c + db #7f, #80, #80, #78, #00, #00, #00, #03, #7f, #80, #80, #78, #00, #10, #00, #00 + db #7f, #80, #00, #f0, #00, #10, #00, #01, #ff, #00, #00, #f0, #00, #21, #00, #01 + db #ff, #00, #00, #e0, #00, #21, #01, #02, #ff, #00, #00, #e0, #00, #42, #01, #02 + db #ff, #00, #00, #c0, #00, #42, #03, #04, #ff, #00, #00, #c0, #00, #04, #03, #04 + db #ff, #00, #00, #80, #00, #04, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08 + db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10 + db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20 + db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40 + db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00 +La1e4_iso_additional_graphic_28: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #20, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #0f, #30 + db #ff, #00, #ff, #00, #c0, #28, #03, #8c, #ff, #00, #ff, #00, #c0, #2a, #00, #23 + db #ff, #00, #ff, #00, #80, #68, #00, #88, #3f, #c0, #ff, #00, #80, #6c, #00, #22 + db #0f, #30, #ff, #00, #00, #b3, #00, #08, #07, #88, #ff, #00, #00, #b0, #00, #c2 + db #07, #28, #fe, #01, #00, #a0, #00, #30, #07, #88, #fe, #01, #00, #a0, #00, #0c + db #07, #28, #fc, #02, #00, #c0, #00, #03, #07, #08, #fc, #02, #00, #c3, #00, #00 + db #07, #c8, #f8, #06, #03, #84, #00, #c0, #07, #38, #f8, #06, #03, #84, #c0, #30 + db #07, #08, #f0, #0b, #01, #0a, #e0, #1c, #0f, #10, #f0, #0b, #00, #0d, #60, #9e + db #0f, #10, #f0, #0a, #00, #1a, #00, #fc, #1f, #20, #f0, #0a, #00, #15, #00, #7c + db #1f, #20, #f0, #0c, #00, #2a, #00, #b8, #3f, #40, #f0, #0c, #00, #35, #00, #78 + db #3f, #40, #f0, #08, #00, #0e, #00, #b0, #7f, #80, #f0, #0c, #00, #03, #00, #70 + db #7f, #80, #fc, #03, #00, #00, #00, #e1, #ff, #00, #ff, #00, #00, #c0, #00, #21 + db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02 + db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4 + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00 +La2e6_iso_additional_graphic_29: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #28, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00 + db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #a3, #ff, #00 + db #ff, #00, #fc, #02, #00, #a8, #3f, #c0, #ff, #00, #fc, #02, #00, #aa, #0f, #30 + db #ff, #00, #f8, #04, #00, #aa, #03, #8c, #ff, #00, #f8, #04, #00, #ae, #00, #a3 + db #ff, #00, #f0, #08, #00, #a9, #00, #a8, #7f, #80, #f0, #0a, #00, #a8, #00, #6a + db #7f, #80, #e0, #12, #00, #a8, #00, #1a, #7f, #80, #e0, #12, #00, #a8, #00, #0a + db #7f, #80, #c0, #22, #00, #ac, #00, #1a, #7f, #80, #c0, #2a, #00, #ab, #00, #3a + db #7f, #80, #80, #4a, #00, #8a, #00, #fa, #7f, #80, #80, #48, #00, #c2, #00, #ba + db #7f, #80, #00, #89, #00, #30, #00, #aa, #7f, #80, #00, #a9, #00, #0c, #00, #2a + db #7f, #80, #00, #aa, #00, #43, #00, #0a, #7f, #80, #00, #a2, #00, #10, #00, #c2 + db #7f, #80, #00, #a4, #00, #84, #00, #30, #7f, #80, #00, #a4, #00, #21, #00, #0c + db #7f, #80, #00, #a9, #00, #08, #00, #43, #7f, #80, #00, #88, #00, #42, #00, #10 + db #7f, #80, #00, #92, #00, #10, #00, #85, #ff, #00, #00, #90, #00, #84, #00, #21 + db #ff, #00, #00, #a4, #00, #21, #01, #0a, #ff, #00, #00, #a1, #00, #08, #01, #42 + db #ff, #00, #00, #c8, #00, #42, #03, #14, #ff, #00, #00, #c2, #00, #10, #03, #84 + db #ff, #00, #00, #90, #00, #84, #07, #28, #ff, #00, #00, #c4, #00, #21, #07, #08 + db #ff, #00, #c0, #31, #00, #08, #0f, #50, #ff, #00, #f0, #0c, #00, #42, #0f, #10 + db #ff, #00, #fc, #03, #00, #10, #1f, #a0, #ff, #00, #ff, #00, #00, #c4, #1f, #20 + db #ff, #00, #ff, #00, #c0, #31, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40 + db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80 + db #ff, #00 +La428_iso_additional_graphic_30: ; mdl-asm+:html:gfx(and-or-bitmap-with-size,post,2) + db #28, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00 + db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #30 + db #ff, #00, #ff, #00, #c0, #2a, #03, #0c, #ff, #00, #ff, #00, #c0, #28, #00, #83 + db #ff, #00, #ff, #00, #80, #4a, #00, #08, #3f, #c0, #ff, #00, #80, #58, #00, #a8 + db #0f, #30, #ff, #00, #00, #d8, #00, #28, #07, #08, #ff, #00, #00, #c8, #00, #22 + db #07, #88, #fe, #01, #00, #ca, #00, #0a, #07, #28, #fe, #01, #00, #c8, #00, #aa + db #07, #88, #fc, #03, #00, #ca, #00, #28, #07, #28, #fc, #03, #00, #88, #00, #a2 + db #07, #08, #f8, #05, #00, #a8, #00, #0a, #07, #08, #f8, #05, #00, #0c, #00, #0a + db #07, #88, #f0, #09, #00, #53, #00, #08, #07, #28, #f0, #08, #00, #10, #00, #c0 + db #07, #88, #f0, #08, #00, #a4, #00, #30, #07, #28, #f0, #0c, #00, #20, #00, #0c + db #07, #08, #f0, #0d, #00, #40, #00, #43, #07, #08, #f0, #08, #00, #42, #00, #00 + db #07, #c8, #f0, #0a, #00, #90, #00, #04, #07, #38, #f0, #08, #00, #80, #00, #00 + db #07, #08, #f0, #09, #00, #01, #00, #00, #0f, #50, #f0, #09, #00, #00, #00, #02 + db #0f, #10, #f0, #0a, #00, #42, #00, #10, #1f, #20, #f0, #0a, #00, #00, #00, #00 + db #1f, #20, #f0, #0c, #00, #04, #00, #21, #3f, #40, #f0, #0c, #00, #20, #00, #00 + db #3f, #40, #f0, #09, #00, #00, #00, #40, #7f, #80, #f0, #0c, #00, #00, #00, #00 + db #7f, #80, #fc, #03, #00, #10, #00, #05, #ff, #00, #ff, #00, #00, #c0, #00, #21 + db #ff, #00, #ff, #00, #c0, #31, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02 + db #ff, #00, #ff, #00, #fc, #03, #03, #14, #ff, #00, #ff, #00, #ff, #00, #03, #c4 + db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08 + db #ff, #00 diff --git a/netherearth-annotated.asm b/netherearth-annotated.asm new file mode 100644 index 0000000..0d4c8fd --- /dev/null +++ b/netherearth-annotated.asm @@ -0,0 +1,8655 @@ +; -------------------------------- +; +; "Nether Earth" by Argus Press Software, 1986 +; Disassembled by Santiago Ontañón in 2022 +; +; -------------------------------- +; +; Notes: +; +; - All the symbol names and comments in this file are my own interpretation of the original source +; code, they could be wrong. So, take them all with a grain of salt! And if you see any errors, +; please report! +; +; - Game binary disassembled using MDL: https://github.com/santiontanon/mdlz80optimizer +; +; - I decided to prefix each label by their address, e.g. "La600_start" instead of just "start" as, +; often, the code makes assumptions about these addresses. For example, when it checks if the +; most-significant byte of a pointer if #dc or #fd to know we are out of bounds of a map. By +; making the map label "Ldd00_map", it is at least clear that checking for "#dc" is to see if the +; pointer is lower than #dd00, which is the beginning of the map. +; +; - There is some unreachable code (see label Lae29) in the code base, that contains code that is +; probably left-over code. +; +; - There are also two gaps in the zone of RAM designated for variables. So, probably some +; variables were defined, but unused in the final version of the code (search for "unused bytes" +; in this file). +; +; - The music system is very interesting for a 48K Spectrum model: +; - Look at "Lc4a7_title_music_loop" +; - Basically, when playing music, the game runs a constant loop that iterates over 3 +; oscillators that produce sound. +; - These oscillators are just 3 loops in the code that make the speaker vibrate with some +; fixed frequencies. +; - The interrupt routine has a script that, using self-modifiable code, modifies the +; oscillator parameters in the loop. +; - So, basically, the loop acts as a sound chip, and the interrupt basically sets its +; parameters, mimicking 3 channel sound. +; - Since it's a dedicated loop, nothing can run in parallel with it. So, as soon as the player +; presses any key, music stops. +; +; - SFX: +; - The game reads from the addresses in the Spectrum ROM and uses them to produce sound. This +; is probably just some random sound (as those values are not a wave, but assembler code), +; but the programmers chose different parts of the ROM that produce slightly different +; sounds when reproduced, which is pretty smart. +; +; - Game-play details, not fully documented in the instructions: +; - Weapons all fly at the same altitude (10) regardless of the height of the robot. +; - Electronics: +; - increase the range of weapons by 1 tile (what the manual states being 3 miles). +; - they also increase the distance robots can "see" an opponent from 10 to 12 tiles. +; - Each player can have at most 24 robots. +; - There can only be 5 bullets at a time in the whole game: +; - one bullet for the player controlled robot +; - two bullets fired by friendly robots +; - two bullets fired by enemy robots +; - How much damage weapons deal is quite curious: +; - The game calculates (60 - (robot height + ground height))/4 as the "base damage". +; - Then cannon deals 2x the base damage, missiles 3x, and phasers 4x. (the Spanish +; instruction manual is wrong here, stating that missiles do the same damage as cannon, +; English is correct). +; - So, robots that are on high ground receive less damage! Stand on a mountain to make a +; robot more resistant! +; - Since a robot can have at most 3 weapons, we have (see the +; Ld7b4_piece_heights data below): +; - The maximum height of a robot is: 11 + 6 + 7 + 7 + 7 = 38 (bipod, missiles, phase, +; nuclear, electronics). This is the most resistant robot! +; - The minimum height of a robot is: 7 + 6 = 13 (tracks, cannon). This is the weakest +; robot! +; - So, for example: phasers against the weakest robot (at ground level) deal: ((60 - 13)/4)*4 +; = 44 damage. +; - The robot/enemy AI is extremely simple: +; - see "Lb154_robot_ai_update" for the code that implements the AI of the robots, +; including their limited "path-finding", and targetting. +; - see "Lb7f4_update_enemy_ai" for the code that implements the strategy of the enemy +; player. +; +; - Terminology: +; - I often use the abbreviation "ptr." for "pointer". +; - I often use the term "one-hot" (vector/byte). This is a way to represent numbers, where +; only one bit of the byte is set to 1, and the others are zero. The number encoded is the +; index of the bit that is set to 1. For example: +; - 1 encoded as a one-hot vector is: 00000001 +; - 2 encoded as a one-hot vector is: 00000010 +; - 3 encoded as a one-hot vector is: 00000100 +; - 4 encoded as a one-hot vector is: 00001000 +; - etc. +; +; -------------------------------- + + +; -------------------------------- +; BIOS Functions and constants: +; - Information obtained from: +; https://worldofspectrum.net/pub/sinclair/books/s/SpectrumMachineCodeReferenceGuideThe.pdf +L0205_BIOS_KEYCODE_TABLE: equ #0205 +L028e_BIOS_POLL_KEYBOARD: equ #028e ; Polls keyboard and builds up key code in DE +L0556_BIOS_READ_FROM_TAPE: equ #0556 ; Load if carry set, load tape header if A=0 (nz=data). + ; IX=address, DE=byte count +L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS: equ #0562 +L04c2_BIOS_CASSETTE_SAVE: equ #04c2 +L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS: equ #04d0 + +L4000_VIDEOMEM_PATTERNS: equ #4000 +L5800_VIDEOMEM_ATTRIBUTES: equ #5800 + +ULA_PORT: equ #fe +KEMPSTON_JOYSTICK_PORT: equ 31 +INTERFACE2_JOYSTICK_PORT_MSB: equ #ef + +COLOR_BRIGHT: equ #40 +COLOR_BLACK: equ 0 +COLOR_BLUE: equ 1 +COLOR_RED: equ 2 +COLOR_PINK: equ 3 +COLOR_GREEN: equ 4 +COLOR_CYAN: equ 5 +COLOR_YELLOW: equ 6 +COLOR_WHITE: equ 7 +PAPER_COLOR_MULTIPLIER: equ 8 + + +; -------------------------------- +; Commands recognized by Ld42d_execute_ui_script: +CMD_END: equ 0 +CMD_SET_POSITION: equ 1 +CMD_SET_ATTRIBUTE: equ 2 +CMD_NEXT_LINE: equ 3 +CMD_SET_SCALE: equ 4 + + +; -------------------------------- +INPUT_KEYBOARD: equ 1 +INPUT_KEMPSTON: equ 2 +INPUT_INTERFACE2: equ 3 + + +; -------------------------------- +; Game constants: +INITIAL_PLAYER_RESOURCES: equ 20 +MAX_ROBOTS_PER_PLAYER: equ 24 +MAX_BULLETS: equ 5 +N_WARBASES: equ 4 +N_FACTORIES: equ 24 +BUILDING_CAPTURE_TIME: equ 144 +MIN_INTERRUPTS_PER_GAME_CYCLE: equ 10 ; game maximum speed is 5 frames per second. + +MAX_PLAYER_ALTITUDE: equ 48 +MIN_PLAYER_X: equ 14 +MAX_PLAYER_X: equ 501 + +MAP_LENGTH: equ 512 ; x coordinate +MAP_WIDTH: equ 16 ; y coordinate + +ROBOT_ORDERS_STOP_AND_DEFEND: equ 0 +ROBOT_ORDERS_ADVANCE: equ 1 +ROBOT_ORDERS_RETREAT: equ 2 +ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS: equ 3 +ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES: equ 4 +ROBOT_ORDERS_DESTROY_ENEMY_WARBASES: equ 5 +ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES: equ 6 +ROBOT_ORDERS_CAPTURE_ENEMY_FACTORIES: equ 7 +ROBOT_ORDERS_CAPTURE_ENEMY_WARBASES: equ 8 + +ROBOT_CONTROL_AUTO: equ 0 +ROBOT_CONTROL_PLAYER_LANDED: equ 1 +ROBOT_CONTROL_DIRECT_CONTROL: equ 2 +ROBOT_CONTROL_ENEMY_AI: equ 128 + +WEAPON_RANGE_DEFAULT: equ 5 +WEAPON_RANGE_MISSILES: equ 7 + + +; -------------------------------- +; Game structs: +ROBOT_STRUCT_SIZE: equ 16 +ROBOT_STRUCT_MAP_PTR: equ 0 ; 2 bytes (the first byte set to 0 when there is no robot in this + ; struct). +ROBOT_STRUCT_X: equ 2 ; 2 bytes +ROBOT_STRUCT_Y: equ 4 +ROBOT_STRUCT_DESIRED_MOVE_DIRECTION: equ 5 +ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING: equ 6 +ROBOT_STRUCT_PIECES: equ 7 +ROBOT_STRUCT_DIRECTION: equ 8 ; one-hot representation: #01, #02, #04, #08 +ROBOT_STRUCT_HEIGHT: equ 9 +ROBOT_STRUCT_CONTROL: equ 10 +ROBOT_STRUCT_ORDERS: equ 11 +ROBOT_STRUCT_STRENGTH: equ 12 +ROBOT_STRUCT_ALTITUDE: equ 13 +ROBOT_STRUCT_ORDERS_ARGUMENT: equ 14 ; This can be # of miles, target robot index, etc. +ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE: equ 15 + + +BULLET_STRUCT_SIZE: equ 9 +BULLET_STRUCT_MAP_PTR: equ 0 ; 2 bytes (the first byte set to 0 when there is no bullet in this + ; struct). +BULLET_STRUCT_X: equ 2 ; 2 bytes +BULLET_STRUCT_Y: equ 4 +BULLET_STRUCT_DIRECTION: equ 5 +BULLET_STRUCT_RANGE: equ 6 +BULLET_STRUCT_TYPE: equ 7 ; 1: cannon, 2: missiles, 3: phasers +BULLET_STRUCT_ALTITUDE: equ 8 + + +BUILDING_STRUCT_SIZE: equ 5 +BUILDING_STRUCT_X: equ 0 ; 2 bytes +BUILDING_STRUCT_Y: equ 2 +BUILDING_STRUCT_TYPE: equ 3 ; contains type + owner (owner in the most-significant bits: bit 6 + ; player 1, bit 5 player 2). bit 7 indicates building is destroyed. +BUILDING_STRUCT_TIMER: equ 4 ; this counts the time the building is occupied by a robot + + +BUILDING_DECORATION_STRUCT_SIZE: equ 3 +BUILDING_DECORATION_STRUCT_MAP_PTR: equ 0 +BUILDING_DECORATION_STRUCT_TYPE: equ 2 + + +; -------------------------------- +; RAM variables/buffers in the low region of RAM: +; The first 3200 bytes (starting at #5b00) are used as a double buffer, to render +; the screen there, before it is copied over to the video memory. 3200 bytes, as +; the game area is 160x160 pixels wide. So, 160/8 = 20 bytes per line, and 20*160 = 3200. +L5b00: equ #5b00 +L5b00_double_buffer: equ #5b00 + + +; -------------------------------- +; Game graphic data" + org #6780 + + include "netherearth-annotated-data.asm" + ds #a600 - $, 0 ; 150 bytes of empty space until the game code starts. + + +; -------------------------------- +; Game entry point +La600_start: + ; Set up the interrupts: + di + ld sp, 0 + ld hl, Lfe00_interrupt_vector_table + ld bc, #00fd + ; Write #fd to the interrupt vector table 257 times +La60a_interrupt_vector_table_init_loop: + ld (hl), c + inc hl + djnz La60a_interrupt_vector_table_init_loop + ld (hl), c + ld a, #c3 ; jp opcode + ld (Lfdfd_interrupt_jp), a + ld hl, Ld59c_empty_interrupt + ld (Lfdfe_interrupt_pointer), hl ; sets the interrupt routine + ld a, #fe + ld i, a ; sets the interrupt vector tp #fe00 + im 2 + ei + + ; Initialize the random number generator: + ld hl, 12345 ; random seed + ld (Lfd00_random_seed), hl + ld (Lfd00_random_seed+2), hl + call Lc100_title_screen + jr nz, La68e_game_loop_start ; Start from a saved game + + ; Start new game from scratch: + ; Clear memory buffers: + ld hl, Lda00_player1_robots + ld de, Lda00_player1_robots+1 + ld bc, 2*MAX_ROBOTS_PER_PLAYER*ROBOT_STRUCT_SIZE - 1 + ld (hl), 0 + ldir + ld hl, Lfd04_script_video_pattern_ptr + ld de, Lfd04_script_video_pattern_ptr+1 + ld bc, 248 + ld (hl), 0 + ldir ; This clears a whole set of in-game variables starting at Lfd04_script_video_pattern_ptr + ld hl, Lff01_building_decorations + ld de, Lff01_building_decorations + 1 + ld bc, 200 ; Potential optimization: change to 167 since only 168 bytes need to be cleared + ; here. + ld (hl), 0 + ldir + ld hl, Ld7d3_bullets + ld de, Ld7d3_bullets+1 + ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE - 1 + ld (hl), 0 + ldir + + ; Initialize variables: + ld hl, Ldd00_map + ld (Lfd06_scroll_ptr), hl + ld hl, 0 + ld (Lfd0a_scroll_x), hl + ld hl, 17 + ld (Lfd0e_player_x), hl ; set player start x + ld a, 10 + ld (Lfd0d_player_y), a ; set player start y + xor a + ld (Lfd10_player_altitude), a ; set player start altitude + ld a, 3 + ld (Lfd30_player_elevate_timer), a ; make the player float a bit right at game start + ld a, INITIAL_PLAYER_RESOURCES + ld (Lfd22_player1_resource_counts), a + ld (Lfd4a_player2_resource_counts), a + call Lbc6f_initialize_map + + +; -------------------------------- +; This is the main game loop: +La68e_game_loop_start: + call Lcfd7_draw_blank_map_in_buffer + call Ld0ca_draw_in_game_screen_and_hud + ld hl, Ld566_interrupt + ld (Lfdfe_interrupt_pointer), hl +La69a_game_loop: + call Ld37c_read_keyboard_joystick_input + call Laf11_player_ship_keyboard_control + call Lb0ca_update_robots_bullets_and_ai + call Lccbd_redraw_game_area + call Lad62_increase_time + call Lcca0_compute_player_map_ptr + bit 6, (hl) + jr z, La70d_game_loop_continue + call Lcdd8_get_robot_at_ptr + jr nz, La6c8_not_landed_on_a_robot + ld a, b + cp MAX_ROBOTS_PER_PLAYER + 1 ; if it's not one of the player's robots, ignore + jr c, La70d_game_loop_continue + ld a, (Lfd10_player_altitude) + sub (iy + ROBOT_STRUCT_HEIGHT) + sub (iy + ROBOT_STRUCT_ALTITUDE) + call z, La720_land_on_robot ; if we are right on top of the robot, control it! + jr La70d_game_loop_continue + +La6c8_not_landed_on_a_robot: + call Lcdf5_find_building_decoration_with_ptr + jr nz, La70d_game_loop_continue ; player is not on top of any ownable building + ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE) + or a + jr nz, La70d_game_loop_continue ; player is not on top of an "H" decoration + ld a, (Lfd10_player_altitude) + cp 15 + jr nz, La70d_game_loop_continue ; player is not at the right height + ld l, (iy + BUILDING_DECORATION_STRUCT_MAP_PTR) + ld a, (iy + BUILDING_DECORATION_STRUCT_MAP_PTR + 1) + add a, 8 + ld h, a + ; check for bit 6 in a 2x2 rectangle around the building map ptr, this is to + ; make sure the building is still there and not destroyed: + ld a, (hl) + inc h + inc h + or (hl) + dec hl + or (hl) + inc hl + inc hl + or (hl) + and #40 + jr nz, La70d_game_loop_continue ; not landed on a warbase + call Lc849_robot_construction_if_possible + ; Reset state of newly created robot: + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 4 ; more down by default + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 5 ; walk 5 steps after exiting the + ; base, and stop + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND + ld (iy + ROBOT_STRUCT_STRENGTH), 100 + ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), 1 + call Lbb40_count_robots + call Ld293_update_stats_in_right_hud +La70d_game_loop_continue: + ld a, (Lfd0c_keyboard_state) + bit 6, a ; restart key + jp nz, La600_start + bit 5, a ; save game key + jp z, La69a_game_loop + call Lc28d_save_game + jp La68e_game_loop_start + + +; -------------------------------- +; Player lands on a robot. +; Input: +; - iy: robot player landed on +La720_land_on_robot: + push iy + pop ix + ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_PLAYER_LANDED + ld a, 4 + ld (Lfd1f_cursor_position), a + ld a, 1 + ld (Lfd39_current_in_game_right_hud), a +La732_land_on_robot_internal: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #04, #17 + db CMD_SET_ATTRIBUTE, #4d + db "DIRECT " + db CMD_NEXT_LINE + db " CONTROL" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "GIVE " + db CMD_NEXT_LINE + db " ORDERS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "COMBAT " + db CMD_NEXT_LINE + db " MODE" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "LEAVE " + db CMD_NEXT_LINE + db " ROBOT" + db CMD_SET_POSITION, #11, #17 + db CMD_SET_ATTRIBUTE, #46 + db "-ORDERS-" + db CMD_END + ; script end: + ; Print the robot current orders in the hud: + ld b, (ix + ROBOT_STRUCT_ORDERS) + inc b + ld hl, La848_possible_robot_order_names - 27 + ld de, 27 +La79f_get_orders_name_loop: + add hl, de + djnz La79f_get_orders_name_loop + ; Copy the current orders to the script below, so we can draw it: + ld de, La7b2_current_orders_buffer + ld bc, 27 + ldir + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #12, #17 + db CMD_SET_ATTRIBUTE, #45 +La7b2_current_orders_buffer: + db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 + db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 + ; script end: + ld a, (ix + ROBOT_STRUCT_ORDERS) + dec a + cp 2 + jr nc, La7e4_no_miles + ; If there orders are advance/retreat, display the # of miles: + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #13, #19 + db CMD_END + ; script end: + ld a, (ix + ROBOT_STRUCT_ORDERS_ARGUMENT) + srl a + call Ld3e5_render_8bit_number +La7e4_no_miles: + call La81d_draw_robot_strength + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0037 + ld e, 5 + ld a, (Lfd1f_cursor_position) + call Lacd7_right_hud_menu_control + ld (Lfd1f_cursor_position), a + dec a + jp z, La93b_direct_control + dec a + jp z, La971_give_orders + dec a + jp z, Lac00_combat_mode + ld a, 120 + call Lccac_beep + xor a + ld (ix + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a + ld (ix + ROBOT_STRUCT_CONTROL), a ; robot controls itself again + ld a, 5 + ld (Lfd30_player_elevate_timer), a ; make the player float a bit after exiting a robot +La812_exit_robot: + call Ld2f6_clear_in_game_right_hud ; potential optimization: this line is not needed + xor a + ld (Lfd39_current_in_game_right_hud), a + call Ld1e5_draw_in_game_right_hud ; potential optimization: tail recursion + ret + + +; -------------------------------- +; Draws the remaining strength (hit points) of a robot. +La81d_draw_robot_strength: + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #16, #17 + db CMD_SET_ATTRIBUTE, #46 + db "STRENGTH" + db CMD_SET_POSITION, #17, #19 + db CMD_SET_ATTRIBUTE, #47 + db CMD_END + ; script end: + ld a, (ix + ROBOT_STRUCT_STRENGTH) + or a + jp p, La83b_positive_strength + xor a +La83b_positive_strength: + ld l, a + ld h, 0 + ld e, ' ' + call Ld401_render_16bit_number_3digits + ld a, '%' + jp Ld427_draw_character_saving_registers + + +; -------------------------------- +La848_possible_robot_order_names: + db " STOP " + db CMD_NEXT_LINE + db " AND " + db CMD_NEXT_LINE + db " DEFEND " + db CMD_END + + db "ADVANCE " + db CMD_NEXT_LINE + db " " + db CMD_NEXT_LINE + db " MILES " + db CMD_END + + db "RETREAT " + db CMD_NEXT_LINE + db " " + db CMD_NEXT_LINE + db " MILES " + db CMD_END + + db "DESTROY " + db CMD_NEXT_LINE + db " ENEMY " + db CMD_NEXT_LINE + db " ROBOTS " + db CMD_END + + db "DESTROY " + db CMD_NEXT_LINE + db " ENEMY " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_END + + db "DESTROY " + db CMD_NEXT_LINE + db " ENEMY " + db CMD_NEXT_LINE + db "WARBASES" + db CMD_END + + db "CAPTURE " + db CMD_NEXT_LINE + db "NEUTRAL " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_END + + db "CAPTURE " + db CMD_NEXT_LINE + db " ENEMY " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_END + + db "CAPTURE " + db CMD_NEXT_LINE + db " ENEMY " + db CMD_NEXT_LINE + db "WARBASES" + db CMD_END + + +; -------------------------------- +; Jumps to the direct-control interface, and goes back to the "land on robot" menu after that. +La93b_direct_control: + call La941_direct_control_internal + jp La732_land_on_robot_internal + + +; -------------------------------- +; Direct control of a robot. +La941_direct_control_internal: + ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_DIRECT_CONTROL + ld (ix + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 0 ; stop the automatic movement of the robot + call Lad57_wait_until_no_keys_pressed +La94c_direct_control_loop: + call Lb0ca_update_robots_bullets_and_ai + call Lccbd_redraw_game_area + call Lb048_update_radar + call Lad62_increase_time + call La81d_draw_robot_strength + ld a, (ix + 1) + or a + ret z ; If the robot is destroyed, exit. + call Ld37c_read_keyboard_joystick_input + and 16 ; If we press "fire", exit + jr z, La94c_direct_control_loop + ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_PLAYER_LANDED + ld a, 120 + call Lccac_beep + ret + + +; -------------------------------- +; This function implements the menu to give new orders to a robot. +La971_give_orders: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #04, #18 + db CMD_SET_ATTRIBUTE, #47 + db "SELECT" + db CMD_NEXT_LINE + db "ORDERS" + db CMD_SET_ATTRIBUTE, #4d + db CMD_SET_POSITION, #07, #17 + db "STOP AND" + db CMD_NEXT_LINE + db " DEFEND" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "ADVANCE " + db CMD_NEXT_LINE + db "?? MILES" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "RETREAT " + db CMD_NEXT_LINE + db "?? MILES" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "SEARCH &" + db CMD_NEXT_LINE + db " DESTROY" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "SEARCH &" + db CMD_NEXT_LINE + db " CAPTURE" + db CMD_END + ; script end: + call La81d_draw_robot_strength + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0097 ; ptr to the start of the menu attributes + ld e, 6 ; this menu has 5 options + ld a, 1 ; we start in option 1 + call Lacd7_right_hud_menu_control + push af + call Lad57_wait_until_no_keys_pressed + pop af + dec a + jr nz, Laa0c_no_stop_and_defend + ld (ix + ROBOT_STRUCT_ORDERS), a ; stop and defend + ld a, 120 + call Lccac_beep + jp La732_land_on_robot_internal +Laa0c_no_stop_and_defend: + cp 3 + jp nc, Laacf_give_capture_or_destroy_orders + ; We have selected advance or retreat: + ld (ix + ROBOT_STRUCT_ORDERS), a + push af + call Ld2f6_clear_in_game_right_hud + pop af + dec a + jr nz, Laa2f_retreat + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #05, #17 + db CMD_SET_ATTRIBUTE, #4f + db "ADVANCE " + db CMD_END + ; Script end: + jr Laa40_advance_or_retreat_drawn +Laa2f_retreat: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #05, #17 + db CMD_SET_ATTRIBUTE, #4f + db "RETREAT " + db CMD_END + ; Script end: +Laa40_advance_or_retreat_drawn: + call Ld42d_execute_ui_script + ; Script start: + db CMD_NEXT_LINE + db "?? MILES" + db CMD_SET_POSITION, #09, #17 + db CMD_SET_ATTRIBUTE, #45 + db " SELECT" + db CMD_NEXT_LINE + db "DISTANCE" + db CMD_SET_POSITION, #0d, #18 + db CMD_SET_ATTRIBUTE, #46 + db "0 MILES" + db CMD_END + ; Script end: + ld d, 0 ; 0 miles to start +Laa70_select_miles_loop: + push de + call La81d_draw_robot_strength + call Lb0ca_update_robots_bullets_and_ai + call Lccbd_redraw_game_area + call Lb048_update_radar + call Lad62_increase_time + pop de + ld a, (ix + 1) + or a ; If robot is destroyed, exit. + jp z, La812_exit_robot + call Ld37c_read_keyboard_joystick_input + bit 4, a + jr nz, Laab8_miles_selected ; If fire pressed + ld c, d + rrca + rrca + and 3 + jr z, Laa70_select_miles_loop ; if we have not pressed up/down + and 2 + ld b, a + add a, a + add a, a + add a, b + sub 5 ; If we have pressed up, a = 5, otherwise, a = -5 + add a, c ; c was storing the # of miles + cp 51 + jr nc, Laa70_select_miles_loop ; Limit miles to 50 + ld d, a ; update the # miles + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #0d, #17 + db CMD_SET_ATTRIBUTE, #46 + db CMD_END + ; Script end + ld a, d + call Ld3e5_render_8bit_number + ld a, 20 + call Lccac_beep + jr Laa70_select_miles_loop + +Laab8_miles_selected: + ld a, d + rlca ; multiply by 2: 1 mile == 2 coordinate units + ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), a ; set the number of miles to advance + or a + jr nz, Laac4 ; "advance/retreat 0 miles" is equivalent to stop and defend. + ld (ix + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND +Laac4: + ld a, 120 + call Lccac_beep + call Lad57_wait_until_no_keys_pressed + jp La732_land_on_robot_internal + +Laacf_give_capture_or_destroy_orders: + jp nz, Lab4e_give_capture_orders + ; Destroy: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #04, #17 + db CMD_SET_ATTRIBUTE, #4f + db "SEARCH &" + db CMD_NEXT_LINE + db " DESTROY" + db CMD_SET_POSITION, #08, #18 + db CMD_SET_ATTRIBUTE, #45 + db "SELECT" + db CMD_NEXT_LINE + db "TARGET" + db CMD_SET_POSITION, #0c, #17 + db CMD_SET_ATTRIBUTE, #4d + db "ENEMY " + db CMD_NEXT_LINE + db " ROBOTS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "ENEMY " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "ENEMY " + db CMD_NEXT_LINE + db "WARBASES" + db CMD_END + ; Script end + call La81d_draw_robot_strength + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0137 ; ptr to the attributes of the first menu option + ld a, 1 ; start at option 1 + ld e, 4 ; 3 options menu + call Lacd7_right_hud_menu_control + add a, ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS - 1 + jr Labc8_capture_or_destroy_order_selected + +Lab4e_give_capture_orders: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #04, #17 + db CMD_SET_ATTRIBUTE, #4f + db "SEARCH &" + db CMD_NEXT_LINE + db " CAPTURE" + db CMD_SET_POSITION, #08, #18 + db CMD_SET_ATTRIBUTE, #45 + db "SELECT" + db CMD_NEXT_LINE + db "TARGET" + db CMD_SET_POSITION, #0c, #17 + db CMD_SET_ATTRIBUTE, #4d + db "NEUTRAL " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "ENEMY " + db CMD_NEXT_LINE + db "FACTORYS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "ENEMY " + db CMD_NEXT_LINE + db "WARBASES" + db CMD_END + ; Script end: + call La81d_draw_robot_strength + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0137 ; ptr to the attributes of the first menu option + ld a, 1 ; start at option 1 + ld e, 4 ; 3 options menu + call Lacd7_right_hud_menu_control + add a, ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES - 1 + +Labc8_capture_or_destroy_order_selected: + ld (ix + ROBOT_STRUCT_ORDERS), a + cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES + jr c, Labd9_orders_executable + cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES + jr nc, Labd9_orders_executable + ; Player has selected to destroy factories or warbases. + ; For that purpose, the robot must be equipped with a nuclear weapon. + ; Check if it does, and otherwise, just cancel the order: + bit 6, (ix + ROBOT_STRUCT_PIECES) + jr z, Labf1_orders_not_executable +Labd9_orders_executable: + ld l, (ix + ROBOT_STRUCT_X) + ld h, (ix + ROBOT_STRUCT_X + 1) + push af + xor a + ld (Lfd51_current_robot_player_or_enemy), a + pop af + ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), #ff + call Lb34d_find_capture_or_destroy_target + ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), d + jr nz, Labf5_order_assignment_done +Labf1_orders_not_executable: + ld (ix + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND +Labf5_order_assignment_done: + ld a, 120 + call Lccac_beep + call Lad57_wait_until_no_keys_pressed + jp La732_land_on_robot_internal + + +; -------------------------------- +; Combat mode menu loop. +Lac00_combat_mode: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; Start script: + db CMD_SET_POSITION, #04, #17 + db CMD_SET_ATTRIBUTE, #4d + db "NUCLEAR " + db CMD_NEXT_LINE + db " BOMB" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "FIRE " + db CMD_NEXT_LINE + db " PHASERS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "FIRE " + db CMD_NEXT_LINE + db "MISSILES" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "FIRE " + db CMD_NEXT_LINE + db " CANNON" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "MOVE " + db CMD_NEXT_LINE + db " ROBOT" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "STOP " + db CMD_NEXT_LINE + db " COMBAT" + db CMD_END + ; End script: + call La81d_draw_robot_strength + ld a, 6 ; current option is the bottom +Lac81_combat_mode_loop: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0037 + ld e, 7 ; menu has 6 options + call Lacd7_right_hud_menu_control + cp 6 ; stop combat + jp z, La732_land_on_robot_internal + push af + cp 5 + jr nz, Lac99_weapon_fire_selected + call La941_direct_control_internal + pop af + jr Lac81_combat_mode_loop + +Lac99_weapon_fire_selected: + ld c, a + ld b, a + inc b + ld a, (ix + ROBOT_STRUCT_PIECES) +Lac9f: + rlca + djnz Lac9f + jr nc, Lacce_selected_weapon_not_present + pop af + cp 1 + jr nz, Lacb3_regular_weapon_fire + ; nuclear bomb selected: + push ix + pop iy + call Lb99f_fire_nuclear_bomb + jp La812_exit_robot + +Lacb3_regular_weapon_fire: + ; Weapon to fire is in "c" + push af + ; The first bullet record is used only for "combat mode". So, we only need to check if the + ; first bullet is available: + ld iy, Ld7d3_bullets + ld a, (iy + 1) + or a ; If there is already a weapon in use, we cannot fire + jr nz, Lacce_selected_weapon_not_present + ld a, 5 + sub c + call Lb6d6_weapon_fire + call Lccbd_redraw_game_area + call Lad62_increase_time + pop af + jp Lac81_combat_mode_loop + +Lacce_selected_weapon_not_present: + ld a, 250 + call Lccac_beep + pop af + jp Lac81_combat_mode_loop + + +; -------------------------------- +; Loop for moving around the options on a right-hand-side hud menu. +; Input: +; - a: cursor position. +; - e: number of options in the menu +Lacd7_right_hud_menu_control: + push af + call Lad57_wait_until_no_keys_pressed + pop af + ld d, a + ld c, COLOR_BRIGHT + COLOR_BLUE*PAPER_COLOR_MULTIPLIER + COLOR_YELLOW + call Lad3c_set_attributes_for_menu_option +Lace2_right_hud_menu_control_loop: + ld a, (ix + 1) ; check if the robot is destroyed + or a + jr nz, Lacec_robot_not_destroyed ; if the robot is not destroyed, continue + pop hl ; simulate a "ret" + jp La812_exit_robot +Lacec_robot_not_destroyed: + push hl + call Ld37c_read_keyboard_joystick_input + pop hl + ld c, d ; d still has the cursor position + ld a, (Lfd0c_keyboard_state) + bit 4, a ; is "fire" pressed + jr nz, Lad2f_menu_option_selected + rrca + and 6 + jr z, Lad1a_no_cursor_change ; neither up nor down are pressed + and 2 ; if pressing down, a = 2, otherwise, a = 0 + dec c ; more cursor up + add a, c ; if we pressed down, a = option + 1, otherwise, option - 1 + jr z, Lad1a_no_cursor_change ; if we pressed up and are at the top, no change + cp e + jr nc, Lad1a_no_cursor_change ; if we pressed down and we are at the bottom, no change + push af + ld a, d + ld c, COLOR_BRIGHT + COLOR_BLUE*PAPER_COLOR_MULTIPLIER + COLOR_CYAN + call Lad3c_set_attributes_for_menu_option + pop af + ld d, a + ld c, COLOR_BRIGHT + COLOR_BLUE*PAPER_COLOR_MULTIPLIER + COLOR_YELLOW + call Lad3c_set_attributes_for_menu_option + ld a, 20 + call Lccac_beep +Lad1a_no_cursor_change: + push de + push hl + ; Advance on game tick: + call Lb0ca_update_robots_bullets_and_ai + call Lccbd_redraw_game_area + call Lb048_update_radar + call Lad62_increase_time + call La81d_draw_robot_strength + pop hl + pop de + jr Lace2_right_hud_menu_control_loop +Lad2f_menu_option_selected: + ld a, d ; d still has the cursor position + ld c, COLOR_BRIGHT + COLOR_BLUE*PAPER_COLOR_MULTIPLIER + COLOR_WHITE + call Lad3c_set_attributes_for_menu_option + ld a, 100 + call Lccac_beep + ld a, d ; d still has the cursor position + ret + + +; -------------------------------- +; Sets a 8x2 block in the attribute table to attribute "c". This is used to set the attributes of +; menu options in the right-hand-side hud. +; Input: +; - c: attribute value to set +; - a: which row to change attributes for (each row is 3 screen rows apart). +; - hl: attribute address of the first row +Lad3c_set_attributes_for_menu_option: + ld b, a + push de + push hl + ld de, 32*3 +Lad42: + add hl, de + djnz Lad42 + ld b, 8 + call Lcbdb_set_attribute_loop ; set 8 attribute positions to attribute "c" + ld a, 24 + call Ld351_add_hl_a ; go one row down + ld b, 8 + call Lcbdb_set_attribute_loop ; set 8 attribute positions to attribute "c" + pop hl + pop de + ret + + +; -------------------------------- +; Waits until the user is not pressing any key. +Lad57_wait_until_no_keys_pressed: + push bc + push hl +Lad59_wait_for_key_release_loop: + call Ld37c_read_keyboard_joystick_input + or a + jr nz, Lad59_wait_for_key_release_loop + pop hl + pop bc + ret + + +; -------------------------------- +; - increases time by 5 minutes, and checks if a whole day has passed, to give resources to the +; players +Lad62_increase_time: + call Ld358_random + ld hl, Lfd35_minutes + ld a, (hl) + add a, 5 ; add 5 minutes + ld (hl), a + cp 60 + jr nz, Lad85_increase_time_done + ld (hl), 0 ; reset minutes + inc hl + inc (hl) ; increase hour + ld a, (hl) + cp 24 + jr nz, Lad85_increase_time_done + ld (hl), 0 ; reset hour + ld hl, (Lfd37_days) + inc hl ; increase days + ld (Lfd37_days), hl + call Lae38_gain_day_resources +Lad85_increase_time_done: + call Ld42d_execute_ui_script + ; Start script: + db CMD_SET_POSITION, #00, #1b + db CMD_SET_SCALE, #00 + db CMD_SET_ATTRIBUTE, #57 + db CMD_END + ; End script: + ld hl, (Lfd37_days) + call Ld3f3_render_16bit_number + call Ld470_execute_command_3_next_line + ld a, (Lfd36_hours) + call Ld3ec_render_8bit_number_with_leading_zeroes + ld a, 46 + call Ld427_draw_character_saving_registers + ld a, (Lfd35_minutes) + call Ld3ec_render_8bit_number_with_leading_zeroes + call Lae6b_game_over_check + push iy + ld iy, Lfd70_warbases + ld b, N_WARBASES + N_FACTORIES + ld c, 0 ; c keeps track of how many captures happened this cycle +Ladb7_building_loop: + ld l, (iy + BUILDING_STRUCT_X) + ld h, (iy + BUILDING_STRUCT_X + 1) + ld a, (iy + BUILDING_STRUCT_Y) + call Lcca6_compute_map_ptr + bit 6, (hl) ; check if building is still there + jr nz, Ladcd_something_in_front_of_it + ld (iy + BUILDING_STRUCT_TIMER), 0 + jr Lae05_next_building +Ladcd_something_in_front_of_it: + inc (iy + BUILDING_STRUCT_TIMER) + ld a, (iy + BUILDING_STRUCT_TIMER) + cp BUILDING_CAPTURE_TIME + jr c, Lae05_next_building + ; Something has been in front of the factory for BUILDING_CAPTURE_TIME cycles, capture! + ld (iy + BUILDING_STRUCT_TIMER), 0 + push bc + push iy + call Lcdd8_get_robot_at_ptr + ld a, (iy + ROBOT_STRUCT_CONTROL) + rlca + and 1 + ld e, a ; here e has the robot owner (0 = player, 1 = enemy AI) + pop iy + ld a, b ; if b == 0, no robot was found + or a + jr z, Lae04_next_building_pop + pop bc + inc c + push bc + ld a, N_FACTORIES + N_WARBASES + sub b + cp 4 + jr nc, Ladfe_factory + ld b, e + call Lbb86_assign_warbase_to_player ; warbase captured! + jr Lae04_next_building_pop +Ladfe_factory: + sub 4 + ld b, e + call Lbb61_assign_factory_to_player ; factory captured! +Lae04_next_building_pop: + pop bc +Lae05_next_building: + ; next building (as BUILDING_STRUCT_SIZE == 5): + inc iy + inc iy + inc iy + inc iy + inc iy + djnz Ladb7_building_loop + pop iy + ld a, c ; "c" has the number of buildings captured this cycle. + or a + jr z, Lae1d_no_new_captures + call Lbb09_update_players_warbase_and_factory_counts + call Ld293_update_stats_in_right_hud +Lae1d_no_new_captures: + ld a, (Lfd34_n_interrupts_this_came_cycle) + cp MIN_INTERRUPTS_PER_GAME_CYCLE + jr c, Lae1d_no_new_captures ; Loop to make sure games does not run too fast + xor a + ld (Lfd34_n_interrupts_this_came_cycle), a + ret + + +; -------------------------------- +; Unused/unreachable code: +; - I did not find anywhere in the code that could jump here. It could be some left-over code from +; a previous version of the game. +; - It does not make sense to jump to the BIOS address #04b0 from this game, in any case, since it +; contains BASIC-related code. So, this code can be removed. +Lae29: + ld a, INTERFACE2_JOYSTICK_PORT_MSB + in a, (ULA_PORT) ; read the interface2 joystick state + and #18 ; button 1 or "up" + ret nz + ld hl, La600_start + push hl + di + jp #04b0 + + +; -------------------------------- +; Update the resources each player has adding their daily gains, and updates the hud. +Lae38_gain_day_resources: + ld hl, Lfd22_player1_resource_counts + ld de, Lfd3a_player1_base_factory_counts + call Lae4e_gain_day_resources_player + ld hl, Lfd4a_player2_resource_counts + ld de, Lfd42_player2_base_factory_counts + call Lae4e_gain_day_resources_player + call Ld293_update_stats_in_right_hud + ret + + +; -------------------------------- +; - adds 5 times the number of bases to the general resources +; - adds 2 times the number of factories of each type to the part-specific resources +; input: +; - de: pointer to the # of bases and factories of a given player +; - hl: pointer to the resources of a given player +Lae4e_gain_day_resources_player: + ld a, (de) + ld c, a + add a, a + add a, a + add a, c ; a = (de)*5 + call Lae62_add_limit_100 ; (hl) += (de)*5 + ld b, 6 +Lae58_factory_loop: + inc hl + inc de + ld a, (de) + add a, a + call Lae62_add_limit_100 + djnz Lae58_factory_loop + ret + + +; -------------------------------- +; Adds a to (hl), keeping the result smaller than 100 +Lae62_add_limit_100: + add a, (hl) + cp 100 + jr c, Lae69_smaller_than_100 + ld a, 99 +Lae69_smaller_than_100: + ld (hl), a + ret + + +; -------------------------------- +; Checks if one of the players does not have any bases left, +; and shows the victory or defeat messages. +Lae6b_game_over_check: + ld a, (Lfd42_player2_base_factory_counts) + or a + jr z, Laeb1_game_over_victory + ld a, (Lfd3a_player1_base_factory_counts) + or a + ret nz + ; Game over defeat: + call Laf00_set_default_hud_and_empty_interrupt + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, 22, 0 + db CMD_SET_ATTRIBUTE, 69 + db "YOU HAVE NO BASES LEFT" + db CMD_NEXT_LINE + db "BETTER LUCK NEXT TIME!" + db CMD_END + ; script end: + jr Laeea_game_over_message_drawn +Laeb1_game_over_victory: + call Laf00_set_default_hud_and_empty_interrupt + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, 22, 0 + db CMD_SET_ATTRIBUTE, 69 + db " INSIGNIANS DESTROYED " + db CMD_NEXT_LINE + db " YOU HAVE WON ! " + db CMD_END + ; script end: +Laeea_game_over_message_drawn: + ; Produce a sound, wait for player to press some key, and restart the game. + ld a, 250 + call Lccac_beep + ld b, 100 ; wait 2 seconds +Laef1_wait_loop: + halt + djnz Laef1_wait_loop + call Lad57_wait_until_no_keys_pressed +Laef7_wait_for_any_key: + call Ld37c_read_keyboard_joystick_input + or a + jr z, Laef7_wait_for_any_key + jp La600_start + +Laf00_set_default_hud_and_empty_interrupt: + xor a + ld (Lfd39_current_in_game_right_hud), a + call Ld2f6_clear_in_game_right_hud ; Potential optimization: not needed, as this is already + ; called in the function below + call Ld1e5_draw_in_game_right_hud + ld hl, Ld59c_empty_interrupt + ld (Lfdfe_interrupt_pointer), hl + ret + + +; -------------------------------- +; Controls the player ship using keyboard. +Laf11_player_ship_keyboard_control: + call Lb01d_remove_player_from_map + ; If the player is pressing up/down, reduce the effect of Lfd30_player_elevate_timer: + ld a, (Lfd0c_keyboard_state) + and #0c ; down/up + jr z, Laf25_player_ship_keyboard_control_x ; Potential optimization: the following lines + ; implement a random behavior (reduce elevate timer + ; if you are pressing up/down) that can be removed. + ld a, (Lfd30_player_elevate_timer) + or a + jr z, Laf25_player_ship_keyboard_control_x + dec a + ld (Lfd30_player_elevate_timer), a + +Laf25_player_ship_keyboard_control_x: + ld a, (Lfd0c_keyboard_state) + and #03 + jr z, Laf77_player_ship_keyboard_control_y ; if left/right are not pressed + cp 3 + jr z, Laf77_player_ship_keyboard_control_y ; if left/right are pressed simultaneously + ld hl, (Lfd0e_player_x) + rrca + jr c, Laf42_move_right + ; Move left: + ld a, h + or a + jr nz, Laf3f + ld a, l + cp MIN_PLAYER_X + jr z, Laf77_player_ship_keyboard_control_y +Laf3f: + dec hl + jr Laf4c_move_player_if_no_collision +Laf42_move_right: + ld a, h + or a + jr z, Laf4b + ld a, l + cp MAX_PLAYER_X - 256 + jr z, Laf77_player_ship_keyboard_control_y +Laf4b: + inc hl +Laf4c_move_player_if_no_collision: + ld a, (Lfd0d_player_y) + call Lb052_check_player_collision + jr c, Laf57_collision + ld (Lfd0e_player_x), hl +Laf57_collision: + ; See if we need to scroll the map: + ld hl, (Lfd0e_player_x) + ld de, (Lfd0a_scroll_x) + xor a + sbc hl, de + ld a, l + cp 13 ; player in the left screen edge + jr nz, Laf67_no_scroll_left + dec de +Laf67_no_scroll_left: + cp 22 ; player in the right screen edge + jr nz, Laf6c_no_scroll_right + inc de +Laf6c_no_scroll_right: + ld (Lfd0a_scroll_x), de + ld hl, Ldd00_map + add hl, de + ld (Lfd06_scroll_ptr), hl + +Laf77_player_ship_keyboard_control_y: + ld a, (Lfd0d_player_y) + ld c, a + ld a, (Lfd0c_keyboard_state) + rrca + rrca + and #03 + jr z, Lafa2_player_ship_keyboard_control_altitude ; up/down not pressed + cp 3 + jr z, Lafa2_player_ship_keyboard_control_altitude ; up/down pressed simultaneously + rrca + jr nc, Laf8c_no_move_down ; no move down + inc c +Laf8c_no_move_down: + rrca + jr nc, Laf90_no_move_up + dec c +Laf90_no_move_up: + ld a, c + and #0f + jr z, Lafa2_player_ship_keyboard_control_altitude ; do not go beyond map borders + ld hl, (Lfd0e_player_x) + ld b, a + call Lb052_check_player_collision + jr c, Lafa2_player_ship_keyboard_control_altitude ; collision + ld a, b + ld (Lfd0d_player_y), a + +Lafa2_player_ship_keyboard_control_altitude: + ld a, (Lfd30_player_elevate_timer) + or a + jr z, Lafae_no_auto_elevate + dec a + ld (Lfd30_player_elevate_timer), a + jr Lafb5_elevate +Lafae_no_auto_elevate: + ld a, (Lfd0c_keyboard_state) + and #10 + jr z, Lafc3_gravity +Lafb5_elevate: + ld a, (Lfd10_player_altitude) + cp MAX_PLAYER_ALTITUDE + jr nc, Lafdb_continue + add a, 2 + ld (Lfd10_player_altitude), a + jr Lafdb_continue + +Lafc3_gravity: + ld a, (Lfd10_player_altitude) + dec a ; Player ship falls with gravity + jp m, Lafdb_continue + ld b, a + ld a, (Lfd0d_player_y) + ld hl, (Lfd0e_player_x) + call Lb052_check_player_collision + ld a, b + cp c + jr c, Lafdb_continue ; collision when going down + ld (Lfd10_player_altitude), a + +Lafdb_continue: + call Lafe6_radar_scroll + ld hl, Lfd1e_player_visible_in_radar ; Potential optimization: are these last lines needed? ( + ; this is already done in "Lb048_update_radar" each + ; cycle, so, maybe this just does even more blinking). + inc (hl) + call Lb024_add_player_to_map_and_update_radar ; Potential optimization: tail recursion. + ret + + +; -------------------------------- +; Check if we need to scroll the radar screen due to player movement. +Lafe6_radar_scroll: + ld hl, (Lfd0e_player_x) + ld a, (Lfd1b_radar_scroll_x_tile) + ld c, a + ld a, l + rr h + rra + srl a + srl a ; a = (Lfd0e_player_x) / 8 + sub c ; c = (Lfd0e_player_x) / 8 - (Lfd1b_radar_scroll_x_tile) + cp 2 ; if we are in the left-edge, scroll left + jr c, Lafff_radar_scroll_left + cp 14 ; if we are in the right-edge, scroll right + jr nc, Lb005_radar_scroll_right + ret +Lafff_radar_scroll_left: + ld a, c + sub 8 + ret m + jr Lb00b_update_radar_scroll +Lb005_radar_scroll_right: + ld a, c + add a, 8 + cp 56 + ret z +Lb00b_update_radar_scroll: + ld (Lfd1b_radar_scroll_x_tile), a + add a, a + add a, a + ld l, a + ld h, 0 + add hl, hl + ld (Lfd1c_radar_scroll_x), hl + ld a, 1 + ld (Lfd52_update_radar_buffer_signal), a + ret + + +; -------------------------------- +; Removes the player from the map (bit 7), and then draws the player in the radar view. +Lb01d_remove_player_from_map: + call Lcca0_compute_player_map_ptr + res 7, (hl) ; mark player is no longer here + jr Lb036_flicker_player_in_radar + + +; -------------------------------- +; Marks that the player is in the map (bit 7), and +; also updates the radar buffers with buildings/robots and player. +Lb024_add_player_to_map_and_update_radar: + call Lcca0_compute_player_map_ptr + set 7, (hl) ; mark player is here +Lb029_update_radar_view_if_necessary: + ; Update the radar view if necessary: + ld a, (Lfd52_update_radar_buffer_signal) + or a + jr z, Lb036_flicker_player_in_radar + call Ld5f8_update_radar_buffers + xor a + ld (Lfd52_update_radar_buffer_signal), a +Lb036_flicker_player_in_radar: + ld a, (Lfd1e_player_visible_in_radar) + and 1 + ret z ; Do not draw player in radar + ld hl, (Lfd0e_player_x) + ld a, (Lfd0d_player_y) + ld c, a + ld b, 0 + jp Ld65a_flip_2x2_radar_area + + +; -------------------------------- +; Increments whether the player is visible in the radar or not, and updates the radar. +Lb048_update_radar: + call Lb036_flicker_player_in_radar + ld hl, Lfd1e_player_visible_in_radar + inc (hl) + jp Lb029_update_radar_view_if_necessary + + +; -------------------------------- +; Checks whether there would be a collision with the player altitude in a 3x3 area +; centered around a given set of coordinates: +; Input: +; - hl: x +; - a: y +; Return: +; - carry flag: set for collision, unset for no collision. +Lb052_check_player_collision: + push hl + call Lcca6_compute_map_ptr + ex de, hl + ld c, 0 + call Lb096_get_map_altitude_including_robots_and_decorations + inc de ; x += 1 + call Lb096_get_map_altitude_including_robots_and_decorations + dec d + dec d ; y -= 1 + call Lb096_get_map_altitude_including_robots_and_decorations + dec de ; x -= 1 + call Lb096_get_map_altitude_including_robots_and_decorations + dec de ; x -= 1 + call Lb099_get_robot_or_decoration_altitude + inc d + inc d ; y += 1 + call Lb099_get_robot_or_decoration_altitude + inc d + inc d ; y += 1 + ld a, d + cp #fd ; edge of the map + jr nc, Lb084 + call Lb099_get_robot_or_decoration_altitude + inc de ; x += 1 + call Lb099_get_robot_or_decoration_altitude + inc de ; x += 1 + call Lb099_get_robot_or_decoration_altitude +Lb084: + ld a, (Lfd10_player_altitude) + cp c + pop hl + ret + + +; -------------------------------- +; Gets the altitude of a position in the map, and if it is higher +; than the current of value in "c", it gets updated. +; Input: +; - de: map pointer +; Output: +; - a: map altitude +; - c: max of "c" and map altitude in "de". +Lb08a_get_map_altitude: + ld a, (de) + and #1f + ld hl, Ld7bc_map_piece_heights + call Ld351_add_hl_a + ld a, (hl) + jr Lb0ab_max_of_a_and_c + + +; -------------------------------- +; Gets the altitude at a particular position, including robots and decorations. +; Input: +; - de: map pointer +; - c: initial altitude +; Output: +; - c: max of "c" and map altitude in "de" (including robots and decorations). +Lb096_get_map_altitude_including_robots_and_decorations: + call Lb08a_get_map_altitude +Lb099_get_robot_or_decoration_altitude: + ld h, d + ld l, e + bit 6, (hl) + ret z + push bc + call Lcdd8_get_robot_at_ptr + jr nz, Lb0b0_get_decoration_altitude + pop bc + ld a, (iy + ROBOT_STRUCT_HEIGHT) + add a, (iy + ROBOT_STRUCT_ALTITUDE) + ; jp Lb0ab_max_of_a_and_c + + +; -------------------------------- +; c = max(c, a) +Lb0ab_max_of_a_and_c: + cp c + jr c, Lb0af_c_larger + ld c, a +Lb0af_c_larger: + ret + + +; -------------------------------- +; Gets the altitude of a decoration (like a "flag") if present. +; Input: +; - de: map pointer +; - c: initial altitude +; Output: +; - c: max of "c" and decoration altitude in "de" if present. +Lb0b0_get_decoration_altitude: + call Lcdf5_find_building_decoration_with_ptr + pop bc + ret nz + ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE) + ld hl, Lb0c1_decoration_altitudes + call Ld351_add_hl_a + ld a, (hl) + jr Lb0ab_max_of_a_and_c + +Lb0c1_decoration_altitudes: + db #0f ; warbase "H" + db #16, #15, #15, #16, #16, #16 ; pieces on top of factories + db #19, #19 ; flags + + +; -------------------------------- +; Executes one update cycle for each robot and bullet in the game. +Lb0ca_update_robots_bullets_and_ai: + call Lb7f4_update_enemy_ai + ld b, MAX_ROBOTS_PER_PLAYER * 2 + ld iy, Lda00_player1_robots +Lb0d3_robot_update_loop: + push bc + ld a, (iy + 1) + or a + call nz, Lb0fa_robot_update ; If robot is not destroyed, execute one update cycle + ld de, ROBOT_STRUCT_SIZE + add iy, de + pop bc + djnz Lb0d3_robot_update_loop + ld iy, Ld7d3_bullets + ld b, MAX_BULLETS +Lb0e9_bullet_update_loop: + push bc + ld a, (iy + 1) + or a + call nz, Lb70d_bullet_update ; If there is a bullet, execute one update cycle + ld de, BULLET_STRUCT_SIZE + add iy, de + pop bc + djnz Lb0e9_bullet_update_loop + ret + + +; -------------------------------- +; Update cycle of a robot, checking if it has to be destroyed or not. +Lb0fa_robot_update: + ld a, (iy + ROBOT_STRUCT_STRENGTH) + or a + jr z, Lb116_robot_destroyed + jp p, Lb154_robot_ai_update + ; negative energy: robot is destroyed, so we are just going to make it blink + inc (iy + ROBOT_STRUCT_STRENGTH) + ld l, (iy + ROBOT_STRUCT_MAP_PTR) + ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1) + and 1 + jr nz, Lb113 + res 6, (hl) ; blink out + ret +Lb113: + set 6, (hl) ; blink in + ret +Lb116_robot_destroyed: + ld l, (iy + ROBOT_STRUCT_MAP_PTR) + ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1) + res 6, (hl) ; remove the mark in the map + ; Check if there is something in the map or not. If there is nothing in the map, + ; we will add some random garbage. + ld a, (hl) + inc hl + or (hl) + dec h + dec h + or (hl) + dec hl + or (hl) + inc h + inc h + and #3f + jr nz, Lb136_map_not_empty ; There is something in the map + call Ld358_random + and 1 + add a, 6 + call Lbd91_add_element_to_map ; Add some debris to the map +Lb136_map_not_empty: + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld c, (iy + ROBOT_STRUCT_Y) + ld a, (iy + ROBOT_STRUCT_CONTROL) + rlca + and 1 + ld b, a ; b = 0 if it's a player robot, and b = 1 if it's an enemy AI robot. + call Ld65a_flip_2x2_radar_area ; remove robot out of the map + ld (iy + 1), 0 ; mark the robot as removed + call Lbb40_count_robots + call Ld293_update_stats_in_right_hud ; Potential optimization: tail recursion. + ret + + +; -------------------------------- +; Update cycle for robots behavior. +; Input: +; - iy: robot ptr. +Lb154_robot_ai_update: + ld a, (iy + ROBOT_STRUCT_CONTROL) + cp ROBOT_CONTROL_PLAYER_LANDED + ret z ; If the player has landed on top of the robot, do not update + + rlca + and 1 + ld (Lfd51_current_robot_player_or_enemy), a + dec (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE) + ret nz ; if we do not yet need to update this robot, skip + + ld l, (iy + ROBOT_STRUCT_MAP_PTR) + ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1) + res 6, (hl) ; remove the mark of this robot in the map for now + push hl + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld c, (iy + ROBOT_STRUCT_Y) + ld a, (iy + ROBOT_STRUCT_CONTROL) + rlca + and 1 + ld b, a ; potential optimization: this was already computed above. + call Ld65a_flip_2x2_radar_area + pop hl + call Lb513_get_robot_movement_possibilities + ld a, (iy + ROBOT_STRUCT_CONTROL) + cp ROBOT_CONTROL_DIRECT_CONTROL + jp z, Lb450_robot_control_direct_control + push bc + call Lb626_check_directions_with_enemy_robots + pop bc + ld a, e + or a + jr z, Lb1e9_no_enemy_robots_in_sight + + and (iy + ROBOT_STRUCT_DIRECTION) + jr z, Lb1d7_no_enemy_robots_in_the_current_direction + ; If we are here, there is an enemy robot just ahead + and c + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), a + push ix + push iy + push iy + pop ix + call Lb6b8_find_new_bullet_ptr + jr nz, Lb1cd_do_not_fire + call Ld358_random ; pick one of our weapons at random + and #38 ; bits corresponding to weapons (cannon, missiles, phaser) + and (ix + ROBOT_STRUCT_PIECES) + jr z, Lb1cd_do_not_fire + ; Get the index of the lowest bit in "a" that is 1, corresponding to a weapon piece: + ld c, 6 +Lb1b7: + dec c + rlca + jr nc, Lb1b7 + ld a, c + call Lb6d6_weapon_fire + pop iy + pop ix + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 0 + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 1 + jr Lb20d_move_robot +Lb1cd_do_not_fire: + pop iy + pop ix + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 1 + jr Lb20d_move_robot +Lb1d7_no_enemy_robots_in_the_current_direction: + ld c, e + ld b, c + call Lb505_check_number_of_directions_is_one + call nz, Lb33e_pick_direction_at_random + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 2 + jp Lb20d_move_robot +Lb1e9_no_enemy_robots_in_sight: + dec (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING) + jp m, Lb1f5_move_in_a_new_direction + ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION) + and c + jr nz, Lb20d_move_robot +Lb1f5_move_in_a_new_direction: + ; pick a random number of steps: + call Ld358_random + and 3 + add a, 3 + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a + call Lb505_check_number_of_directions_is_one + call nc, Lb222_choose_direction_to_move + ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1) + or a + ret z + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c + +Lb20d_move_robot: + ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION) + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld b, (iy + ROBOT_STRUCT_Y) + call Lb471_move_robot_one_step_in_desired_direction + call Lb5f3_determine_speed_based_on_terrain + jp Lcc7c_set_robot_position + + +; -------------------------------- +; Chooses a direction for a robot to move to, considering the orders and target. +; Input: +; - iy: robot ptr. +; - c: one-hot representation of the directions we can to move the robot in. +; Output: +; - c: direction to move. +Lb222_choose_direction_to_move: + ld b, c + ld a, (iy + ROBOT_STRUCT_ORDERS) + or a + jr nz, Lb22b_choose_direction_to_move_continue + ld c, a ; if orders are "stop and defend", just set direction = 0 + ret + +Lb22b_choose_direction_to_move_continue: + cp ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS + jp c, Lb326_choose_direction_orders_with_possible_directions + jr nz, Lb289_choose_direction_orders_with_building_targets + + ; Destroy enemy robots orders: + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + or a + jp m, Lb258_find_new_robot_target + call Lb3f9_find_orders_target_robot_ptr + inc hl + ld a, (hl) + or a + jr z, Lb258_find_new_robot_target ; if our current target was already destroyed, pick a new one + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; hl now is target robot "x" + ld e, (iy + ROBOT_STRUCT_X) + ld d, (iy + ROBOT_STRUCT_X + 1) + call Lb3ca_distance_from_hl_to_de + ld a, h + or a + jr nz, Lb258_find_new_robot_target ; If robot target is too far, pick a new one. + ld a, l + cp 50 + jr c, Lb26d_choose_direction_to_target_robot ; If robot target is too far, pick a new one. +Lb258_find_new_robot_target: + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), #ff + push bc + call Lb41d_find_nearest_opponent_robot + pop bc + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d + jp z, Lb33e_pick_direction_at_random ; if no nearest robot, pick a direction at random. + +Lb26d_choose_direction_to_target_robot: + call Lb3f9_find_orders_target_robot_ptr + inc hl + inc hl + ld e, (hl) + inc hl + ld d, (hl) ; "de" now has the target robot "x" + inc hl + ld a, (iy + ROBOT_STRUCT_Y) + sub (hl) + ld b, a ; "b" now has "y" - "target robot y" + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + xor a + sbc hl, de ; "hl" now has "x" - "target robot x" + ld d, a ; "d" = 0 to indicate same x ("Lb2d5_choose_direction_to_target_coordinates" will + ; overwrite if they are not). + jr z, Lb2dc_choose_direction_to_target_coordinates_x_alread_considered + jr Lb2d5_choose_direction_to_target_coordinates + +Lb289_choose_direction_orders_with_building_targets: + ; If we are here, orders are to capture/destroy some building. + call Lb3d5_prepare_robot_order_building_target_search + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + ld b, a + add a, a + add a, a + add a, b ; a *= BUILDING_STRUCT_SIZE + call Ld351_add_hl_a ; hl has the pointer to the target + ld a, (hl) + and #e0 ; keep just the flags + cp e ; see if the flags match the orders target + jr z, Lb2bb_choose_direction_to_target_building + ; Pick a new target building: + ld a, (iy + ROBOT_STRUCT_ORDERS) + push bc + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + call Lb34d_find_capture_or_destroy_target + pop bc + jr nz, Lb2b8_target_found + ; We could not find any target: + ld c, 0 + bit 7, (iy + ROBOT_STRUCT_CONTROL) + ret z + ; if it's an enemy AI controlled robot, switch to targeting player robots: + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS + ret + +Lb2b8_target_found: + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d +Lb2bb_choose_direction_to_target_building: + ; Calculate the relative target coordinates: + dec hl + ld a, (iy + ROBOT_STRUCT_Y) + sub (hl) + ld b, a ; "b" now has "y" - "target robot y" + dec hl + ld d, (hl) + dec hl + ld e, (hl) + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + xor a + sbc hl, de ; "hl" now has "x" - "target robot x" + ld d, a ; "d" = 0 to indicate same x ("Lb2d5_choose_direction_to_target_coordinates" will + ; overwrite if they are not). + jr z, Lb2dc_choose_direction_to_target_coordinates_x_alread_considered + ld a, b + sub 3 + ld b, a +Lb2d5_choose_direction_to_target_coordinates: + ; At this point we have the relative position of the target to the robot in "hl", "b" + ld a, h + rrca + and #03 ; a = (h/2) mod 4 + xor 2 ; flip the second bit + ld d, a ; d = 1 if difference in "x" is negative, d = 2 if difference is positive +Lb2dc_choose_direction_to_target_coordinates_x_alread_considered: + ld a, b + or a + jr z, Lb2e8_target_directions_calculated + ; different y: + ; accumulate in "d" the good directions to go toward the target: + rrca + rrca + and #0c + xor 8 + or d + ld d, a ; d now has "1"s in the up/down directions pointing toward the target +Lb2e8_target_directions_calculated: + ld a, d + or a + jr nz, Lb306_not_at_target + ; We are at the target position: + ld c, a + ld a, (iy + ROBOT_STRUCT_ORDERS) + cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES + jr c, Lb2f9_inconsistent_orders + cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES + jp c, Lb99f_fire_nuclear_bomb +Lb2f9_inconsistent_orders: + ; If we reached here, something went wrong (we have orders ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS, + ; but are exactly on target, which is weird, so, just keep moving) + ld a, (iy + ROBOT_STRUCT_DIRECTION) + cp 4 + ret z + ld c, 4 ; desired direction is down, and go until collision, then reconsider. + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), #ff + ret +Lb306_not_at_target: + ; get the absolute difference of the "x" difference: + ld a, l + or a + jp p, Lb30e_x_diff_positive + neg + ld l, a +Lb30e_x_diff_positive: + cp 8 + ld b, c + ld a, d + jr nc, Lb326_choose_direction_orders_with_possible_directions ; if target is further than 8 + ; positions away follow the + ; target directions. + ; If we are closer than 8 cells (in "x") to the target, we will move at random until reaching + ; it: + and c + jr z, Lb33e_pick_direction_at_random ; if we have no good directions, pick one at random + ld b, a + and #03 + jr z, Lb33e_pick_direction_at_random ; If we cannot go left/right, pick a direction at random. + ld a, l + or a + jr z, Lb33e_pick_direction_at_random ; if we are at the same "x", pick a direction at random + dec a ; set the number of steps to keep walking to the distance to the target in "x" - 1 + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a + jr Lb33e_pick_direction_at_random + +Lb326_choose_direction_orders_with_possible_directions: + ; If we are here is that "a" has the good directions to move in. + and #03 + ld d, a + xor #fc ; here we reverse the up/down directions, to try something different if we fail to + ; pick a direction. + ld e, a + ld a, c ; c has the possible directions we can move in + and d ; if stop&defend, a = 0, if it's advance/retreat: a direction compatible with it if + ; available. + jr z, Lb33e_pick_direction_at_random ; if no direction compatible with orders, pick one at + ; random. + ; Otherwise, try twice to pick a direction among the ones that are compatible: + ld c, d + call Ld358_random + and d + ret nz ; first attempt + call Ld358_random + and d + ret nz ; second attempt + ld a, b ; b still has the available directions of movement + and e + ld b, a ; now b has compatible directions (with up/down flipped). So, we pick one at random + ; from those: + +Lb33e_pick_direction_at_random: + ld c, b + ; keep generating random numbers, and masking with the possible directions, + ; until we get just 1 direction, and use it: +Lb33f_pick_direction_at_random_loop: + call Ld358_random + and c + ld c, a + call Lb505_check_number_of_directions_is_one + ret z + jr nc, Lb33f_pick_direction_at_random_loop + ld c, b + jr Lb33f_pick_direction_at_random_loop + + +; -------------------------------- +; Finds the target for a capture or destroy order. This can be +; the index of a robot, or the index of a building. +; Input: +; - a: orders +; Output: +; - d: target. +; - z: no target found. +; - nz: target found. +Lb34d_find_capture_or_destroy_target: + cp ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS + jp z, Lb41d_find_nearest_opponent_robot + push af + ex af, af' + pop af + call Lb411_prepare_nearest_robot_or_building_search_registers + call Lb3d5_prepare_robot_order_building_target_search +Lb35b_building_loop: + ld a, (hl) + and #e0 + cp e ; check if they match the order target flags + call z, Lb36c_check_if_building_is_available_and_nearest_than_current_nearest + ; next building: + ld a, l + add a, BUILDING_STRUCT_SIZE + ld l, a + inc c + djnz Lb35b_building_loop + ld a, d ; d has the nearest building that was available as a target. + inc a ; check if we found a target (d == #ff means no target found). + ret + + +; -------------------------------- +; Given a building (index "c"), checks to make sure no other robot with the same +; orders as the current robot has that building as its target already. Then, if +; this is not the case, checks to see if this is closer than the previous target +; we had found. IF it is, set this building as the current target. +; Input: +; - a': orders +; - c: current building index +Lb36c_check_if_building_is_available_and_nearest_than_current_nearest: + push iy + push bc + push de + ex af, af' + ld e, a ; retrieve the orders + ex af, af' + ; Check if there is already another robot with the same orders, and that + ; already has this target: + ; Determine if we are searching over player or enemy robots: + ld iy, Lda00_player1_robots + ld a, (Lfd51_current_robot_player_or_enemy) + or a + jr z, Lb381_target_robots_ptr_set + ld iy, Ldb80_player2_robots +Lb381_target_robots_ptr_set: + ld b, MAX_ROBOTS_PER_PLAYER +Lb383: + ld a, (iy + 1) + or a + jr z, Lb395_next_robot + ld a, (iy + ROBOT_STRUCT_ORDERS) + cp e ; Check if robot has the same orders + jr nz, Lb395_next_robot + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + cp c ; check if the other robot already has this building as the target + jr z, Lb3ae_skip_building +Lb395_next_robot: + push de + ld de, ROBOT_STRUCT_SIZE + add iy, de + pop de + djnz Lb383 + pop de + pop bc + pop iy + ; If we reached this point, it means that there is no other robot that has + ; this building as its target. See if it's closer than the current closest: + push hl + dec hl + dec hl + ld a, (hl) + dec hl + ld l, (hl) + ld h, a + call Lb3b3_check_if_nearer_than_current_nearest + pop hl + ret +Lb3ae_skip_building: + pop de + pop bc + pop iy + ret + + +; -------------------------------- +; Check if the coordinate "hl" (x) is nearer than the current robot +; believed to be the nearest to the reference robot (only considering "x"). +; Input: +; - hl: x coordinate to check +Lb3b3_check_if_nearer_than_current_nearest: + push hl + exx + pop hl + call Lb3ca_distance_from_hl_to_de ; distance from "hl" to reference robot + ld a, h + cp b + jr c, Lb3c3_new_closest + jr nz, Lb3c8 + ld a, l + cp c + jr nc, Lb3c8 +Lb3c3_new_closest: + ld b, h ; update the "closest distance" + ld c, l + exx + ld d, c ; update the index of the closest robot + ret +Lb3c8: + exx + ret + + +; -------------------------------- +; Returns the absolute value of |hl - de|. +Lb3ca_distance_from_hl_to_de: + xor a + sbc hl, de + ret p + sub l + ld l, a + ld a, 0 + sbc a, h + ld h, a + ret + + +; -------------------------------- +; Given the orders of the current robot, prepares the registers to look for a potential +; target. +; Input: +; - a: robot orders +; Output: +; - hl: ptr to factories or warbases +; - b: # buildings to search +; - e: target flags (whether we are looking for friendly, enemy or neutral buildings). +Lb3d5_prepare_robot_order_building_target_search: + ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE + ld b, N_FACTORIES + cp ROBOT_ORDERS_DESTROY_ENEMY_WARBASES + jr z, Lb3e2_look_for_a_warbase + cp ROBOT_ORDERS_CAPTURE_ENEMY_WARBASES + jr nz, Lb3e7_continue +Lb3e2_look_for_a_warbase: + ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE + ld b, N_WARBASES +Lb3e7_continue: + ld e, #20 ; bit 5 (indicates enemy) + push af + ld a, (Lfd51_current_robot_player_or_enemy) + or a + jr z, Lb3f2_player + rlc e ; changes to bit 6 (indicates player) +Lb3f2_player: + pop af + cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES + ret nz + ld e, 0 ; if we are looking for neutral buildings, set e to 0 (neither player nor enemy) + ret + + +; -------------------------------- +; Gets the target robot index, based on the orders argument. +; Input: +; - iy: robot +; Output: +; - hl: ptr to target robot +Lb3f9_find_orders_target_robot_ptr: + ld de, Lda00_player1_robots + ld a, (Lfd51_current_robot_player_or_enemy) + or a + jr nz, Lb405_target_is_player_1 + ld de, Ldb80_player2_robots +Lb405_target_is_player_1: + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + add a, a + add a, a + add a, a + ld l, a + ld h, 0 + add hl, hl + add hl, de ; hl = Lda00_player1/2_robots + ROBOT_STRUCT_SIZE * argument + ret + + +; -------------------------------- +; Initializes some ghost registers for preparing to find the "closest" robot/building. +; - Copies "hl" to "de'" (x of the reference robot) +; - set "bc'" = 8192 (min distance) +; - c = 0 ; current robot/building we are checking +; - d = #ff ; will store the index of the closest robot/building +Lb411_prepare_nearest_robot_or_building_search_registers: + push hl + exx + pop de + ld bc, 8192 + exx + ld c, 0 + ld d, #ff + ret + + +; -------------------------------- +; Finds the opponent robot that is nearest to the current robot. +; Input: +; - iy: current robot ptr. +; Output: +; - d: nearest robot index. +; - z: no nearest robot. +; - nz: some nearest robot found. +Lb41d_find_nearest_opponent_robot: + call Lb411_prepare_nearest_robot_or_building_search_registers + push iy + ; Choose either "Lda00_player1_robots" or "Ldb80_player2_robots", + ; depending on whether the current robot belongs to player or enemy AI. + ld iy, Lda00_player1_robots ; if current robot is enemy, search through + ; "Lda00_player1_robots" + ld a, (Lfd51_current_robot_player_or_enemy) + or a + jr nz, Lb430 + ld iy, Ldb80_player2_robots ; if current robot is player, search through + ; "Lda00_player2_robots" +Lb430: + ld b, MAX_ROBOTS_PER_PLAYER +Lb432_loop_robot: + ld a, (iy + 1) + or a + jr z, Lb441_next_robot + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + call Lb3b3_check_if_nearer_than_current_nearest +Lb441_next_robot: + push de + ld de, ROBOT_STRUCT_SIZE + add iy, de + pop de + inc c ; next robot index + djnz Lb432_loop_robot + pop iy + ld a, d + inc a + ret + + +; -------------------------------- +; Updates a robot while we are moving it in combat mode. +; Input: +; - iy: robot ptr. +; - c: possible move directions (along which there would be no collision). +Lb450_robot_control_direct_control: + push bc + call Ld37c_read_keyboard_joystick_input + pop bc + ld b, c + cp (iy + ROBOT_STRUCT_DIRECTION) + ; Since when we are requesting the robot to turn, collisions do not matter, we do not filter + ; by collisions: + jr nz, Lb45c_keyboard_input_different_from_current_robot_direction + and c ; we filter keyboard input keys by those directions we can actually move the robot in. +Lb45c_keyboard_input_different_from_current_robot_direction: + ld c, a ; "c" now has the directions we want to move the robot towards, and are possible. + call Lb505_check_number_of_directions_is_one + jr z, Lb467_only_one_direction + ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION) ; get the current desired direction + and b ; "b" still had the possible move directions. + ld c, a ; if we can still move in the desired, keep moving, otherwise, stop. +Lb467_only_one_direction: + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c + ld a, c + ld (Lfd0c_keyboard_state), a ; overwrite the keyboard state with the filtered direction + jp Lb20d_move_robot + + +; -------------------------------- +; Moves the robot one step in the desired direction (if currently facing it), or rotates it if +; needed. +; Input: +; - a: robot desired move direction. +Lb471_move_robot_one_step_in_desired_direction: + or a + ret z ; If robot does not want to move, return. + cp (iy + ROBOT_STRUCT_DIRECTION) + jr z, Lb495 ; if robot is facing the right direction, just move + ; rotate robot: + ld c, a + or (iy + ROBOT_STRUCT_DIRECTION) + cp #03 + jr nz, Lb486 + rlc c ; because of the way they organized the direction bits, to rotate 90 degrees, we need to + ; shift the bits w positions. Potential optimization: all the direction code can be + ; greatly simplified if direction bits are reordered. + rlc c + jr Lb48e_new_direction_calculated +Lb486: + cp #0c + jr nz, Lb48e_new_direction_calculated + rrc c ; because of the way they organized the direction bits, to rotate 90 degrees, we need to + ; shift the bits w positions + rrc c +Lb48e_new_direction_calculated: + ; We now have the new robot direction: + ld (iy + ROBOT_STRUCT_DIRECTION), c + inc (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING) ; since this was not a move, it does + ; not count toward the # of steps we + ; want to move. + ret +Lb495: + ; Make the robot actually advance: + call Lb4b9_robot_advance + call Lb5d6_map_altitude_2x2 + ld (iy + ROBOT_STRUCT_ALTITUDE), a + ld a, (iy + ROBOT_STRUCT_CONTROL) ; update the altitude of the robot based on the terrain + ; underneath. + cp ROBOT_CONTROL_DIRECT_CONTROL + ret nz + ; If we are here it means the player is controlling the robot directly. + push bc + push hl + push iy + ; This just has the effect of making the player mimic the robot movement: + call z, Laf11_player_ship_keyboard_control ; Potential optimization: (not really an + ; optimization), the "z," is not needed. + pop iy + pop hl + pop bc + ld a, (iy + ROBOT_STRUCT_HEIGHT) + add a, (iy + ROBOT_STRUCT_ALTITUDE) + ld (Lfd10_player_altitude), a + ret + + +; -------------------------------- +; Moves a robot in the direction it wants to move, and update the +; order parameters in case they were advance or retreat. +; Input: +; - a: desired move direction (one-hot encoding) +Lb4b9_robot_advance: + rrca + jr nc, Lb4c7_not_right + ; move right: + inc hl + ld a, (iy + ROBOT_STRUCT_ORDERS) + dec a + jr z, Lb4f2_advance_in_direction_of_orders + dec a + jr z, Lb4de_advance_against_direction_of_orders + ret + +Lb4c7_not_right: + rrca + jr nc, Lb4d5_not_left + ; move left: + dec hl + ld a, (iy + ROBOT_STRUCT_ORDERS) + dec a + jr z, Lb4de_advance_against_direction_of_orders + dec a + jr z, Lb4f2_advance_in_direction_of_orders + ret + +Lb4d5_not_left: + rrca + jr nc, Lb4da_not_down + ; move down: + inc b + ret + +Lb4da_not_down: + rrca + ret nc + ; move up: + dec b + ret + +Lb4de_advance_against_direction_of_orders: + ; The robot moved against the direction it wants to go (e.g., its orders + ; were "retreat", but it moved to the right). So, we increment the argument + ; of the orders to compensate: + ld a, (iy + ROBOT_STRUCT_CONTROL) + cp ROBOT_CONTROL_DIRECT_CONTROL + ret z + inc (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + cp 100 + ret c ; do not go beyond 99 in the distance to travel. + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 99 + ret + +Lb4f2_advance_in_direction_of_orders: + ; The robot moved towards the direction it wants to go (e.g., its orders + ; were "retreat", and it moved to the left). So, we decrement the argument + ; of the orders to compensate: + ld a, (iy + ROBOT_STRUCT_CONTROL) + cp ROBOT_CONTROL_DIRECT_CONTROL + ret z + dec (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + ret nz + ; When the robot advances/retreats the desired number of miles, + ; switch to "stop & defend": + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 0 + ret + + +; -------------------------------- +; Counts the number of bits in the lower nibble of "c" that are set to 1, and checks +; if there is only 1 such bit on. +; Input: +; - c: one-hot representation of the directions we want to move the robot in. +Lb505_check_number_of_directions_is_one +Lb505_count_number_of_active_bits_in_the_lower_nibble: + push bc + ld b, 4 ; only consider the lower 4 bis + xor a +Lb509_direction_loop: + rr c + adc a, 0 ; if the bit was set, increment a, otherwise do not increment. + djnz Lb509_direction_loop + pop bc + cp 1 ; check that the number of bits set to 1 was just 1. + ret + + +; -------------------------------- +; Checks which directions can a robot move in, and in which it will collide. +; Input: +; - iy: robot ptr. +; Output: +; - c: lower 4 bits indicate if robot can move right, left, up, down. +Lb513_get_robot_movement_possibilities: + ld c, 0 + ; Check if the player is above or below robot height, to see if the player + ; is an obstacle or not. + ld a, (Lfd10_player_altitude) + sub (iy + ROBOT_STRUCT_HEIGHT) + sub (iy + ROBOT_STRUCT_ALTITUDE) + and 128 ; If the player is lower than the robot height, player is also an obstable + or #40 + ld e, a ; e contains a mask to check if a given position in the map is not walkable due to + ; player or another robot. + ld a, (iy + ROBOT_STRUCT_PIECES) + ld d, 8 ; if chassis is bipod, d = 8 + rrca + jr c, Lb532 + ld d, 12 ; if chassis is tracks, d = 12 + rrca + jr c, Lb532 + ld d, 15 ; if chassis is antigrav, d = 15 +Lb532: + push hl + call Lb557_check_robot_collision_inc_x + pop hl + jr nz, Lb53b_collision_right + set 0, c ; mark that we can move to the right +Lb53b_collision_right: + push hl + call Lb56f_check_robot_collision_dec_x + pop hl + jr nz, Lb544_collision_left + set 1, c ; mark that we can move to the left +Lb544_collision_left: + push hl + call Lb58f_check_robot_collision_inc_y + pop hl + jr nz, Lb54d_collision_down + set 2, c ; mark that we can move down +Lb54d_collision_down: + push hl + call Lb5b1_check_robot_collision_dec_y + pop hl + jr nz, Lb556_up + set 3, c ; mark that we can move up +Lb556_up: + ret + + +; -------------------------------- +; Checks if a robot can walk to the right (incrementing x). +; Input: +; - hl: map pointer +; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk +; over). +; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable). +; But it could be #c0 when the player is lower than the height of the robot in consideration, +; to consider the player as an obstacle. +Lb557_check_robot_collision_inc_x: + inc hl + inc hl ; x += 2 + dec h + dec h ; y -= 1 + call Lb5cd_robot_map_collision_internal + ret nz ; collision + inc h ; y += 1 + inc h + call Lb5cd_robot_map_collision_internal + ret nz ; collision + inc h ; y += 1 + inc h + ld a, h + cp #fd ; check if we are out of map bounds + jr nc, Lb5c8_no_collision + ld a, (hl) + and e + ret + + +; -------------------------------- +; Checks if a robot can walk to the left (decrementing x). +; Input: +; - hl: map pointer +; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk +; over). +; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable). +; But it could be #c0 when the player is lower than the height of the robot in consideration, +; to consider the player as an obstacle. +Lb56f_check_robot_collision_dec_x: + dec h ; y -= 1 + dec h + dec hl ; x -= 1 + call Lb5cd_robot_map_collision_internal + ret nz ; collision + dec hl ; x -= 1 + ld a, (hl) + and e + ret nz ; collision + inc h ; y += 1 + inc h + ld a, (hl) + and e + ret nz ; collision + inc hl ; x += 1 + call Lb5cd_robot_map_collision_internal + ret nz ; collision + dec hl ; x -= 1 + inc h + inc h ; y += 1 + ld a, h + cp #fd ; check if we are out of map bounds + jr nc, Lb5c8_no_collision + ld a, (hl) + and e + ret + + +; -------------------------------- +; Checks if a robot can walk down (incrementing y). +; Input: +; - hl: map pointer +; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk +; over). +; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable). +; But it could be #c0 when the player is lower than the height of the robot in consideration, +; to consider the player as an obstacle. +Lb58f_check_robot_collision_inc_y: + inc h ; y += 1 + inc h + ld a, h + cp #fd + jr nc, Lb5ca_collision ; check if we are out of map bounds + call Lb5cd_robot_map_collision_internal + ret nz + inc hl ; x += 1 + call Lb5cd_robot_map_collision_internal + ret nz + inc h ; y += 1 + inc h + ld a, h + cp #fd ; check if we are out of map bounds + jr nc, Lb5c8_no_collision + ld a, (hl) + and e + ret nz + dec hl ; x -= 1 + ld a, (hl) + and e + ret nz + dec hl ; x -= 1 + ld a, (hl) + and e + ret + + +; -------------------------------- +; Checks if a robot can walk up (decrementing y). +; Input: +; - hl: map pointer +; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk +; over). +; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable). +; But it could be #c0 when the player is lower than the height of the robot in consideration, +; to consider the player as an obstacle. +Lb5b1_check_robot_collision_dec_y: + dec h + dec h ; y -= 1 + dec h + dec h ; y -= 1 + ld a, h + cp #dd ; check if we are out of map bounds + jr c, Lb5ca_collision + dec hl ; x -= 1 + ld a, (hl) + and e + ret nz + inc hl ; x += 1 + call Lb5cd_robot_map_collision_internal + ret nz + inc hl ; x += 1 + call Lb5cd_robot_map_collision_internal + ret +Lb5c8_no_collision: + xor a + ret +Lb5ca_collision: + or 1 + ret + + +; -------------------------------- +; Check if a given position in the map is walkable by the chassis of a robot. +; This is checked by seeing if the element in the map is < "d". +; Input: +; - hl: map pointer +; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk +; over). +; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable). +; But it could be #c0 when the player is lower than the height of the robot in consideration, +; to consider the player as an obstacle. +Lb5cd_robot_map_collision_internal: + ld a, (hl) + and #1f + cp d + jr nc, Lb5ca_collision ; map element is not walkable by the current chassis. + ld a, (hl) + and e ; check for objects (robots and potentially the player) + ret + + +; -------------------------------- +; Get highest altitude of 2x2 map area: +; input: +; - hl: x +; - b: y +; Output: +; - a: altitude +Lb5d6_map_altitude_2x2: + push hl + push bc + ld a, b + call Lcca6_compute_map_ptr + ex de, hl + ld c, 0 + call Lb08a_get_map_altitude + inc de + call Lb08a_get_map_altitude + dec d + dec d + call Lb08a_get_map_altitude + dec de + call Lb08a_get_map_altitude + ld a, c + pop bc + pop hl + ret + + +; -------------------------------- +; Determines how many cycles will the robot need to take to move +; depending on the terrain it is on. +; Input: +; - iy: robot pointer +Lb5f3_determine_speed_based_on_terrain: + push bc + push hl + ld a, (iy + ROBOT_STRUCT_ALTITUDE) + ld c, 0 ; flat terrain + or a + jr z, Lb605_terrain_type_determined + ld c, 3 ; rugged + cp 4 + jr c, Lb605_terrain_type_determined + ld c, 6 ; mountains +Lb605_terrain_type_determined: + ld a, (iy + ROBOT_STRUCT_PIECES) + ld d, 255 +Lb60a_determine_chassis_loop: + inc d + rrca + jr nc, Lb60a_determine_chassis_loop + ld a, c + add a, d + ld hl, Lb61d_robot_movement_speed_table + call Ld351_add_hl_a + ld a, (hl) + ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), a + pop hl + pop bc + ret + +; How many cycles does the robot take to move in the different terrains, +; depending on its chassis: +Lb61d_robot_movement_speed_table: + ; bipod, tracks, anti-grav + db #06, #04, #03 ; flat terrain + db #08, #06, #03 ; rugged + db #09, #07, #04 ; mountains + + +; -------------------------------- +; Looks in the 4 cardinal directions to see if in any of them there are enemy robots +; that we could fire at. +; Input: +; - iy: robot ptr. +; Output: +; - e: one-hot representation of the directions where enemy robots can be found. +Lb626_check_directions_with_enemy_robots: + ld e, 0 ; will accumulate the directions in which there are enemy robots in line. + ld d, 8 ; initial direction (up in a one-hot encoded representation) +Lb62a_loop_direction: + rlc e + ld l, (iy + ROBOT_STRUCT_MAP_PTR) + ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1) + ld b, 8 ; distance to check in directions we are not facing + ld a, d + cp (iy + ROBOT_STRUCT_DIRECTION) + jr nz, Lb666_simple_check + ld b, 10 ; look a bit further in the direction we are facing + bit 7, (iy + ROBOT_STRUCT_PIECES) + jr z, Lb644 + ld b, 12 ; if robot has "electronics", it can see a bit further still. +Lb644: + ld a, d + and #03 + jr nz, Lb657 + ; Look along the y axis (left/right): + ld c, b ; store the max distance for later + dec hl ; check with an offset of 1 tile up + call Lb66e_check_if_enemy_robot_in_line + ld b, c ; restore the max distance + inc hl ; check with no offset + call Lb66e_check_if_enemy_robot_in_line + ld b, c ; restore the max distance + inc hl ; check with an offset of 1 tile down + jr Lb666_simple_check +Lb657: + ; Look along the x axis (up/down): + ld c, b ; store the max distance for later + dec h + dec h ; check with an offset of 1 tile left + call Lb66e_check_if_enemy_robot_in_line + ld b, c ; restore the max distance + inc h ; check with no offset + inc h ; check with an offset of 1 tile right + call Lb66e_check_if_enemy_robot_in_line + ld b, c ; restore the max distance + inc h + inc h +Lb666_simple_check: + ; Just check in a straight line without adjusting the offset: + call Lb66e_check_if_enemy_robot_in_line + rrc d ; next direction + jr nc, Lb62a_loop_direction + ret + + +; -------------------------------- +; Checks if there is an enemy robot in line with the current robot in the desired direction. +; Basically, to see if we fired a weapon in that direction, if we could hit an enemy robot. +; Input: +; - hl: map ptr. +; - b: maximum distance to check. +; - d: direction (one-hot representation). +; - e: current directions at which we found enemy robots. +; Output: +; - e: updated with whether we found an enemy robot in the current direction. +Lb66e_check_if_enemy_robot_in_line: + push hl + push de + push hl + ld hl, Lb6b0_direction_offsets - 2 + ld a, d + ; get the position from the Lb6b0_direction_offsets array corresponding to the + ; one-hot bit in "d", and store it in "de" +Lb675_get_word_loop: + inc hl + inc hl + rrca + jr nc, Lb675_get_word_loop + ld e, (hl) + inc hl + ld d, (hl) + pop hl + ; Keeps advancing in the desired direction until we get out of the map, + ; or we find an object. +Lb67e_raycast_loop: + add hl, de ; add the offset to the map ptr. + ld a, h + sub #dd + cp 16 * 2 + jr nc, Lb6ad_nothing_found ; out of bounds of the map + bit 6, (hl) + jr nz, Lb68e_object_found ; object found + djnz Lb67e_raycast_loop + jr Lb6ad_nothing_found + +Lb68e_object_found: + push iy + call Lcdd8_get_robot_at_ptr + ld a, (iy + ROBOT_STRUCT_CONTROL) + ld b, (iy + ROBOT_STRUCT_STRENGTH) + pop iy + jr nz, Lb6ad_nothing_found + xor (iy + ROBOT_STRUCT_CONTROL) + jp p, Lb6ad_nothing_found ; the robot has the same owner as the current robot. + dec b + jp m, Lb6ad_nothing_found ; the robot is already destroyed + pop de + ld a, e + or 1 + ld e, a ; potential optimization: these 3 instructions are just "set 0, e". + push de ; push just to make sure the next pop does not mess up the stack. +Lb6ad_nothing_found: + pop de +Lb6ae: + pop hl + ret + +Lb6b0_direction_offsets: + dw 1 ; right + dw -1 ; left + dw 512 ; down + dw -512 ; up + + +; -------------------------------- +; Find new bullet pointer. Friendly robots can only use bullets 1, and 2, +; and enemy robots bullets 3 and 4 (bullet 0 is reserved for player-controlled robots). +; Input: +; - ix: pointer to robot that is firing. +; Output: +; - iy: new bullet ptr +; - z: new bullet found +; - nz: no bullet slots available. +Lb6b8_find_new_bullet_ptr: + ld iy, Ld7d3_bullets + BULLET_STRUCT_SIZE + bit 7, (ix + ROBOT_STRUCT_CONTROL) + jr z, Lb6c7_player_robot + ld de, BULLET_STRUCT_SIZE * 2 + add iy, de +Lb6c7_player_robot: + ld a, (iy + 1) + or a + ret z ; first bullet is available + ; Try next bullet: + ld de, BULLET_STRUCT_SIZE + add iy, de + ld a, (iy + 1) + or a + ret + + +; -------------------------------- +; Spawns a new bullet on "iy". +; Input: +; - a: weapon to fire: 1: cannon, 2: missiles, 3: phasers. +; - iy: bullet pointer to use. +; - ix: pointer to robot that fired the weapon. +Lb6d6_weapon_fire: + ld (iy + BULLET_STRUCT_TYPE), a + ld c, WEAPON_RANGE_DEFAULT ; range + cp 2 ; missiles + jr nz, Lb6e1_not_missiles + ld c, WEAPON_RANGE_MISSILES ; missiles have an extended range +Lb6e1_not_missiles: + bit 7, (ix + ROBOT_STRUCT_PIECES) + jr z, Lb6e8_not_electronics + inc c ; electronics increase by one the weapon range +Lb6e8_not_electronics: + ld (iy + BULLET_STRUCT_RANGE), c + ld a, (ix + ROBOT_STRUCT_DIRECTION) + ld (iy + BULLET_STRUCT_DIRECTION), a + ld (iy + BULLET_STRUCT_ALTITUDE), 10 + ld l, (ix + ROBOT_STRUCT_X) + ld h, (ix + ROBOT_STRUCT_X + 1) + ld b, (ix + ROBOT_STRUCT_Y) + call Lb724_bullet_update_internal + ld a, (iy + 1) + or a + jr z, Lb70c + ld a, 1 + ld (Lfd53_produce_in_game_sound), a ; produce sound +Lb70c: + ret + + +; -------------------------------- +; Update cycle for bullets, including dealing damage to robots. +; Input: +; - iy: bullet ptr +Lb70d_bullet_update: + ld l, (iy + BULLET_STRUCT_MAP_PTR) + ld h, (iy + BULLET_STRUCT_MAP_PTR + 1) + res 6, (hl) ; remove the bullet from the map + dec (iy + BULLET_STRUCT_RANGE) ; decrease the lifetime of the bullet + jp z, Lb7ea_bullet_disappear ; if bullet has reached its maximum range, destroy it + ld l, (iy + BULLET_STRUCT_X) + ld h, (iy + BULLET_STRUCT_X + 1) + ld b, (iy + BULLET_STRUCT_Y) +Lb724_bullet_update_internal: + ; move the bullet in the direction of movement: + ld a, (iy + BULLET_STRUCT_DIRECTION) + rrca + jr nc, Lb72e_not_right + inc hl ; x += 2 + inc hl + jr Lb747_movement_complete +Lb72e_not_right: + rrca + jr nc, Lb735_not_left + dec hl ; x -= 2 + dec hl + jr Lb747_movement_complete +Lb735_not_left: + rrca + jr nc, Lb73c_not_down + inc b ; y += 2 + inc b + jr Lb741_check_out_of_map_in_y +Lb73c_not_down: + rrca + jr nc, Lb747_movement_complete + dec b ; y -= 2 + dec b +Lb741_check_out_of_map_in_y: + ; Notice that we only need to check out of bounds in the y axis, as, in the x axis, there's + ; always obstacles at the ends of the map, so, we don't need to check. + ld a, b + cp MAP_WIDTH + jp nc, Lb7ea_bullet_disappear ; if y > 16 or < 0, make it disappear. +Lb747_movement_complete: + ld (iy + BULLET_STRUCT_X), l + ld (iy + BULLET_STRUCT_X + 1), h + ld (iy + BULLET_STRUCT_Y), b + ; Check if the bullet collided with the map: + call Lb5d6_map_altitude_2x2 + cp (iy + BULLET_STRUCT_ALTITUDE) + jp nc, Lb7ea_bullet_disappear ; collision + ld a, b + ; Calculate the new map pointer given the new position: + call Lcca6_compute_map_ptr + ld (iy + BULLET_STRUCT_MAP_PTR), l + ld (iy + BULLET_STRUCT_MAP_PTR + 1), h + push hl + dec hl ; x -= 1 + dec h ; y -= 1 + dec h + ld a, h + cp #dd ; check if the pointer is out of the map area + jr c, Lb77c_continue ; out of bounds in that direction, so, we can skip a few collision + ; checks. + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl ; x += 1 + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl ; x += 1 + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + dec hl ; restore the x coordinate + dec hl +Lb77c_continue: + inc h ; y += 1 + inc h + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl ; x += 1 + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl ; x += 1 + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + dec hl ; x -= 2 + dec hl + inc h ; y += 1 + inc h + ld a, h + cp #fd ; check if the pointer is out of the map area + jr nc, Lb7a3_no_robot_collision + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot + inc hl + bit 6, (hl) + jr nz, Lb7a7_potentially_hit_a_robot +Lb7a3_no_robot_collision: + pop hl + set 6, (hl) ; we mark the bullet in the map again + ret +Lb7a7_potentially_hit_a_robot: + push iy + ld e, (iy + BULLET_STRUCT_TYPE) + ld c, 252 ; c determines the SFX that will be played with this event + call Lcdd8_get_robot_at_ptr + jr nz, Lb7de_collision_handled + ld a, (iy + ROBOT_STRUCT_STRENGTH) + dec a + jp m, Lb7de_collision_handled ; robot was already destroyed + ; Determine the damage dealt: + ld a, 60 + sub (iy + ROBOT_STRUCT_HEIGHT) + sub (iy + ROBOT_STRUCT_ALTITUDE) + srl a + srl a + ld d, a ; d = "base damage" = (60 - (robot height + altitude)) / 4 + ld b, e ; bullet type (1: cannon, 2: missiles, 3: phaser) +Lb7c8_damage_calculation_loop: + add a, d + djnz Lb7c8_damage_calculation_loop + ; Here a = 2x base damage for cannon, 3x for missiles, and 4x for phasers. + ld b, a + ld c, 250 ; sfx + ld a, (iy + ROBOT_STRUCT_STRENGTH) + sub b ; deal damage + jr z, Lb7d7_robot_destroyed + jp p, Lb7db_robot_hit +Lb7d7_robot_destroyed: + ld a, -4 ; mark negative strength, which will make the robot blink before being + ; destroyed. + ld c, 200 ; sfx +Lb7db_robot_hit: + ld (iy + ROBOT_STRUCT_STRENGTH), a ; update robot health +Lb7de_collision_handled: + pop iy + pop hl + ld (iy + BULLET_STRUCT_MAP_PTR + 1), 0 ; make the bullet disappear + ld a, c + ld (Lfd53_produce_in_game_sound), a ; produce sound + ret + + +; -------------------------------- +; Make a bullet disappear. +; Input: +; - iy: bullet pointer. +Lb7ea_bullet_disappear: + ld (iy + 1), 0 + ld a, -4 + ld (Lfd53_produce_in_game_sound), a ; produce sound + ret + + +; -------------------------------- +; Enemy AI update cycle. It works as follows: +; - with probability 0.25 it does nothing. +; - it then tries to pick a robot at random (from the set of 24 possible robots). +; - if it's an active robot, it will control it via "Lb920_enemy_ai_single_robot_control" +; - otherwise, it picks a random warbase +; - if it belongs to the enemy, it will try to produce a random robot with come constraints. +; - if any of the constraints is violated, then the enemy AI will just do nothing. +; - otherwise, it will construct the robot with "stop & defend" orders, and wait for it +; to be randomly picked up later to be assigned new orders. +Lb7f4_update_enemy_ai: + call Ld358_random + and #1f + cp MAX_ROBOTS_PER_PLAYER + ret nc ; with 0.25 probability the enemy AI does nothing. + ; Use the generated random number to get the pointer of a robot at random: + add a, a + add a, a + add a, a + ld l, a + ld h, 0 + add hl, hl + ld de, Ldb80_player2_robots + add hl, de + push hl + pop iy ; iy now has the pointer to a random robot from the enemy AI. + ld a, 1 + ld (Lfd51_current_robot_player_or_enemy), a + ; Check if the pointer corresponds to an active robot: + ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1) + or a + jp nz, Lb920_enemy_ai_single_robot_control + + ; pick a random warbase otherwise: + ld b, N_WARBASES + ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE +Lb81b_pick_random_warbase_loop: + call Ld358_random + and 1 + jr z, Lb827_next_warbase + ld a, (hl) + cp #20 + jr z, Lb0ca_enemy_ai_control_warbase ; also ensures it's a warbase +Lb827_next_warbase: + ld a, BUILDING_STRUCT_SIZE + call Ld351_add_hl_a + djnz Lb81b_pick_random_warbase_loop + ; no warbase selected + ret + +Lb0ca_enemy_ai_control_warbase: + ; Notice that if we reached here, "iy" has the pointer to an empty + ; robot position. + dec hl + ld b, (hl) + dec hl + ld a, (hl) + dec hl + ld l, (hl) + ld h, a ; hl = x coordinate, b = y coordinate + ld a, b + push hl + exx + pop hl + ld b, a ; hl = x coordinate, b = y coordinate in both ghost and regular registers + ; this is to set the robot coordinates below. + exx + call Lcca6_compute_map_ptr + ; Check if the entrance to the warbase is blocked: + push hl + ld a, (hl) + inc h + inc h + or (hl) + dec hl + or (hl) + inc hl + inc hl + or (hl) + and #40 + pop hl + ret nz ; if there is something blocking the entrance of the warbase, exit. + call Ld358_random ; Note: not sure why calling random twice. + call Ld358_random + ld c, a ; save the random number for later + ld (iy + ROBOT_STRUCT_PIECES), a + and 7 + cp 1 ; bipod + jr z, Lb864_correct_chasis + cp 2 ; tracks + jr z, Lb864_correct_chasis + cp 4 ; antigrav + ret nz ; if we picked more than one chassis, just return. +Lb864_correct_chasis: + ld a, c ; restore the random number + rrca + rrca + rrca + and #0f + ret z ; if we picked no weapon, just return. + cp #f + ret z ; if we picked too many weapons (only 3 allowed), just return. + ld c, a ; save the weapon selection + ld a, (Lfd49_player2_robot_count) + rrca + rrca + rrca + inc a + and 3 + ld b, a ; enemy # of robots / 8 + 1 + call Lb505_count_number_of_active_bits_in_the_lower_nibble + cp b + ret c ; the first 8 robots, can at most have 1 weapon, the next 8 can have two, etc. + + ; Check if player 2 has enough resources: + ld hl, Lfd4a_player2_resource_counts + ld de, Lfd29_resource_counts_buffer + ld bc, 7 + ldir + ld c, (iy + ROBOT_STRUCT_PIECES) + ld d, 0 ; how many "general resources" will we need to use. + ld b, 8 +Lb890_check_resource_availability_loop: + rrc c + jr nc, Lb8b8_next_piece + ld a, 8 + sub b + push af + ld hl, Lcaf0_piece_costs + call Ld351_add_hl_a + ld e, (hl) ; cost of the piece + pop af + ld hl, Lcaf8_piece_factory_type + call Ld351_add_hl_a + ld a, (hl) ; type of factory that can produce this piece + ld hl, Lfd29_resource_counts_buffer + call Ld351_add_hl_a + ld a, (hl) + sub e + jp p, Lb8b7_no_need_for_general_resources + neg + add a, d ; add the left over to the general resources cost + ld d, a + xor a ; zero out the resources we have left for this factory type. +Lb8b7_no_need_for_general_resources: + ld (hl), a +Lb8b8_next_piece: + djnz Lb890_check_resource_availability_loop + ; Check that we have enough general resources: + ld hl, Lfd29_resource_counts_buffer + ld a, (hl) + srl a + cp 11 + jr nc, Lb8c6_more_than_22_resources_left + ld a, 11 +Lb8c6_more_than_22_resources_left: + cp d + ret c ; The maximum general resources we can spend on a robot is half of the amount we have ( + ; except if we need to spend less or equal to 11). + + ld a, (hl) + sub d + ret m ; we do not have enough resources to build the robot, return. + + ; subtract the costs from the actual player 2 resources: + ld (hl), a + ld de, Lfd4a_player2_resource_counts + ld bc, 7 + ldir + + ; Start the robot! + ld (iy + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_ENEMY_AI ; mark the owner + exx + call Lcc7c_set_robot_position ; set position + exx + ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 4 ; by default move down (to exit the warbase) + ld (iy + ROBOT_STRUCT_DIRECTION), 4 + ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 3 + ld (iy + ROBOT_STRUCT_ALTITUDE), 0 + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND + ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), 1 + ld (iy + ROBOT_STRUCT_STRENGTH), 100 + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 255 + ; calculate robot height (when a player constructs it, this is calculated in the robot editing + ; UI): + ld c, (iy + ROBOT_STRUCT_PIECES) + ld b, 8 + ld d, 0 +Lb904_robot_height_loop: + rrc c + jr nc, Lb914_next_piece + ld a, 8 + sub b + ld hl, Ld7b4_piece_heights + call Ld351_add_hl_a + ld a, (hl) + add a, d + ld d, a +Lb914_next_piece: + djnz Lb904_robot_height_loop + ld (iy + ROBOT_STRUCT_HEIGHT), d + call Lbb40_count_robots + call Ld293_update_stats_in_right_hud + ret + + +; -------------------------------- +; If the robot already has orders (!= from "stop & defend"): +; - with a 1 / 32 chance they will be kept. +; - if the robot target is of the type it was looking for, a new order will be given (note: I think +; this is a bug, look my other note below). +; - if the robot has not reached the target, a new order will be given. +; If new orders are to be given: +; - if robot has nuclear, it will try to randomly go and destroy player factories/warbases. +; - otherwise, capture neutral/player factories or player warbases. +; - if it cannot find a target, then destroy player robots. +; Input: +; - iy: robot ptr. +Lb920_enemy_ai_single_robot_control: + ld a, (iy + ROBOT_STRUCT_ORDERS) + or a + jr z, Lb95d_assign_new_orders ; if current orders are stop & defend + + ; The robot already had orders different from stop & defend. + ld b, a + call Ld358_random + and #1f + ret nz ; 1 / 32 chance to keep the same orders the robot still has. + ld a, b + cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES + jr c, Lb95d_assign_new_orders ; if orders where stop & defend, advance, retreat or destroy + ; robots, assign new orders. + + ; Otherwise, look for a target: + ld a, (iy + ROBOT_STRUCT_ORDERS) + call Lb3d5_prepare_robot_order_building_target_search + ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT) + ld b, a + add a, a + add a, a + add a, b + call Ld351_add_hl_a ; hl now contains a pointer to the target building type flag + ld a, (hl) + and #e0 + cp e ; compare if the target flags are the same as we are looking for. + jr z, Lb95d_assign_new_orders ; if the robot's target was a correct one, assign new orders ( + ; note: this is strange, I think this is a bug, and it was meant + ; to be "nz"). + ; Now check, if the robot has arrived to the target, keep orders, otherwise, change. + dec hl + ld a, (iy + ROBOT_STRUCT_Y) + sub (hl) + jr nz, Lb95d_assign_new_orders ; if the target is not in the same "y" coordinate, assign new + ; orders. + dec hl + ld d, (hl) + dec hl + ld e, (hl) + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + xor a + sbc hl, de + ret z ; if the robot is in the same "x" coordinate as the target, keep the orders! + +Lb95d_assign_new_orders: + ; Randomly assigns a robot to destroy/capture factories or warbases. + ; - destroy if the robot has nuclear, and capture if it does not. + ; - in case it cannot find a target for the random orders it was assigned, it will just + ; be tasked to destroy player robots. + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS ; Potential optimization: + ; this assignment will always + ; be overwritten. So, it can + ; be eliminated. + bit 6, (iy + ROBOT_STRUCT_PIECES) + jr z, Lb976_robot_does_not_have_nuclear + ; robot has nuclear: + ; randomly assign it to destroy either player factories or player warbases: + call Ld358_random + ld b, a + rlca + or b + and 1 + add a, ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES + ld (iy + ROBOT_STRUCT_ORDERS), a + jr Lb989_new_orders_assigned + +Lb976_robot_does_not_have_nuclear: + ; Randomly assign it to capture: neutral factories, enemy factories or enemy warbases: + ld c, ROBOT_ORDERS_STOP_AND_DEFEND + call Ld358_random + rrca + jr c, Lb983 + inc c + rrca + jr c, Lb983 + inc c +Lb983: + ld a, c + add a, ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES + ld (iy + ROBOT_STRUCT_ORDERS), a + +Lb989_new_orders_assigned: + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 255 + call Lb34d_find_capture_or_destroy_target + ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d + ret nz ; if target found, we are done. + ; Otherwise, just try to destroy enemy robots + ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS + ret + + +; -------------------------------- +; Nuclear bomb effect: destroys buildings and robots nearby and replace with debris. +; Input: +; - iy: robot pointer. +Lb99f_fire_nuclear_bomb: + ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE + ld c, 0 ; building index + ld de, #070a ; nuclear bomb effect radius for warbases (something in between a circle and a + ; square): + ; - maximum distance in each axis of 7 + ; - maximum sum of distances in each axis of 10 +Lb9a7_building_loop: + push hl + bit 7, (hl) ; check if the building is already destroyed. + jr nz, Lb9dd_skip_building + dec hl + ld a, c + cp N_WARBASES + ; Calculate the distance in the y axis between robot and building. + ld a, (iy + ROBOT_STRUCT_Y) + jr nc, Lb9b7_not_a_warbase + add a, 4 +Lb9b7_not_a_warbase: + inc a + sub (hl) + ; "a" now has the difference in the y axis, now calculate the absolute value: + jp p, Lb9be_positive_difference + neg +Lb9be_positive_difference: + ld b, a ; store the difference in y. + cp d + jr nc, Lb9dd_skip_building ; building is too far + ; calculate the distance in the x axis: + push de + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; building x + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) ; robot x + call Lb3ca_distance_from_hl_to_de + pop de + ld a, h + or a + jr nz, Lb9dd_skip_building ; too far + ld a, l + cp d + jr nc, Lb9dd_skip_building ; too far + add a, b + cp e ; check if the sum of distances is larger than 10 + jr c, Lb9f2_building_in_range_of_nuclear_bomb +Lb9dd_skip_building: + pop hl + ; next building + ld a, BUILDING_STRUCT_SIZE + call Ld351_add_hl_a + inc c + ld a, c + cp 4 + jr c, Lb9a7_building_loop + ld de, #0507 ; nuclear bomb effect radius for factories (something in between a circle and a + ; square): + ; - maximum distance in each axis of 5 + ; - maximum sum of distances in each axis of 7 + cp N_WARBASES + N_FACTORIES + jr c, Lb9a7_building_loop + jr Lba02_look_for_robots_in_range_of_nuclear_bomb + +Lb9f2_building_in_range_of_nuclear_bomb: + ; A nuclear bomb will only destroy at most one building. As soon as + ; a building to destroy is found, we are done with the above loop: + pop hl + ld a, c + cp N_WARBASES + jr nc, Lb9fd_factory + call Lbbf9_destroy_warbase + jr Lba02_look_for_robots_in_range_of_nuclear_bomb +Lb9fd_factory: + sub N_WARBASES + call Lbbd8_destroy_factory + +Lba02_look_for_robots_in_range_of_nuclear_bomb: + ; Look for robots nearby to destroy + ld l, (iy + ROBOT_STRUCT_MAP_PTR) + ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1) + push iy + ld de, -(4*MAP_LENGTH + 4) + add hl, de ; subtract (4, 4) to the robot map pointer. + ; look for robots in a 9x9 window around the robot + ld bc, #0909 +Lba11_loop_y: + push bc + push hl + ld a, h + cp #df + jr c, Lba61_next_y ; out of map bounds + cp #fd + jr nc, Lba61_next_y ; out of map bounds + ld a, c + cp 1 + jr z, Lba2d_double_x_increment + cp 2 + jr z, Lba30_x_increment + cp 8 + jr z, Lba30_x_increment + cp 9 + jr nz, Lba33_loop_x +Lba2d_double_x_increment: + inc hl + dec b + dec b +Lba30_x_increment: + inc hl + dec b + dec b +Lba33_loop_x: + push bc + ld a, (hl) + bit 6, a + jr z, Lba44_robots_handled + call Lcdd8_get_robot_at_ptr + jr nz, Lba44_robots_handled + ld (iy + ROBOT_STRUCT_MAP_PTR + 1), 0 ; mark robot as destroyed + res 6, (hl) ; remove from map +Lba44_robots_handled: + ; Destroy map elements + ld a, (hl) + bit 5, a + jr nz, Lba5d_next_x + and #1f + cp 17 ; do not destroy terrain + jr c, Lba5d_next_x + cp 21 + jr nc, Lba5d_next_x ; do not destroy the fences that mark the end of the map + ; in each end. + call Ld358_random + and 1 + add a, 6 ; pick a random piece of debris + call Lbd91_add_element_to_map +Lba5d_next_x: + pop bc + inc hl + djnz Lba33_loop_x +Lba61_next_y: + pop hl + inc h ; y+= 1 + inc h + pop bc + dec c + jr nz, Lba11_loop_y + ; mark the player in the map and redraw + call Lcca0_compute_player_map_ptr + set 7, (hl) + call Lccbd_redraw_game_area + pop iy + ld (iy + ROBOT_STRUCT_MAP_PTR + 1), 0 ; destroy the robot that triggered the nuclear bomb + call Lba87_nuclear_bomb_visual_effect + ld a, 1 + ld (Lfd52_update_radar_buffer_signal), a + call Lbb40_count_robots + call Lbb09_update_players_warbase_and_factory_counts + jp Ld293_update_stats_in_right_hud + + +; -------------------------------- +; Nuclear bomb visual and sound effect. +; Basically pick random "paper" colors for the game area and keep +; changing them, while producing noise in the background. +Lba87_nuclear_bomb_visual_effect: + ; Store the original screen attributes to the L5b00 buffer. + ld de, L5b00 + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021 ; beginning of the game-play area. + ld bc, #1414 ; 20, 20 +Lba90_loop_y: + push bc +Lba91_loop_x: + ldi + inc c + djnz Lba91_loop_x + ld a, 12 + call Ld351_add_hl_a + pop bc + dec c + jr nz, Lba90_loop_y + + ; Visual and sound effect + ld bc, #f401 +Lbaa2_nuclear_bomb_visual_effect_loop: + call Lbaee_nuclear_explosion_sfx + push bc + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021 ; beginning of the game-play area. + ld bc, #1414 ; 20, 20 +Lbaac_random_color_loop: + call Ld358_random + and #38 ; random number of the form 8 * [0 - 7] ; random attribute with black ink, + ; basically. + cp #10 + jr c, Lbaac_random_color_loop ; do not allow black on black or black on blue. + cp e + jr z, Lbaac_random_color_loop ; do not allow the same color as before. + ld e, a + ; add the new random paper color to all the game area: +Lbab9_loop_y: + push bc +Lbaba_loop_x: + ld a, (hl) + and #38 + jr z, Lbac4_skip ; do not change the black on black areas (sky). + ld a, (hl) + and #c7 ; leave ink / brightness the same. + or e ; add the new paper color. + ld (hl), a +Lbac4_skip: + inc hl + djnz Lbaba_loop_x + ld a, 12 + call Ld351_add_hl_a + pop bc + dec c + jr nz, Lbab9_loop_y + pop bc + djnz Lbaa2_nuclear_bomb_visual_effect_loop + + ; Restore the original screen attributes from the L5b00 buffer. + ld hl, L5b00 + ld de, L5800_VIDEOMEM_ATTRIBUTES + #0021 + ld bc, #1414 ; 20, 20 +Lbadc_loop_y: + push bc +Lbadd_loop_x: + ldi + inc c + djnz Lbadd_loop_x + ld a, 12 + add a, e + ld e, a + jr nc, Lbae9_continue + inc d +Lbae9_continue: + pop bc + dec c + jr nz, Lbadc_loop_y + ret + + +; -------------------------------- +; Produces part of the sfx of the nuclear explosion. +; This function is called many times in a loop (above), and the +; combination of all calls, produces the nuclear explosion sound +; effect. +; Input: +; - c: wave period. +; - b: number of bytes to read to generate noise. +Lbaee_nuclear_explosion_sfx: + push bc + ld hl, 144 +Lbaf2_outer_loop: + push bc + ; read a value from some position in the ZX Spectrum BIOS (used to + ; get some semi-random values to produce noise): + ld a, (hl) + and 16 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound). + inc hl + ; insert some delay before we change the wave again: +Lbaf9_inner_loop: + dec c + nop + nop + jr nz, Lbaf9_inner_loop + pop bc + djnz Lbaf2_outer_loop + pop bc + dec b + dec b + dec b + inc c + inc c + inc c + ret + + +; -------------------------------- +; Clears the factory/warbase counters, and recomputes it from scratch. +Lbb09_update_players_warbase_and_factory_counts: + ; clear warbase/factory counts: + ld hl, Lfd3a_player1_base_factory_counts + ld b, 7 +Lbb0e_clear_player1_loop: + ld (hl), 0 + inc hl + djnz Lbb0e_clear_player1_loop + inc hl ; skip robot count + ld b, 7 +Lbb16_clear_player2_loop: + ld (hl), 0 + inc hl + djnz Lbb16_clear_player2_loop + ld de, Lfd70_warbases + BUILDING_STRUCT_TYPE + ld b, N_WARBASES + N_FACTORIES +Lbb20: + ld a, (de) + or a + jp m, Lbb39_skip + ld hl, Lfd3a_player1_base_factory_counts + bit 6, a ; bit 6 indicates it belongs to player 1 + jr nz, Lbb33_increment_counter + ld hl, Lfd42_player2_base_factory_counts + bit 5, a ; bit 5 indicates it belongs to player 2 (AI) + jr z, Lbb39_skip +Lbb33_increment_counter: + and 7 ; ignore the owners, and just keep the type + call Ld351_add_hl_a + inc (hl) ; increment the count +Lbb39_skip: + ld a, e + add a, 5 + ld e, a + djnz Lbb20 + ret + + +; -------------------------------- +; Counts the number of robots of each player and stores it in "Lfd41_player1_robot_count" and +; "Lfd49_player2_robot_count" +Lbb40_count_robots: + ld hl, Lda00_player1_robots+1 + call Lbb50_count_player_robots + ld (Lfd41_player1_robot_count), a + call Lbb50_count_player_robots + ld (Lfd49_player2_robot_count), a + ret + + +; -------------------------------- +; Counts the number of robots a player has +; Input: +; - hl: pointer to the table of robots of a given player (offset by one byte) +; Returns: +; - a: # robots +Lbb50_count_player_robots: + ld b, MAX_ROBOTS_PER_PLAYER + ld c, 0 + ld de, 16 +Lbb57_count_player_robots_loop: + ld a, (hl) + or a + jr z, Lbb5c_no_robot + inc c +Lbb5c_no_robot: + add hl, de + djnz Lbb57_count_player_robots_loop + ld a, c + ret + + +; -------------------------------- +; Gets factory # "a", removes any records of being owned by a previous player, and assigns it to +; player "b". +; Input: +; - a: factory index +; - b: owner +Lbb61_assign_factory_to_player: + ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE + call Lbbb9_mark_ath_building_and_get_ptr + dec h + dec h + dec h + dec h + inc hl + inc hl + call Lbc5d_remove_decoration ; remove a potential enemy flag + dec hl + dec hl + dec hl + dec hl + call Lbc5d_remove_decoration ; remove a potential player flag + ld a, b ; owner + or a + jr z, Lbb7f_assign_to_player + ; the enemy sets the flag in a different position than the player + inc hl + inc hl + inc hl + inc hl +Lbb7f_assign_to_player: + add a, 7 ; add a flag + ld c, a + call Lbc43_add_decoration_to_map ; Potential optimization: tail recursion. + ret + + +; -------------------------------- +; Input: +; - a: warbase index +; - b: player to assign it to +Lbb86_assign_warbase_to_player: + ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE + call Lbbb9_mark_ath_building_and_get_ptr + ld a, h + sub 8 + ld h, a + call Lbc5d_remove_decoration + dec l + dec l + dec l + dec l + call Lbc5d_remove_decoration + ld a, l + add a, 8 + ld l, a + call Lbc5d_remove_decoration + ld c, 8 + ld a, b + or a + jp nz, Lbc43_add_decoration_to_map + dec l + dec l + dec l + dec l + ld c, a + call Lbc43_add_decoration_to_map + dec l + dec l + dec l + dec l + ld c, 7 + jp Lbc43_add_decoration_to_map + + +; -------------------------------- +; Marks whether the a-th warbase/factory belongs to player 1 or 2, and returns +; its pointer in the map. +; Input: +; - a: index of warbase/factory +; - hl: ptr to the beginning of the warbase/factory + 3 +; - b: owner +Lbbb9_mark_ath_building_and_get_ptr: + ld c, a + add a, a + add a, a + add a, c + call Ld351_add_hl_a ; hl = hl + a * 5 + ld a, b + or a + ld a, #40 ; if player == 0, mark bit 6 + jr z, Lbbc7_neutral + rrca ; if player != 0, mark bit 5 instead +Lbbc7_neutral: + ld c, a + ld a, (hl) + and 31 + or c + ld (hl), a ; update the location in the map with the neutral/occupied mark +Lbbcd_get_map_ptr_of_warbase: + dec hl + ld c, (hl) + dec hl + ld a, (hl) + dec hl + ld l, (hl) + ld h, a + ld a, c + jp Lcca6_compute_map_ptr + + +; -------------------------------- +; Destroy a factory and replace it with debris. +; Input: +; - a: factory index. +Lbbd8_destroy_factory: + ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE + call Lbc1c_mark_building_as_destroyed_and_get_map_ptr + push hl + ; Remove the potential flags (player/enemy) and the factory type decoration: + dec h + dec h + dec h + dec h + inc hl + inc hl + call Lbc5d_remove_decoration + dec hl + dec hl + call Lbc5d_remove_decoration + dec hl + dec hl + call Lbc5d_remove_decoration + pop hl + ld de, Lbfe2_factory + jp Lbc27_replace_building_by_debris + + +; -------------------------------- +; Destroy a warbase and replace it with debris. +; Input: +; - a: warbase index. +Lbbf9_destroy_warbase: + ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE + call Lbc1c_mark_building_as_destroyed_and_get_map_ptr + push hl + ; Remove the potential flags (player/enemy) and the warbase "H" decoration: + ld a, h + sub 8 + ld h, a + call Lbc5d_remove_decoration + dec l + dec l + dec l + dec l + call Lbc5d_remove_decoration + ld a, l + add a, 8 + ld l, a + call Lbc5d_remove_decoration + pop hl + ld de, Lbfb2_warbase + jp Lbc27_replace_building_by_debris + + +; -------------------------------- +; Marks a given warbase as destroyed, and returns the map pointer where it is located. +; Input: +; - hl: warbases array ptr + 3 +; - a: warbase index +Lbc1c_mark_building_as_destroyed_and_get_map_ptr: + ld c, a + add a, a + add a, a + add a, c ; a *= BUILDING_STRING_SIZE + call Ld351_add_hl_a + ld (hl), #80 ; mark warbase as destroyed + jr Lbbcd_get_map_ptr_of_warbase + + +; -------------------------------- +; Replace a building by debris. This is used when factories/warbases are destroyed. +; Input: +; - hl: map pointer of the building. +; - de: pointer to a building definition. +Lbc27_replace_building_by_debris: + ld a, (de) + or a + jr z, Lbc35 + call Ld358_random ; select a random debris graphic + and 1 + add a, 6 + call Lbd91_add_element_to_map +Lbc35: + ; See if the building has more parts. Each part is a 3 byte block: type, x offset, y offset. If + ; the offsets are both 0, it means there are no more parts. + inc de + ld a, (de) + ld c, a + inc de + ld a, (de) + ld b, a + inc de + or c + ret z ; The offsets are zero, there are no more parts. + call Lbd7f_add_map_ptr_offset + jr Lbc27_replace_building_by_debris + + +; -------------------------------- +; Finds an empty spot in the building decoration list, and adds a decoration +; record pointing at position "hl" in the map. +; Input: +; - hl: map ptr +; - c: type +Lbc43_add_decoration_to_map: + ld de, Lff01_building_decorations + 1 + ld b, (N_WARBASES + N_FACTORIES) * 2 +Lbc48_loop: + ld a, (de) + or a + jr z, Lbc52_empty_spot_found + inc de + inc de + inc de + djnz Lbc48_loop + ret +Lbc52_empty_spot_found: + dec de + set 6, (hl) ; mark bit 6 of the map position + ex de, hl + ld (hl), e ; map pointer + inc hl + ld (hl), d ; map pointer + inc hl + ld (hl), c ; type + ex de, hl + ret + + +; -------------------------------- +; Searches for a building owner record with ptr == hl, and removes it. +; Input: +; - hl: map ptr +Lbc5d_remove_decoration: + push iy + push bc + call Lcdf5_find_building_decoration_with_ptr + jr nz, Lbc6b_not_found + ld (iy + 1), 0 ; removes the record + res 6, (hl) ; removes the mark from the map +Lbc6b_not_found: + pop bc + pop iy + ret + + +; -------------------------------- +; Initializes the map buffer in Ldd00_map and all the warbase/factory/flag records. +Lbc6f_initialize_map: + ; Clear the map: + ld hl, Ldd00_map + ld d, h + ld e, l + inc de + ld bc, MAP_LENGTH * MAP_WIDTH - 1 + ld (hl), 0 + ldir + + ; Clear the minimap: + ld hl, Ld800_radar_view1 + ld d, h + ld e, l + inc de + ld bc, 255 + ld (hl), 0 + ldir + + ld hl, Lbda9_map_elements_part1 + ld d, 0 ; indicates x < 256 + call Lbcd6_add_elements_to_map ; Write map elements to the map buffer (those with x < 256) + + ld hl, Lbe79_map_elements_part2 + ld d, 1 ; indicates x >= 256 + call Lbcd6_add_elements_to_map ; Write map elements to the map buffer (those with x >= 256) + + ld iy, Lfd84_factories + ld ix, Lfd70_warbases + + ld hl, Lbf46_warbases_factories_part1 + ld d, 0 + call Lbcf9_add_warbases_and_factories_to_map + + ld hl, Lbf6e_warbases_factories_part2 + ld d, 1 + call Lbcf9_add_warbases_and_factories_to_map + + xor a + ld b, a + call Lbb86_assign_warbase_to_player ; warbase 0 to player 1 + ld a, 1 + ld b, a + call Lbb86_assign_warbase_to_player ; warbase 1 to player 2 + ld a, 2 + ld b, 1 + call Lbb86_assign_warbase_to_player ; warbase 2 to player 2 + ld a, 3 + ld b, 1 + call Lbb86_assign_warbase_to_player ; warbase 3 to player 2 + call Lbb09_update_players_warbase_and_factory_counts ; compute the warbase/factory counts + ld a, 1 + ld (Lfd52_update_radar_buffer_signal), a + call Lb024_add_player_to_map_and_update_radar ; Potential optimization: tail recursion. + ret + + +; -------------------------------- +; Adds a list of map elements to the map buffer. +; Input: +; - d: A 0 or a 1. Indicates whether x coordinates start at 0 or at 256. +Lbcd6_add_elements_to_map: +Lbcd6_loop: + ld a, (hl) + or a + ret z ; a 0 at the end indicates end of data. + ld c, a ; element type + inc hl + ld e, (hl) ; x + inc hl + ld a, (hl) ; y % 256 + inc hl ; we have read 3 bytes from the data in: c, e, a. + push hl + push de + ld hl, Ldd00_map + add a, a + add a, h + ld h, a + add hl, de ; hl now has the pointer in the map to (e, a + d*256). + ld a, c + or a + jp m, Lbcf2 ; Those elements with msb set to 1 are complex structures, and are handled + ; separately. + call Lbd91_add_element_to_map + jr Lbcf5_continue +Lbcf2: + call Lbd61_add_complex_structure_to_map +Lbcf5_continue: + pop de + pop hl + jr Lbcd6_loop + + +; -------------------------------- +; Adds warbases and factories to the map. +; - It also adds all the factories to the buildings list (but not the warbases) +; Input: +; - d: 0 if element x < 256, 1 if element x >= 256 +; - hl: ptr to the elements to add. +; - ix: ptr to the factory list +; - iy: ptr to the warbase list +Lbcf9_add_warbases_and_factories_to_map: + ld a, (hl) + or a + ret m ; a 1 in the most significant bit indicates termination + ld c, a ; type + inc hl + ld e, (hl) ; x (the most significant byte of x is passed as argument in d) + inc hl + ld a, (hl) + ld b, a ; y + inc hl + push hl + push de + ld hl, Ldd00_map + add a, a + add a, h + ld h, a + add hl, de ; hl now points to the position in the map corresponding to the x, y, + ; coordinates of the element + ld a, c + or a + jr z, Lbd3e_warbase + ld (iy + 0), e ; x + ld (iy + 1), d ; x + ld (iy + 2), b ; y + ld (iy + 3), c ; type + ld (iy + 4), 0 + inc iy + inc iy + inc iy + inc iy + inc iy + push bc + push hl + ld a, #81 ; add a factory + call Lbd61_add_complex_structure_to_map + pop hl + pop bc + dec h + dec h + dec h + dec h + ; notice c still holds the type here + call Lbc43_add_decoration_to_map + pop de + pop hl + jr Lbcf9_add_warbases_and_factories_to_map +Lbd3e_warbase: + ld (ix + 0), e ; x + ld (ix + 1), d ; x + ld (ix + 2), b ; y + ld (ix + 3), c ; type + ld (ix + 4), 0 + inc ix + inc ix + inc ix + inc ix + inc ix + ld a, #80 ; add a warbase + call Lbd61_add_complex_structure_to_map + pop de + pop hl + jr Lbcf9_add_warbases_and_factories_to_map + + +; -------------------------------- +; Adds a complex structure to the map buffer. +Lbd61_add_complex_structure_to_map: + push hl + ld hl, Lbf9c_map_complex_structure_ptrs + and #7f ; remove the msb + call Ld348_get_ptr_from_table + ex de, hl + pop hl +Lbd6c_loop: + ld a, (de) + or a ; element type + call nz, Lbd91_add_element_to_map ; if the structure is != 0, end. + inc de + ld a, (de) + ld c, a ; x + inc de + ld a, (de) + ld b, a ; y + inc de + or c + ret z ; if x == y == 0, we are done + call Lbd7f_add_map_ptr_offset + jr Lbd6c_loop + + +; -------------------------------- +; Adds an (x, y) offset to a map pointer. +; Input: +; - hl: map pointer +; - c: offset in x +; - b: offset in y +Lbd7f_add_map_ptr_offset: + push de + ; hl += c + ; extend c to 16 bits in de: + ld e, c + ld d, 0 + ld a, c + or a + jp p, Lbd8a_c_positive + ld d, 255 +Lbd8a_c_positive: + add hl, de + ld a, h + add a, b + add a, b + ld h, a ; h += b*2 + pop de + ret + + +; -------------------------------- +; Adds an element (building, terrain) to the map. +; This methods adds the desired element to a 2x2 grid, and marks the bottom-left with bit 5 to 0, +; and the rest with bit 5 to 1. +; Input: +; - hl: map ptr +; - a: map element. +Lbd91_add_element_to_map: + push de + ld e, a + ld bc, #0202 + push hl +Lbd97_loop_y: + push bc + push hl +Lbd99_loop_x: + ld (hl), e ; write the type of map element we have in this position. + set 5, e ; only the bottom-left corner has bit 5 set to 0, the rest have it to 1. + inc hl + djnz Lbd99_loop_x + pop hl + pop bc + dec h ; y -= 1 + dec h + dec c + jr nz, Lbd97_loop_y + pop hl + pop de + ret + + + ; -------------------------------- + ; Game map data: + ; Each block of 3 bytes represents a map element: type, x, y. + ; - Element types with the most significant bit set to 1 represent complex structures, which + ; are specified + ; in "Lbf9c_map_complex_structure_ptrs". + ; - A 0 indicates termination. +Lbda9_map_elements_part1: ; elements with x < 256 + db #86, #0c, #01 + db #86, #0c, #09 + db #11, #10, #0e + db #11, #20, #03 + db #82, #22, #0a + db #05, #20, #0c + db #04, #2a, #0a + db #07, #2a, #0c + db #06, #2a, #0e + db #03, #2c, #0a + db #09, #2c, #0c + db #07, #2c, #0e + db #83, #2e, #0a + db #03, #30, #08 + db #04, #32, #08 + db #02, #36, #0c + db #06, #36, #0e + db #03, #38, #0e + db #12, #3f, #02 + db #12, #41, #02 + db #12, #46, #01 + db #11, #46, #0f + db #11, #48, #0f + db #87, #48, #02 + db #87, #53, #08 + db #06, #53, #02 + db #05, #53, #04 + db #83, #55, #02 + db #02, #55, #06 + db #04, #5b, #06 + db #07, #5d, #02 + db #03, #5d, #04 + db #85, #5e, #0f + db #88, #68, #09 + db #88, #6e, #09 + db #0d, #6e, #09 + db #85, #6a, #04 + db #85, #6c, #0d + db #84, #79, #09 + db #11, #7f, #0c + db #11, #81, #07 + db #85, #86, #04 + db #12, #85, #0b + db #12, #85, #0d + db #87, #97, #06 + db #82, #a5, #02 + db #83, #a7, #06 + db #83, #ad, #08 + db #83, #b3, #0a + db #12, #bf, #08 + db #89, #bf, #03 + db #89, #c1, #08 + db #89, #bf, #0d + db #89, #c7, #03 + db #89, #c7, #0d + db #89, #cf, #03 + db #89, #c9, #08 + db #89, #cf, #0d + db #12, #d1, #08 + db #89, #d7, #0d + db #89, #df, #0d + db #11, #e5, #0b + db #84, #e9, #09 + db #12, #e9, #07 + db #82, #eb, #0a + db #82, #f3, #0a + db #02, #fb, #0c + db #04, #fb, #0e + db #03, #fd, #0e + db #00 + +Lbe79_map_elements_part2: ; elements with x >= 256 + db #83, #0e, #02 + db #83, #0c, #0a + db #83, #10, #0a + db #08, #08, #0e + db #09, #0a, #0c + db #0a, #0a, #0e + db #08, #18, #0c + db #0b, #18, #0e + db #12, #21, #03 + db #11, #2b, #09 + db #12, #33, #0d + db #11, #40, #0a + db #11, #42, #0c + db #11, #44, #0e + db #12, #49, #0c + db #85, #50, #05 + db #85, #50, #09 + db #85, #58, #05 + db #85, #58, #09 + db #84, #60, #09 + db #12, #5e, #01 + db #12, #5e, #03 + db #11, #58, #01 + db #11, #52, #03 + db #11, #52, #0d + db #11, #56, #0d + db #11, #56, #0f + db #11, #58, #0f + db #11, #5a, #0f + db #11, #5a, #0b + db #8a, #64, #05 + db #11, #7b, #04 + db #03, #7b, #0e + db #04, #7d, #0c + db #02, #7d, #0e + db #82, #7f, #0a + db #05, #87, #0c + db #02, #87, #0e + db #04, #89, #0e + db #12, #8a, #01 + db #11, #91, #0f + db #12, #99, #01 + db #88, #96, #05 + db #88, #99, #09 + db #88, #99, #0d + db #87, #a4, #08 + db #87, #a8, #02 + db #87, #ac, #08 + db #87, #b0, #02 + db #09, #b4, #0e + db #83, #b6, #0a + db #83, #bc, #0a + db #04, #c0, #0a + db #03, #c2, #0a + db #02, #c2, #0c + db #88, #c5, #03 + db #11, #d0, #0a + db #11, #d3, #0d + db #8a, #de, #01 + db #8a, #dc, #03 + db #8a, #da, #05 + db #8a, #da, #09 + db #8a, #dc, #0b + db #8a, #de, #0d + db #8a, #e0, #0f + db #8a, #e0, #05 + db #86, #f7, #01 + db #86, #f7, #09 + db #00 + + ; Warbases and factories: + ; 0 are warbases, and 1 - 6 are factories +Lbf46_warbases_factories_part1: + db #00, #16, #09 + db #04, #27, #06 + db #06, #35, #03 + db #01, #3e, #0a + db #05, #4f, #03 + db #03, #61, #03 + db #02, #7d, #03 + db #06, #8c, #0b + db #01, #a0, #05 + db #03, #b4, #03 + db #04, #d9, #03 + db #05, #e3, #09 + db #06, #f1, #03 + db #ff + +Lbf6e_warbases_factories_part2: + db #00, #05, #08 + db #03, #1a, #03 + db #01, #20, #0d + db #02, #28, #03 + db #04, #37, #07 + db #06, #42, #03 + db #00, #71, #08 + db #03, #82, #03 + db #05, #91, #07 + db #01, #a0, #03 + db #02, #b4, #05 + db #04, #be, #03 + db #05, #c8, #0a + db #06, #d2, #03 + db #00, #ee, #08 + db #ff + +Lbf9c_map_complex_structure_ptrs: + dw Lbfb2_warbase + dw Lbfe2_factory + dw Lbff4 + dw Lc018 + dw Lc03c + dw Lc048 + dw Lc054 + dw Lc060 + dw Lc06c + dw Lc078 + dw Lc084 + + ; Each complex structure is a list of map elements. Termination is marked by an + ; element with x == y == 0. +Lbfb2_warbase: + db #00, #fc, #fc + db #10, #00, #fe + db #10, #02, #05 + db #0f, #00, #fe + db #0f, #00, #fe + db #0f, #00, #fe + db #10, #02, #05 + db #0f, #00, #fe + db #10, #00, #fe + db #10, #02, #05 + db #0f, #00, #fe + db #0f, #00, #fe + db #0f, #00, #fe + db #10, #02, #03 + db #10, #00, #fe + db #10, #00, #00 + +Lbfe2_factory: + db #00, #fe, #00 + db #0f, #00, #fe + db #10, #02, #00 + db #10, #02, #00 + db #10, #00, #02 + db #0f, #00, #00 + +Lbff4: + db #02, #02, #00 + db #03, #02, #00 + db #04, #02, #00 + db #05, #fa, #02 + db #04, #02, #00 + db #05, #02, #00 + db #02, #02, #00 + db #03, #fa, #02 + db #03, #02, #00 + db #02, #02, #00 + db #05, #02, #00 + db #04, #00, #00 + +Lc018: + db #08, #02, #00 + db #09, #02, #00 + db #0a, #02, #00 + db #0b, #fa, #02 + db #0a, #02, #00 + db #0b, #02, #00 + db #08, #02, #00 + db #09, #fa, #02 + db #09, #02, #00 + db #08, #02, #00 + db #0b, #02, #00 + db #0a, #00, #00 + +Lc03c: + db #12, #00, #02 + db #12, #00, #02 + db #12, #00, #02 + db #12, #00, #00 + +Lc048: + db #12, #02, #00 + db #12, #02, #00 + db #12, #02, #00 + db #12, #00, #00 + +Lc054: + db #15, #00, #02 + db #15, #00, #02 + db #15, #00, #02 + db #15, #00, #00 + +Lc060: + db #0c, #00, #02 + db #0d, #00, #02 + db #0d, #00, #02 + db #0e, #00, #00 + +Lc06c: + db #0c, #02, #00 + db #0d, #02, #00 + db #0d, #02, #00 + db #0e, #00, #00 + +Lc078: + db #11, #02, #00 + db #11, #02, #00 + db #11, #02, #00 + db #11, #00, #00 + +Lc084: + db #11, #02, #00 + db #12, #02, #00 + db #11, #00, #00 + + + ds #c100 - $, 0 ; 115 bytes of empty space until the game code continues. + + +; -------------------------------- +Lc100_title_screen: + call Ld0b9_clear_screen + call Lc1e3_draw_game_title +Lc106_title_screen_redraw_options: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_ATTRIBUTE, #46 + db CMD_SET_SCALE, #21 + db CMD_SET_POSITION, #0b, #08 + db "0..START GAME" + db CMD_SET_SCALE, #00 + db CMD_END + ; Script end: + ld c, 1 + call Lc336_highlight_if_selected + call Ld42d_execute_ui_script + ; Script start: + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "1..KEYBOARD" + db CMD_END + ; Script end: + ld c, 2 + call Lc336_highlight_if_selected + call Ld42d_execute_ui_script + ; Script start: + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "2..KEMPSTON J/S" + db CMD_END + ; Script end: + ld c, 3 + call Lc336_highlight_if_selected + call Ld42d_execute_ui_script + ; Script start: + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "3..INTERFACE 2" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db CMD_SET_ATTRIBUTE, #46 + db "4..REDEFINE KEYS" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db "5..LOAD SAVED GAME" + db CMD_END + ; Script end: +Lc192_wait_for_key_not_pressed_loop: + halt + call Lc820_title_color_cycle + call L028e_BIOS_POLL_KEYBOARD + ld a, e + or a + jp p, Lc192_wait_for_key_not_pressed_loop + call Lc4a7_title_music_loop +Lc1a1_wait_for_key_press_loop: + halt + call Lc820_title_color_cycle + call L028e_BIOS_POLL_KEYBOARD + ld a, e + or a + jp m, Lc1a1_wait_for_key_press_loop + ld hl, L0205_BIOS_KEYCODE_TABLE + add a, l + ld l, a + ld a, (hl) + cp '5' + jr z, Lc1fd_select_load_saved_game + cp '0' + jr z, Lc1d1_select_start_game + cp '1' + jr z, Lc1d3_select_keyboard + cp '2' + jr z, Lc1d7_select_kempston + cp '3' + jr z, Lc1db_select_interface2 + cp '4' + jr nz, Lc1a1_wait_for_key_press_loop + call Lc34a_redefine_keys + jp Lc100_title_screen + +Lc1d1_select_start_game: + xor a + ret + +Lc1d3_select_keyboard: + ld a, INPUT_KEYBOARD + jr Lc1dd_select_input + +Lc1d7_select_kempston: + ld a, INPUT_KEMPSTON + jr Lc1dd_select_input + +Lc1db_select_interface2: + ld a, INPUT_INTERFACE2 +Lc1dd_select_input: + ld (Ld3e4_input_type), a + jp Lc106_title_screen_redraw_options + + +; -------------------------------- +Lc1e3_draw_game_title: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #01, #0a + db CMD_SET_ATTRIBUTE, #47 + db CMD_SET_SCALE, #32 + db "NETHER" + db CMD_SET_POSITION, #05, #0b + db "EARTH" + db CMD_END + ; Script end: + ret + + +; -------------------------------- +Lc1fd_select_load_saved_game: + call Lc1e3_draw_game_title + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #16, #07 + db CMD_SET_ATTRIBUTE, #45 + db CMD_SET_SCALE, #21 + db "PRESS PLAY ON TAPE " + db CMD_END + ; Script end: + ld a, 2 + out (ULA_PORT), a ; change border color + ld ix, L5b00 ; Address to store the data read from tape + ld de, 2 ; read 2 bytes (checksum) + xor a + scf + inc d + ex af, af' + dec d + di + call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS + + ld ix, Ld92b_save_game_start ; Address to store the data read from tape + ld de, Lfdfc_save_game_end - Ld92b_save_game_start ; read 9425 bytes (the whole RAM space, up + ; to the interrupt table!) + xor a + scf + inc d + ex af, af' + dec d + di + call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS + + xor a + out (ULA_PORT), a ; border to black + + ; Make sure checksum is correct: + call Lc30f_compute_checksum + ld hl, (L5b00) + and a + sbc hl, de + ld a, h + or l + jr nz, Lc269_checksum_does_not_match + ld hl, Ld92b_save_game_start + ld de, Ld7d3_bullets + ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE + ldir ; Restore the bullet state from the reading buffer. + ld de, Lff01_building_decorations + ld bc, 168 + ldir + ei + or 1 + ret + + +Lc269_checksum_does_not_match: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #16, #02 + db CMD_SET_ATTRIBUTE, #47 + db CMD_SET_SCALE, #22 + db "LOADING ERROR!" + db CMD_END + ; Script end: + ld a, 250 + call Lccac_beep + call Lc325_wait_for_key + jp La600_start + + +; -------------------------------- +; Saves the current game state to tape +Lc28d_save_game: + ld hl, Ld59c_empty_interrupt + ld (Lfdfe_interrupt_pointer), hl + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #16, #00 + db CMD_SET_ATTRIBUTE, #45 + db "PRESS RECORD AND PLAY " + db CMD_NEXT_LINE + db " THEN ANY KEY " + db CMD_END + ; Script end: + call Lc325_wait_for_key + ld a, 1 + ld (Lfd52_update_radar_buffer_signal), a + ld hl, Ld7d3_bullets + ld de, Ld92b_save_game_start + ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE + ldir ; save the bullet state to a buffer for saving the game. Potential optimization: put the + ; bullets here to begin with. + ld hl, Lff01_building_decorations + ld bc, 168 + ldir + di + call Lc30f_compute_checksum + ld (L5b00), de + ld hl, 2304 ; Data timing for saving bytes to disc + ld ix, L5b00 + ld de, 2 ; save 2 bytes to tape (checksum) + xor a + scf + call L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS + ld hl, 2304 ; Data timing for saving bytes to disc + ld ix, Ld92b_save_game_start + ld de, Lfdfc_save_game_end - Ld92b_save_game_start ; save 9425 bytes to tape + xor a + scf + call L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS + xor a + out (ULA_PORT), a ; border black + ei + ret + + +; -------------------------------- +; Computes the checksum of the whole block of data that is saved +; in a save game (9425 bytes) +Lc30f_compute_checksum: + ld hl, Ld92b_save_game_start + ld bc, Lfdfc_save_game_end - Ld92b_save_game_start + ld de, 0 +Lc318: + ld a, (hl) + inc hl + add a, e + ld e, a + jr nc, Lc31f + inc d +Lc31f: + dec bc + ld a, b + or c + jr nz, Lc318 + ret + + +; -------------------------------- +; Waits until the user presses any key +Lc325_wait_for_key: + ; Wait until no key is pressed: +Lc325_wait_for_key_loop1: + xor a + in a, (ULA_PORT) ; a = high byte, ULA_PORT = low byte + cpl + and 31 + jr nz, Lc325_wait_for_key_loop1 + ; Wait until the user presses any key: +Lc32d_wait_for_key_loop2: + xor a + in a, (ULA_PORT) ; a = high byte, ULA_PORT = low byte + cpl + and 31 + jr z, Lc32d_wait_for_key_loop2 + ret + + +; -------------------------------- +Lc336_highlight_if_selected: + ld a, (Ld3e4_input_type) + cp c + jr z, Lc343_highlight + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_ATTRIBUTE, #46 + db CMD_END + ; Script end: + ret +Lc343_highlight: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_ATTRIBUTE, #45 + db CMD_END + ; Script end: + ret + + +; -------------------------------- +Lc34a_redefine_keys: + call Ld0b9_clear_screen + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #02, #09 + db CMD_SET_ATTRIBUTE, #47 + db CMD_SET_SCALE, #21 + db "REDEFINE KEYS" + db CMD_SET_POSITION, #05, #03 + db CMD_SET_SCALE, #00 + db CMD_END + ; Script end: +Lc36a_wait_for_no_key_pressed_loop: + call L028e_BIOS_POLL_KEYBOARD + ld a, e + or a + jp p, Lc36a_wait_for_no_key_pressed_loop + ; Clear all the key definitions: + ld hl, Ld3cc_key_pause + ld de, Ld3cc_key_pause+1 + ld bc, 23 + ld (hl), 0 + ldir + call Lc40c_print_press_key_for + ; Script start: + db " UP" + db CMD_END + ; Script end: + ld hl, Ld3d8_key_up+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db " DOWN" + db CMD_END + ; Script end: + ld hl, Ld3db_key_down+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db " LEFT" + db CMD_END + ; Script end: + ld hl, Ld3de_key_left+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db "RIGHT" + db CMD_END + ; Script end: + ld hl, Ld3e1_key_right+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db " FIRE" + db CMD_END + ; Script end: + ld hl, Ld3d5_key_fire+2 + call Lc427_redefine_one_key + call Ld470_execute_command_3_next_line + call Lc40c_print_press_key_for + ; Script start: + db "PAUSE" + db CMD_END + ; Script end: + ld hl, Ld3cc_key_pause+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db "ABORT" + db CMD_END + ; Script end: + ld hl, Ld3cf_key_abort+2 + call Lc427_redefine_one_key + call Lc40c_print_press_key_for + ; Script start: + db " SAVE" + db CMD_END + ; Script end: + ld hl, Ld3d2_key_save+2 + call Lc427_redefine_one_key +Lc3fa: + call L028e_BIOS_POLL_KEYBOARD + ld a, e + or a + jp p, Lc3fa + ld bc, 0 +Lc405: + dec bc + nop + ld a, c + or b + jr nz, Lc405 + ret + + +; -------------------------------- +Lc40c_print_press_key_for: + call Ld42d_execute_ui_script + ; Script start: + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db CMD_SET_ATTRIBUTE, #46 + db "PRESS KEY FOR " + db CMD_SET_ATTRIBUTE, #45 + db CMD_END + ; Script end: + jp Ld42d_execute_ui_script + + +; -------------------------------- +Lc427_redefine_one_key: + push hl + call Ld42d_execute_ui_script + ; Script start: + db " " + db CMD_SET_ATTRIBUTE, #46 + db CMD_END + ; Script emd: +Lc430_wait_for_key_pressed_loop: + call L028e_BIOS_POLL_KEYBOARD + ld a, e + or a + jp m, Lc430_wait_for_key_pressed_loop + ld hl, L0205_BIOS_KEYCODE_TABLE + add a, l + ld l, a + ld a, (hl) + ld d, a + ld hl, Ld3cc_key_pause+2 + ld b, 8 +Lc444_duplicate_key_check_loop: + cp (hl) ; If they key is already used, ignore + jr z, Lc430_wait_for_key_pressed_loop + inc hl + inc hl + inc hl + djnz Lc444_duplicate_key_check_loop + pop hl + ld (hl), a ; assign the key haracter + ld a, e + and #07 + ld c, a + srl e + srl e + srl e + ld b, e + inc b + ld a, 32 +Lc45c: + rrca + djnz Lc45c + dec hl + ld (hl), a + ld b, c + inc b + xor a + dec a +Lc465: + rra + djnz Lc465 + dec hl + ld (hl), a + ld a, d + cp 14 + jr nz, Lc47a_not_sym_shift + call Ld42d_execute_ui_script + ; Script start: + db "SYM SH" + db CMD_END + ; Script end: + ret +Lc47a_not_sym_shift: + cp 13 + jr nz, Lc488_not_enter + call Ld42d_execute_ui_script + ; Script start: + db "ENTER" + db CMD_END + ; Script end: + ret +Lc488_not_enter: + cp 227 + jr nz, Lc498_not_caps_shift + call Ld42d_execute_ui_script + ; Script start: + db "CAPS SH" + db CMD_END + ; Script end: + ret +Lc498_not_caps_shift: + cp 32 + jp nz, Ld427_draw_character_saving_registers + call Ld42d_execute_ui_script + ; Script start: + db "SPACE" + db CMD_END + ; Script end: +Lc4a6: +Lc4a6_music_empty_event: ; event 0 + ret + + +; -------------------------------- +; Waits until the player presses any number in the keyboard. +; While waiting, the title color is cycled, and music is played +Lc4a7_title_music_loop: + di + ld (Lfd08_stack_ptr_buffer), sp ; store the stack pointer + ld hl, Lc4fd_title_music_loop_interrupt + ld (Lfdfe_interrupt_pointer), hl + ld hl, Lc678_music_event_table_channel1 + ld de, Lc702_music_event_table_channel2 + ld bc, #0101 ; duration of the current event in the music channels (c = 1, b = 1 means + ; they will be reevaluated in the next frame, in + ; "Lc4fd_title_music_loop_interrupt") + exx + ld hl, Lc665_percussion_loops + ei + ld c, 1 + halt +Lc4c3: + push af + ld a, (Lfd0c_keyboard_state) ; Question: what is the effect of this? + ld (Lfd0c_keyboard_state), a + pop af +Lc4cb: + dec d ; note: undefined the first time we enter this function + jp nz, Lc4e0 + ; Produce a wave for channel 2: the events of the channel modify these parameters to produce + ; the right wave. +Lc4d0_selfmodifying: equ $ + 1 + ld d, 55 ; mdl:self-modifying +Lc4d2_selfmodifying: equ $ + 1 + ld a, 24 ; mdl:self-modifying + out (ULA_PORT), a ; produce sound (wave front up) +Lc4d6_selfmodifying: equ $ + 1 + ld a, 13 ; mdl:self-modifying +Lc4d7: + dec a + jp nz, Lc4d7 + out (ULA_PORT), a ; produce sound (wave front down as a == 0) + jp Lc4e8 +Lc4e0: + push af + ld a, (Lfd0c_keyboard_state) ; Question: what is the effect of this? + ld (Lfd0c_keyboard_state), a + pop af +Lc4e8: + dec e + jp nz, Lc4c3 + ; Produce a wave for channel 1: the events of the channel modify these parameters to produce + ; the right wave. +Lc4ed_selfmodifying: equ $ + 1 + ld e, 124 ; mdl:self-modifying +Lc4ef_selfmodifying: equ $ + 1 + ld a, 24 ; mdl:self-modifying + out (ULA_PORT), a ; produce sound (wave front up) +Lc4f3_selfmodifying: equ $ + 1 + ld a, 31 ; mdl:self-modifying +Lc4f4: + dec a + jp nz, Lc4f4 + out (ULA_PORT), a ; produce sound (wave front down as a == 0) + jp Lc4cb + + +; -------------------------------- +Lc4fd_title_music_loop_interrupt: + push af + dec c + call z, Lc5db_music_percussion + exx + dec c + call z, Lc528_music_next_event_channel1 ; if the duration of the previous event + ; reached 0, new event! + dec b + call z, Lc53b_music_next_event_channel2 ; if the duration of the previous event + ; reached 0, new event! + call Lc820_title_color_cycle + ld a, 231 ; read 4th and 5th keyboard rows (all the numbers). + in a, (ULA_PORT) ; a = high byte, ULA_PORT = low byte. + cpl + and 31 + jr nz, Lc51b ; If any number was pressed, exit the title music loop. + exx + pop af + ei + ret +Lc51b: + di + ld sp, (Lfd08_stack_ptr_buffer) ; restore the stack pointer that was stored when entering + ; "Lc4a7_title_music_loop". + ld hl, Ld59c_empty_interrupt + ld (Lfdfe_interrupt_pointer), hl + ei + ret ; this effectively returns from "Lc4a7_title_music_loop". + + +; -------------------------------- +; Reads the next event from the music event table 1 and executes it +; input: +; - hl: next event +Lc528_music_next_event_channel1: + ld a, (hl) + cp 9 + jr c, Lc54f_music_event_jump_table_channel1 + ld (Lc4ed_selfmodifying), a + rrca + rrca + and #3f + ld (Lc4f3_selfmodifying), a + inc hl + ld c, (hl) + inc hl + ret + + +; -------------------------------- +; Reads the next event from the music event table 2 and executes it +; input: +; - de: next event +Lc53b_music_next_event_channel2: + ld a, (de) + cp 9 + jr c, Lc56e_music_event_jump_table_channel2 + ld (Lc4d0_selfmodifying), a + rrca + rrca + and #3f + ld (Lc4d6_selfmodifying), a + inc de + ld a, (de) + ld b, a + inc de + ret + + +; -------------------------------- +Lc54f_music_event_jump_table_channel1: + push hl + call Lc65b_jump_table_jump + jp Lc4a6_music_empty_event + jp Lc5a7_music_channel1_jump + jp Lc58d_music_channel1_call + jp Lc5cc_set_percussion_ptr + jp Lc635_activate_channel1 + jp Lc63f_silence_channel1 + jp Lc5bb_music_channel1_ret + jp Lc5cc_set_percussion_ptr + jp Lc5cc_set_percussion_ptr + + +; -------------------------------- +Lc56e_music_event_jump_table_channel2: + push hl + call Lc65b_jump_table_jump + jp Lc4a6_music_empty_event + jp Lc5b0_music_channel2_jump + jp Lc599_music_channel2_call + jp Lc5cc_set_percussion_ptr + jp Lc648_activate_channel2 + jp Lc652_silence_channel2 + jp Lc5c3_music_channel2_ret + jp Lc5cc_set_percussion_ptr + jp Lc5cc_set_percussion_ptr + + +; -------------------------------- +; Event 2 +Lc58d_music_channel1_call: + pop hl + inc hl + ld a, (hl) + inc hl + ld (Lfd54_music_channel1_ret_address), hl + ld h, (hl) + ld l, a + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +; Event 2 +Lc599_music_channel2_call: + pop hl + ex de, hl + inc hl + ld a, (hl) + inc hl + ld (Lfd56_music_channel2_ret_address), hl + ld h, (hl) + ld l, a + ex de, hl + jp Lc53b_music_next_event_channel2 + + +; -------------------------------- +; Event 1 +Lc5a7_music_channel1_jump: + pop hl + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +; Event 1 +Lc5b0_music_channel2_jump: + pop hl + ex de, hl + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + jp Lc53b_music_next_event_channel2 + + +; -------------------------------- +; Event 6 +Lc5bb_music_channel1_ret: + pop hl + ld hl, (Lfd54_music_channel1_ret_address) + inc hl + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +; Event 6 +Lc5c3_music_channel2_ret: + pop hl + ld de, (Lfd56_music_channel2_ret_address) + inc de + jp Lc53b_music_next_event_channel2 + + +; -------------------------------- +; Event 3, 7 or 8 +Lc5cc_set_percussion_ptr: + pop hl + inc hl + ld a, (hl) + inc hl + exx + ld l, a + exx + ld a, (hl) + inc hl + exx + ld h, a + exx + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +Lc5db_music_percussion: + ld a, (hl) + inc hl + cp 1 + jr z, Lc601_go_to ; command == 1: go-to + ld c, a ; Otherwise, repeat the following command for "a" steps + ld a, (hl) + inc hl + cp 2 + jr z, Lc616_tone_drum ; 2: beep + and a + jr z, Lc608_drum1 ; 0: noisy beep + ; any number != 0 and != 2: + push hl + ld h, 0 ; read 80 random bytes from the BIOS + ld b, 80 +Lc5f0_drum2: + ld a, (hl) + and 24 ; sets all bits to 0 except those referring to MIC/EAR (to produce sound). + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) + ld a, b + cpl + and 63 +Lc5f9_wait_pulse_on: + dec a + jr nz, Lc5f9_wait_pulse_on + inc hl + djnz Lc5f0_drum2 + pop hl + ret + + +; -------------------------------- +Lc601_go_to: + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + jp Lc5db_music_percussion + + +; -------------------------------- +Lc608_drum1: + push hl + ld h, 8 + ld b, 96 +Lc60d: + ld a, (hl) ; This is just reading a random byte from the BIOS (so, probably to produce + ; noise). + and 24 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) + djnz Lc60d + pop hl + ret + + +; -------------------------------- +Lc616_tone_drum: + ld a, (hl) + inc hl + push hl + ld b, 48 ; number of pulses the sound wave will have + ld l, a + rrca + ld h, a +Lc61e_wave_loop: + xor a + out (ULA_PORT), a ; change MIC/EAR state (sound off) + dec l + ld a, l +Lc623_wait_pulse_off: + dec a + jr nz, Lc623_wait_pulse_off + ld a, 24 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) + ld a, 4 + add a, h + ld h, a +Lc62e_wait_pulse_on: + dec a + jr nz, Lc62e_wait_pulse_on + djnz Lc61e_wave_loop + pop hl + ret + + +; -------------------------------- +; Event 4 +Lc635_activate_channel1: + pop hl + ld a, 24 + ld (Lc4ef_selfmodifying), a + inc hl + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +; Event 5 +Lc63f_silence_channel1: + pop hl + xor a + ld (Lc4ef_selfmodifying), a + inc hl + jp Lc528_music_next_event_channel1 + + +; -------------------------------- +; Event 4 +Lc648_activate_channel2: + pop hl + ld a, 24 + ld (Lc4d2_selfmodifying), a + inc de + jp Lc53b_music_next_event_channel2 + + +; -------------------------------- +; Event 5 +Lc652_silence_channel2: + pop hl + xor a + ld (Lc4d2_selfmodifying), a + inc de + jp Lc53b_music_next_event_channel2 + + +; -------------------------------- +; Gets the pointer to the list of jumps from the stack, selects the pointer index "a", and jumps +; Input: +; - stack: jump table pointer +; - a: index of the function to jump to +Lc65b_jump_table_jump: + ld l, a + add a, a + add a, l ; a = a*3 + pop hl ; get the pointer to the jump table + ; hl += a: + add a, l + ld l, a + jr nc, Lc664 + inc h +Lc664: + jp hl + + +; -------------------------------- +; Title Music: +; Music in Nether Earth is defined in a scripting language with a series of commands, and has 3 +; channels: +; - one channel just contains percussion loops +; - the other two channels (channel 1, channel 2) contain the notes. +; For example, command "2" is a "call" to a music subroutine, "3" is a "jump" to a different +; part of the score, etc. These commands basically index the functions in two jumptables: +; "Lc54f_music_event_jump_table_channel1" and "Lc54f_music_event_jump_table_channel2". +Lc665_percussion_loops: + db #20, #00 ; 32 steps of drum 1 + db #01, #65, #c6 ; go-to #c665 + db #20, #00 ; 32 steps of drum 1 [I think this is unused] +Lc66c: + db #10, #01 ; 16 steps of drum 2 + db #08, #00 ; 8 steps of drum 1 + db #08, #00 ; 8 steps of drum 1 + db #20, #02, #30 ; 32 steps of clean beep drum instrument + db #01, #6c, #c6 ; go-to #c66c + +Lc678_music_event_table_channel1: + db #03, #65, #c6 + db #02, #bd, #c6 ; call Lc6bd + db #02, #bd, #c6 ; call Lc6bd + db #02, #bd, #c6 ; call Lc6bd + db #02, #bd, #c6 ; call Lc6bd + db #03, #6c, #c6 + db #02, #cc, #c6 ; call Lc6cc + db #02, #cc, #c6 ; call Lc6cc + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #dd, #c6 ; call Lc6dd + db #02, #cc, #c6 ; call Lc6cc + db #02, #cc, #c6 ; call Lc6cc + db #02, #cc, #c6 ; call Lc6cc + db #02, #cc, #c6 ; call Lc6cc + db #02, #cc, #c6 ; call Lc6cc + db #03, #65, #c6 + db #01, #78, #c6 ; jump back to the beginning +Lc6bd: + db #7c, #10, #05, #7c, #08, #04, #7c, #10, #05, #7c, #40, #52, #18, #04 + db #06 ; ret +Lc6cc: + db #7c, #40, #6e, #40, #68, #40, #5d, #40, #7c, #40, #6e, #40, #68, #40, #5d, #40 + db #06 ; ret +Lc6dd: + db #7c, #08, #05, #7c, #08, #04, #7c, #08, #05, #7c, #08, #04, #7c, #08, #8b, #08 + db #93, #08, #a5, #08, #ba, #08, #a5, #08, #93, #08, #8b, #08, #7c, #08, #8b, #08 + db #93, #08, #a5, #08 + db #06 ; ret + +Lc702_music_event_table_channel2: + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #aa, #c7 ; call Lc7aa + db #02, #aa, #c7 ; call Lc7aa + db #02, #aa, #c7 ; call Lc7aa + db #02, #aa, #c7 ; call Lc7aa + db #05 + db #02, #aa, #c7 ; call Lc7aa + db #04 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #d2, #c7 ; call Lc7d2 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #d2, #c7 ; call Lc7d2 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #d2, #c7 ; call Lc7d2 + db #02, #c5, #c7 ; call Lc7c5 + db #3e, #20, #37, #20 + db #02, #aa, #c7 ; call Lc7aa + db #02, #aa, #c7 ; call Lc7aa + db #02, #df, #c7 ; call Lc7df + db #02, #df, #c7 ; call Lc7df + db #02, #df, #c7 ; call Lc7df + db #02, #df, #c7 ; call Lc7df + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #c5, #c7 ; call Lc7c5 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #02, #89, #c7 ; call Lc789 + db #01, #02, #c7 ; jump back to the beginning +Lc789: + db #37, #10, #05, #37, #08, #04, #37, #10, #05, #37, #08, #04, #29, #08, #2e, #08 + db #29, #08, #2e, #08, #29, #08, #2e, #08, #29, #08, #2e, #08, #37, #08, #3e, #08 + db #06 ; ret +Lc7aa: + db #29, #10, #2e, #10, #31, #10, #37, #10, #3e, #20, #49 + db #10, #3e, #10, #45, #20, #2e, #20, #29, #10, #2e, #10, #34, #10, #2e, #10 + db #06 ; ret +Lc7c5: + db #3e, #10, #52, #08, #7c, #08, #3e, #10, #52, #08, #7c, #08 + db #06 ; ret +Lc7d2: + db #45, #10, #5d, #08, #8b, #08, #45, #10, #5d, #08, #8b, #08 + db #06 ; ret +Lc7df: + db #29, #04, #2e, #04, #34, #04, #37, #04, #3e, #04, #45, #04, #49, #04, #52, #04 + db #5d, #04, #68, #04, #6e, #04, #7c, #04, #8b, #04, #93, #04, #a5, #04, #ba, #04 + db #29, #04, #2e, #04, #34, #04, #37, #04, #3e, #04, #45, #04, #49, #04, #52, #04 + db #5d, #04, #68, #04, #6e, #04, #7c, #04, #8b, #04, #93, #04, #a5, #04, #ba, #04 + db #06 ; ret + + +; -------------------------------- +Lc820_title_color_cycle: + push bc + push hl + ld hl, L5800_VIDEOMEM_ATTRIBUTES + 32 + 10 + ld a, (Lfd33_title_color) + inc a + and #0f + ld (Lfd33_title_color), a + rrca + jr c, Lc846 + or 64 + ld bc, #0c07 ; change the color of 12 columns and 7 rows +Lc836: + push bc +Lc837: + ld (hl), a + inc hl + djnz Lc837 + ld b, a + ld a, 20 + call Ld351_add_hl_a + ld a, b + pop bc + dec c + jr nz, Lc836 +Lc846: + pop hl + pop bc + ret + + +; -------------------------------- +; Checks if the player has less than the maximum number of robots, and if so, jumps to the robot +; construction screen with "iy" pointing to a free robot structure. +Lc849_robot_construction_if_possible: + ld iy, Lda00_player1_robots + ld de, 16 + ld b, MAX_ROBOTS_PER_PLAYER +Lc852_loop: + ld a, (iy + 1) + or a + jr z, Lc85d_robot_construction + add iy, de + djnz Lc852_loop + ret + + +; -------------------------------- +; Robot construction screen: +; input: +; - iy: pointer to the robot struct that we will be editing. +Lc85d_robot_construction: + di + ld hl, Ld59c_empty_interrupt + ld (Lfdfe_interrupt_pointer), hl + ei + call Ld0b9_clear_screen + ld b, 8 ; there are 8 pieces to draw + ld de, #57f0 ; Video pointer: (x, y) = (128, 191) (bottom center of the screen) +Lc86d_robot_construction_draw_piece_loop: + push bc + push de + ld a, 8 + sub b + add a, a + add a, a ; a contains the index of the piece we want to draw in the + ; Ld6c8_piece_direction_graphic_indices table + inc a ; we add 1 to select the index for the south-west direction + ld hl, Ld6c8_piece_direction_graphic_indices + call Ld351_add_hl_a + ld a, (hl) ; get the graphic index + add a, a + inc a + ld hl, Ld740_isometric_graphic_pointers + call Ld348_get_ptr_from_table + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + add a, a + call Ld351_add_hl_a + dec c + ld a, c + ; Limit the height to draw to 24 pixels (some pieces are taller than that): + cp 24 + jr c, Lc895_height_calculated + ld c, 24 +Lc895_height_calculated: + ; Draw a piece sprite: + call Ld315_draw_masked_sprite_bottom_up + pop de + pop bc + ; move the drawing coordinates 24 pixels up: + ld a, e + sub 96 + ld e, a + jr nc, Lc8a4 + ld a, d + sub 8 + ld d, a +Lc8a4: + djnz Lc86d_robot_construction_draw_piece_loop + + ; Set the part of the screen where the robot under construction will be drawn to yellow: + ld bc, #0409 + ld hl, L5800_VIDEOMEM_ATTRIBUTES + 15*32 +Lc8ac_loop_y: + push bc +Lc8ad_loop_x: + ld (hl), #46 ; bright, black paper, ink color 6 (yellow) + inc hl + djnz Lc8ad_loop_x + ld a, 28 + call Ld351_add_hl_a + pop bc + dec c + jr nz, Lc8ac_loop_y + + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_SCALE, #22 + db CMD_SET_ATTRIBUTE, #47 + db CMD_SET_POSITION, #00, #03 + db "ROBOT" + db CMD_SET_POSITION, #02, #02 + db CMD_SET_SCALE, #21 + db "CONSTRUCTION" + db CMD_SET_SCALE, #00 + db CMD_SET_ATTRIBUTE, #45 + db CMD_SET_POSITION, #01, #15 + db "ELECTRONICS" + db CMD_SET_POSITION, #04, #15 + db "NUCLEAR" + db CMD_SET_POSITION, #07, #15 + db "PHASERS" + db CMD_SET_POSITION, #0a, #15 + db "MISSILES" + db CMD_SET_POSITION, #0d, #15 + db "CANNON" + db CMD_SET_POSITION, #10, #15 + db "ANTI-GRAV" + db CMD_SET_POSITION, #13, #15 + db "TRACKS" + db CMD_SET_POSITION, #16, #15 + db "BIPOD" + db CMD_SET_POSITION, #15, #05 + db "EXIT START" + db CMD_NEXT_LINE + db "MENU ROBOT" + db CMD_SET_ATTRIBUTE, #43 + db CMD_SET_POSITION, #02, #16 + db "3" + db CMD_SET_POSITION, #05, #16 + db "20" + db CMD_SET_POSITION, #08, #16 + db "4" + db CMD_SET_POSITION, #0b, #16 + db "4" + db CMD_SET_POSITION, #0e, #16 + db "2" + db CMD_SET_POSITION, #11, #16 + db "10" + db CMD_SET_POSITION, #14, #16 + db "5" + db CMD_SET_POSITION, #17, #16 + db "3" + db CMD_SET_SCALE, #00 + db CMD_SET_ATTRIBUTE, #46 + db CMD_SET_POSITION, #06, #00 + db "-- RESOURCES --" + db CMD_NEXT_LINE + db "-- AVAILABLE --" + db CMD_SET_ATTRIBUTE, #44 + db CMD_SET_POSITION, #09, #04 + db "GENERAL" + db CMD_SET_POSITION, #0b, #00 + db "ELECTRONICS" + db CMD_SET_POSITION, #0c, #04 + db "NUCLEAR" + db CMD_NEXT_LINE + db "PHASERS" + db CMD_SET_POSITION, #0e, #03 + db "MISSILES" + db CMD_SET_POSITION, #0f, #05 + db "CANNON" + db CMD_SET_POSITION, #10, #04 + db "CHASSIS" + db CMD_SET_POSITION, #12, #06 + db "TOTAL" + db CMD_END + ; Script end: + ld (iy + ROBOT_STRUCT_DIRECTION), 4 ; Robot facing south-east initially + ld (iy + ROBOT_STRUCT_ALTITUDE), 0 + + ; Make a copy of the player resources: + ld hl, Lfd22_player1_resource_counts + ld de, Lfd29_resource_counts_buffer + ld bc, 7 + ldir + + call Lcbe0_draw_resource_counts_in_construction_screen + ld hl, 2 + ld (Lfd1f_cursor_position), hl ; start in the second column, first piece ("bipod") + xor a + ld (Lfd21_construction_selected_pieces), a + call Lcc1f_update_selected_pieces_and_robot_preview + ld c, COLOR_YELLOW + COLOR_BRIGHT + call Lcba9_construction_screen_set_option_color +Lca0f_waiting_for_key_press_loop: + call Ld37c_read_keyboard_joystick_input + and #1f + ; some key has been pressed: + jr z, Lca0f_waiting_for_key_press_loop + ld hl, (Lfd1f_cursor_position) + ld a, (Lfd0c_keyboard_state) + and #10 + jp z, Lcb00_construction_screen_move ; Moving through the options (no space pressed) + ; "fire" has been pressed: + ld a, l ; which column is the cursor in: + or a + jp z, Lcb8e_construction_screen_exit ; "fire" pressed on "exit menu" (column 0) + dec a + jp z, Lcb52_construction_screen_start_robot ; "fire" pressed on "start robot" (column 1) + ; "fire" pressed on a piece: + ld a, h ; a = selected piece + ld e, a ; potential optimization: no need for the ld a, h; just ld e, a; ld b, e + ld b, a + inc b + xor a + scf + ; get the selected piece as a one-hot representation (one bit on, all others off): +Lca30_piece_to_one_hot_loop: + rla + djnz Lca30_piece_to_one_hot_loop + ld d, a + ld a, (Lfd21_construction_selected_pieces) + ld c, a + and d ; check if we already had that piece: + jr nz, Lcaa4_construction_remove_piece + ld a, e ; e has the new selected piece + cp 3 + jr nc, Lca57_construction_add_piece ; If it's not a chassis piece, just add it + ; It's a chassis piece, check if we already had one selected: + ld a, c ; c still has the currently selected pieces in the robot + and 7 + jr z, Lca57_construction_add_piece + ; Replace chassis piece: + push de + ld e, 255 + ; Here a = still has the currently selected pieces in the robot + ; This loop gets in "e" the index of the currently selected chassis in the robot: +Lca48_get_current_chassis_loop: + inc e + rrca + jr nc, Lca48_get_current_chassis_loop + call Lcac1_update_resources_buffer_when_removing_a_piece + ; We remove the current chassis from the robot: + ld a, c + and #f8 + ld c, a + ld (Lfd21_construction_selected_pieces), a + pop de +Lca57_construction_add_piece: + ld a, c ; c still has the currently selected pieces in the robot + or d ; we add in the new piece + and #78 + cp #78 + jp z, Lcaac_construction_beep_and_back_to_loop + ; Update the resources: + ld hl, Lcaf0_piece_costs + ld a, e + call Ld351_add_hl_a + ld b, (hl) ; b has the piece cost + ld hl, Lcaf8_piece_factory_type + ld a, e + call Ld351_add_hl_a + ld a, (hl) ; a has the index of the resource to subtract from + ld hl, Lfd29_resource_counts_buffer + call Ld351_add_hl_a + ld a, (hl) + sub b + jp nc, Lca89_construction_add_piece_continue ; If we had enough, we are good + neg + ld b, a + ld a, (Lfd29_resource_counts_buffer) + sub b + jp c, Lcaac_construction_beep_and_back_to_loop + ld (Lfd29_resource_counts_buffer), a + xor a +Lca89_construction_add_piece_continue: + ld (hl), a ; update the resource counts after subtracting the piece cost + ld a, c + or d + ld (Lfd21_construction_selected_pieces), a ; update the robot pieces + ld a, 100 + call Lccac_beep ; Potential optimization: the following lines are identical to the end of the + ; function below, unify. + call Lcc1f_update_selected_pieces_and_robot_preview + call Lcbe0_draw_resource_counts_in_construction_screen +Lca9a_wait_for_fire_button_release: + call Ld37c_read_keyboard_joystick_input + and 16 + jr nz, Lca9a_wait_for_fire_button_release + jp Lcb4a_pause_and_back_to_construction_loop + + +; -------------------------------- +; Removes a piece from the current robot we are editing +; Input: +; - e: piece to remove +Lcaa4_construction_remove_piece: + call Lcac1_update_resources_buffer_when_removing_a_piece + ld a, c + xor d + ld (Lfd21_construction_selected_pieces), a +Lcaac_construction_beep_and_back_to_loop: + ld a, 120 + call Lccac_beep + call Lcc1f_update_selected_pieces_and_robot_preview + call Lcbe0_draw_resource_counts_in_construction_screen +Lcab7_wait_for_fire_button_release: + call Ld37c_read_keyboard_joystick_input + and 16 + jr nz, Lcab7_wait_for_fire_button_release + jp Lcb4a_pause_and_back_to_construction_loop + + +; -------------------------------- +; Update the resource counts buffer in the construction screen after removing a piece from the +; robot. +; Input: +; - e: piece to remove +Lcac1_update_resources_buffer_when_removing_a_piece: + ld hl, Lcaf0_piece_costs + ld a, e + call Ld351_add_hl_a + ld b, (hl) ; get the cost of the piece. + ld hl, Lcaf8_piece_factory_type + ld a, e + call Ld351_add_hl_a + ld a, (hl) ; Get the index in the resource counts that we should add it to. + ld hl, Lfd29_resource_counts_buffer + call Ld351_add_hl_a + ld a, (hl) + add a, b ; Add the piece cost to the corresponding resource counts. + ld (hl), a + ; See if we have added more than the player had: + push hl + ld a, l + sub 7 ; The actual player resource counts (Lfd22_player1_resource_counts) are just 7 bytes + ; offset from the buffer. + ld l, a + ld b, (hl) ; Get the current resources that the player has on the index we just added to. + pop hl + ld a, (hl) + cp b + ret z ; If after adding the piece cost, we still haven't reached the resources the player had + ; originally in that index, we are done. + ret c + ; Otherwise, we need to cap the resource count in this index to what the player had, and add + ; the rest to the general resources index (0): + ld (hl), b + sub b + ld b, a + ld a, (Lfd29_resource_counts_buffer) + add a, b + ld (Lfd29_resource_counts_buffer), a + ret + + +; -------------------------------- +; How much does each piece cost: bipod, tracks, anti-grav, cannon, missiles, phasers, nuclear, +; electronics: +Lcaf0_piece_costs: + db 3, 5, 10, 2, 4, 4, 20, 3 + +; Which factory type produces resources for each piece: +; - bipod, tracks, anti-grav are all produced in the "chassis" factory types (6), whereas the other +; pieces. +; have dedicated factories for themselves. +Lcaf8_piece_factory_type: + db 6, 6, 6, 5, 4, 3, 2, 1 + + +; -------------------------------- +; Moves the cursor around the construction screen after pressing one of the direction keys +; Input: +; - h: cursor row (selected piece if column == 2) +; - l: cursor column +Lcb00_construction_screen_move: + ld a, (Lfd0c_keyboard_state) + and 3 + jr z, Lcb1b_construction_screen_move_up_down + ld c, a + ld a, l + rr c + jr nc, Lcb0e_right_not_pressed + inc a +Lcb0e_right_not_pressed: + rr c + jr nc, Lcb13_left_not_pressed + dec a +Lcb13_left_not_pressed: + cp 3 ; make sure we did not move out of bounds + jr nc, Lcb4a_pause_and_back_to_construction_loop + ld l, a ; l = new cursor column + jp Lcb36_construction_screen_update_color_of_selected_option_after_move + +Lcb1b_construction_screen_move_up_down: + ld a, (Lfd0c_keyboard_state) + ; Rotate the keyboard state to get to the bits representing up/down + rrca + rrca + ld c, a + ld a, l + cp 2 ; If we are not on the pieces column, just return as we cannot move up/down: + jr nz, Lcb4a_pause_and_back_to_construction_loop + ld a, h + rr c + jr nc, Lcb2c_up_not_pressed + dec a ; move up +Lcb2c_up_not_pressed: + rr c + jr nc, Lcb31_down_not_pressed + inc a ; move down +Lcb31_down_not_pressed: + cp 8 ; make sure we did not move out of bounds + jr nc, Lcb4a_pause_and_back_to_construction_loop + ld h, a ; h = new cursor row +Lcb36_construction_screen_update_color_of_selected_option_after_move: + push hl + ld c, COLOR_CYAN + COLOR_BRIGHT + call Lcba9_construction_screen_set_option_color + pop hl + ld (Lfd1f_cursor_position), hl + ld c, COLOR_YELLOW + COLOR_BRIGHT + call Lcba9_construction_screen_set_option_color + ld a, 20 + call Lccac_beep + +Lcb4a_pause_and_back_to_construction_loop: + ld b, 10 +Lcb4c_pause_loop: + halt + djnz Lcb4c_pause_loop + jp Lca0f_waiting_for_key_press_loop + + +; -------------------------------- +Lcb52_construction_screen_start_robot: + ld a, (Lfd21_construction_selected_pieces) + ld c, a + and 7 + jr z, Lcb4a_pause_and_back_to_construction_loop ; If we have not selected any piece, do not + ; allow the robot to start + ld a, c + and #78 + jr z, Lcb4a_pause_and_back_to_construction_loop ; If we have not selected any weapon, do not + ; allow the robot to start + ld hl, Lfd29_resource_counts_buffer + ld de, Lfd22_player1_resource_counts + ld bc, 7 + ldir ; copy the resource buffer (that has the price of the robot discounted) to the player + ; resources + ld hl, (Lfd0e_player_x) + ld a, (Lfd0d_player_y) + add a, 4 + ld b, a ; robot starts 4 positions off the player in the y axis to be placed at the entrance + ; of the factory + ld (iy + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_AUTO + call Lcc7c_set_robot_position + ld a, (Lfd21_construction_selected_pieces) + ld (iy + ROBOT_STRUCT_PIECES), a + ; Make the sound corresponding to having created a robot: + ld b, 80 +Lcb82_sound_loop: + ld a, b + call Lccac_beep + ld a, b + sub 5 + ld b, a + cp 20 + jr nc, Lcb82_sound_loop + ; And then just exit the construction screen: + ; jp Lcb8e_construction_screen_exit + + +; -------------------------------- +Lcb8e_construction_screen_exit: + ld a, 200 + call Lccac_beep ; make a sound + ld a, 5 + ld (Lfd30_player_elevate_timer), a ; make the player levitate a bit after exiting + push iy + call Lcffe_clear_5b00_buffer ; clear the screen buffer + call Ld0ca_draw_in_game_screen_and_hud + pop iy + ; Restore the in-game interrupt (which was deactivated in the construction screen): + ld hl, Ld566_interrupt + ld (Lfdfe_interrupt_pointer), hl + ret + + +; -------------------------------- +; input: +; - (Lfd1f_cursor_position): option to change the color +; - c: color to set +Lcba9_construction_screen_set_option_color: + ld hl, (Lfd1f_cursor_position) + ld a, l + cp 2 ; if cursor is in column "2' (the piece names) + jr z, Lcbc6_set_attribute_piece_name + add a, a + add a, l + add a, a + add a, 164 + ld l, a ; l = a*6 + 5*32 + 4 + ld h, #5a ; Here, if a == 0, we will change the color of the "EXIT MENU" option, and if a == + ; 1, of the "START ROBOT" option. + ld b, 5 + call Lcbdb_set_attribute_loop ; change color of the first line + ld a, l + add a, 27 + ld l, a + ld b, 5 + jr Lcbdb_set_attribute_loop ; change color of the second line + +Lcbc6_set_attribute_piece_name: + ; Calculate the position of the "h"-th piece name and paint it with color "c" + ld a, h + add a, a + add a, h ; a = h*3 + neg ; a = -h*3 + add a, 22 ; a = 22 - h*3 + add a, a + add a, a + add a, a ; a = 8*(22 - h*3) + ld l, a + ld h, 0 + add hl, hl + add hl, hl ; hl = 32 * (22 - h*3) + ld de, L5800_VIDEOMEM_ATTRIBUTES + 21 + add hl, de ; hl = L5800_VIDEOMEM_ATTRIBUTES + 21 + 32 * (22 - h*3) + ; set the attribute for 11 characters in a row (which is the length of the larger piece name + ; "electronics"): + ld b, 11 + ; set "b" positions in the attribute table to attribute "c": +Lcbdb_set_attribute_loop: + ld (hl), c + inc hl + djnz Lcbdb_set_attribute_loop + ret + + +; -------------------------------- +Lcbe0_draw_resource_counts_in_construction_screen: + ld de, Lfd29_resource_counts_buffer + ld hl, 0 ; hl will accumulate total resources + ld c, 9 ; start y coordinate to draw resource counts + ld b, 7 +Lcbea: + ld a, (de) + call Ld351_add_hl_a + ld a, (de) + call Lcc08_draw_single_resource_count_in_construction_screen + inc de + inc c + ld a, b + cp 7 + jr nz, Lcbfa + inc c ; the fist time, we leave a blank space between general resources and the rest +Lcbfa: + djnz Lcbea + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION, #12, #0c + db CMD_END + ; script end: + ld e, ' ' + jp Ld401_render_16bit_number_3digits ; render the sum of all resources + + +; -------------------------------- +Lcc08_draw_single_resource_count_in_construction_screen: + push af + ld a, c + ld (Lcc11_selfmodifying), a ; set the desired y coordinate + call Ld42d_execute_ui_script + ; script start: + db CMD_SET_POSITION +Lcc11_selfmodifying: + db #00, #0d + db CMD_END + ; script end: + pop af + push bc + push de + push hl + call Ld3e5_render_8bit_number + pop hl + pop de + pop bc + ret + + +; -------------------------------- +; - Paints the selected pieces in white +; - those not selected in yellow +; - synthesizes the robot preview and draws it to screen +; input: +; - iy: robot struct pointer +Lcc1f_update_selected_pieces_and_robot_preview + ld hl, L5800_VIDEOMEM_ATTRIBUTES + 16 + ld a, (Lfd21_construction_selected_pieces) + ld c, a + ld b, 8 ; 8 pieces + ; paint the selected pieces in white color, and non-selected in yellow: +Lcc28_loop_piece: + ld e, COLOR_YELLOW + rl c + jr nc, Lcc30 + ld e, COLOR_BRIGHT + COLOR_WHITE +Lcc30: + push bc + ld bc, #0403 +Lcc34_loop_y: + push bc +Lcc35_loop_x: + ld (hl), e + inc hl + djnz Lcc35_loop_x + ld a, 28 ; next line + call Ld351_add_hl_a + pop bc + dec c + jr nz, Lcc34_loop_y + pop bc + djnz Lcc28_loop_piece + + call Lcffe_clear_5b00_buffer + ld a, (Lfd21_construction_selected_pieces) + ld (iy + ROBOT_STRUCT_PIECES), a + ld de, #0a07 ; isometric coordinates of the robot, so it shows up in the right place in the + ; screen. + call Lcee8_draw_robot_to_buffer + ld a, (Lcf3f_selfmodifying_sprite_elevation) + ld (iy + ROBOT_STRUCT_HEIGHT), a + ; Copies a block of 32*48 pixels from #6168 to (0,120) in video memory: this is the preview of + ; the robot being constructed. + ld bc, #0448 + ld de, #6168 + ld hl, L4000_VIDEOMEM_PATTERNS + #08e0 ; (x, y) = (0, 120) +Lcc63_loop_y: + push bc + push hl +Lcc65_loop_x: + ld a, (de) + ld (hl), a + inc de + inc hl + djnz Lcc65_loop_x + ld a, e + add a, 16 + ld e, a + ld a, d + adc a, 0 + ld d, a + pop hl + call Ld32a_inc_video_ptr_y_hl + pop bc + dec c + jr nz, Lcc63_loop_y + ret + + +; -------------------------------- +; Input: +; - hl: x coordinate +; - b: y coordinate +Lcc7c_set_robot_position: + ld (iy + ROBOT_STRUCT_X), l + ld (iy + ROBOT_STRUCT_X + 1), h + ld (iy + ROBOT_STRUCT_Y), b + push hl + ld a, b + call Lcca6_compute_map_ptr + ld (iy + ROBOT_STRUCT_MAP_PTR), l + ld (iy + ROBOT_STRUCT_MAP_PTR + 1), h + set 6, (hl) + pop hl + ld c, (iy + ROBOT_STRUCT_Y) + ld a, (iy + ROBOT_STRUCT_CONTROL) + rlca + and 1 + ld b, a ; b = 0 if player robot, and b = 1 if enemy robot. + jp Ld65a_flip_2x2_radar_area + + +; -------------------------------- +; Computes the pointer in the map corresponding to the current x, y coordinates of the player. +Lcca0_compute_player_map_ptr: + ld hl, (Lfd0e_player_x) + ld a, (Lfd0d_player_y) + ; jp Lcca6_compute_map_ptr + + +; -------------------------------- +; Computes the pointer in the map corresponding to some x, y coordinates. +; Input: +; - hl: x +; - a: y +; Output: +; - hl: map ptr +Lcca6_compute_map_ptr: + add a, a + add a, #dd + add a, h + ld h, a ; h += a*2 + #dd + ret + + +; -------------------------------- +; Produces a beep sound. +; input: +; - a: sound period (lower means higher pitch) +Lccac_beep: + push bc + ld b, a + xor a + ld c, a +Lccb0_beep_outer_loop: + push bc + xor 16 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) +Lccb5_inner_loop: + djnz Lccb5_inner_loop + pop bc + dec c + jr nz, Lccb0_beep_outer_loop + pop bc + ret + + +; -------------------------------- +; Clears the double buffer, draws the game area there, and copies it to the video memory. +Lccbd_redraw_game_area: + call Lcfd7_draw_blank_map_in_buffer + call Lccc6_draw_map_to_buffer + jp Ld071_copy_game_area_buffer_to_screen + + +; -------------------------------- +; Renders the player and the map to the buffer +Lccc6_draw_map_to_buffer: + ld hl, 0 + ld (Lfd11_player_iso_coordinates_if_deferred), hl ; mark that the player rendering is not + ; deferred. + ; Draw the player shadow: + xor a + ld (Lcf3f_selfmodifying_sprite_elevation), a + ld hl, (Lfd0e_player_x) + ld de, (Lfd06_scroll_ptr) + ld a, d + and #01 + ld d, a ; keep only the lower 9 bits of (Lfd06_scroll_ptr), which contain the x coordinate + xor a + sbc hl, de ; hl = player_x - scroll_x + ld e, l + ld a, (Lfd0d_player_y) + ld d, a + ld a, 1 ; draw graphic 1 (player shadow) + call Lcf2d_draw_sprite_to_buffer + + ld hl, (Lfd06_scroll_ptr) + ld a, 32 + call Ld351_add_hl_a + ld de, 32 + ; Draw the visible part of the map: + ; - "de" starts at 32 and decrements at each loop, and keeps track of the visible area we need + ; to draw. +Lccf3_outer_loop: + dec hl + dec e + push hl + push de + ; Each inner iteration represents a diagonal row of the map (horizontal when projected to + ; the screen). + ; - So, if a row starts in (7,0), it will draw: (7,0), (8,1), (9,2), etc. + ; - In the first iteration, it'll draw the objects that appear in the top of the screen. + ; - In subsequent iterations it goes down one row every time. + ; - In the first iteration of the outer loop "e" will go from 31 -> 32, then from 30 -> 32, + ; 29 -> 32, etc. + ; - until we reach 15 -> 31, 14 -> 30, etc. as at most the inner loop loops 16 times ( + ; controlled by "d"). + ; - This is to capture the visible part of the screen with the isometric projection. +Lccf7_inner_loop: + ld a, e + or a + jp m, Lcd01_not_visible ; if we are outside of the visible area, skip + ld a, (hl) + or a + call nz, Lcd18_draw_map_cell ; If there is anything in the map, draw it! +Lcd01_not_visible: + ; move to the next position of the map to draw: + inc h ; This does "y++" (since each row is 512 bytes long) + inc h + inc hl ; This does "x++". Potential optimization: "inc l"? + inc d ; keep track of how many positions we have drawn in this outer loop iteration + inc e + ld a, d + cp 16 + jr nc, Lcd10_exit_inner_loop ; If we have done 16 iterations of the inner loop, end + ld a, e + cp 32 ; if we have reached the limit visible in the screen, we are done. + jr nz, Lccf7_inner_loop +Lcd10_exit_inner_loop: + ld a, e + pop de + pop hl + cp 1 ; when after drawing one row, "e == 1", end, which means there is no chance of anything + ; visible any more in subsequent outer loop iterations. + jr nz, Lccf3_outer_loop + ret + + +; -------------------------------- +; Draws whatever is in this map cell: map elements, robots, player, etc. +; Input: +; - hl: map ptr +Lcd18_draw_map_cell: + ; Start by drawing the map element in this position, if any: + push hl + push de + push af + bit 5, a ; Map elements occupy a 2x2 block in the map, but only the bottom-left corner has + ; bit 5 == 0. + jr nz, Lcd2b_skip_map_element_draw + and #1f ; If there is no map element in this position, skip. + jr z, Lcd2b_skip_map_element_draw + ld hl, Lcf3f_selfmodifying_sprite_elevation + ld (hl), 0 + call Lcf2d_draw_sprite_to_buffer +Lcd2b_skip_map_element_draw: + pop af + pop de + pop hl + ; Now check if there is an object here (robot, etc.): + bit 6, a ; objects are marked with bit 6 + call nz, Lce12_draw_object_to_map + ld a, (hl) + bit 7, a ; the player is marked with bit 7 + ret z ; player is not here + ; Draw the player: + ld bc, (Lfd11_player_iso_coordinates_if_deferred) + ld a, b + or c + jr nz, Lcd79_player_rendering_was_deferred ; player rendering was already deferred. + ; Check if there is a map element that would occlude the player sprite when it shouldn't, + ; and defer player rendering if so: + push de + ; "de" will have the map pointer where the player should be rendered at. + ; It should be == "hl" if not deferred. + ld d, h + ld e, l + call Lcd96_find_near_in_front_map_element + push hl + dec hl + dec h + dec h + call Lcd90_find_near_in_front_map_element + inc h + inc h + call Lcd90_find_near_in_front_map_element + inc h + inc h + ld a, h + cp #fd + jr nc, Lcd63_out_of_map_bounds + call Lcd90_find_near_in_front_map_element + inc hl + call Lcd90_find_near_in_front_map_element + inc hl + call Lcd90_find_near_in_front_map_element +Lcd63_out_of_map_bounds: + pop hl + ld a, d + cp h + jr nz, Lcd6f_defer_player_rendering + ld a, e + cp l + jr nz, Lcd6f_defer_player_rendering + pop de + jr Lcd81_render_player_push +Lcd6f_defer_player_rendering: + ex de, hl + set 7, (hl) ; mark the player as being in the deferred coordinates. + ex de, hl + pop de + ld (Lfd11_player_iso_coordinates_if_deferred), de + ret + +Lcd79_player_rendering_was_deferred: + res 7, (hl) ; remove the player mark from the deferred position + push hl + push de + ld d, b + ld e, c ; set the correct isometric coordinates (before it was deferred). + jr Lcd83_render_player + +Lcd81_render_player_push: + push hl + push de +Lcd83_render_player: + ld a, (Lfd10_player_altitude) + ld (Lcf3f_selfmodifying_sprite_elevation), a + xor a + call Lcf2d_draw_sprite_to_buffer + pop de + pop hl + ret + + +; -------------------------------- +; Sees if there is a map element that would be rendered on top of the object in "hl", and +; returns its map pointer in de +; Input: +; - hl: map ptr to check +; - de: map ptr to update if we find a "more in front" map element +Lcd90_find_near_in_front_map_element: + bit 6, (hl) + ret z + call Lcdbf_update_de_if_hl_more_in_front_internal +Lcd96_find_near_in_front_map_element: + push hl + dec hl ; x -= 1 + inc h ; y += 1 + inc h + ld a, h + cp #fd ; check if pointer is outside of map bounds + jr nc, Lcda7_skip_first_row ; out of bounds + call Lcdb8_update_de_if_hl_more_in_front + inc hl ; x += 1 + call Lcdb8_update_de_if_hl_more_in_front + dec hl ; x -= 1 +Lcda7_skip_first_row: + dec h + dec h ; y -= 1 + call Lcdb8_update_de_if_hl_more_in_front + inc hl ; x += 1 + inc hl ; x += 1 + inc h ; y += 1 + inc h + ld a, h + cp #fd ; check if pointer is outside of map bounds + call c, Lcdb8_update_de_if_hl_more_in_front + pop hl + ret + + +; -------------------------------- +; Checks if there is a map element in "hl" that is "in front" (rendered lower in the screen) of the +; position pointed to by "de", and if so, overwrites "de" with "hl". +; Input: +; - hl: map ptr to check +; - de: map ptr to update if we find a "more in front" map element +Lcdb8_update_de_if_hl_more_in_front: + bit 5, (hl) + ret nz ; return if this is not the bottom-left corner of the a map object + ld a, (hl) + and #1f + ret z ; return if there is nothing in this map position + ; If we are here is that we are in a map position with the bottom-left corner of a map element. +Lcdbf_update_de_if_hl_more_in_front_internal: + ld a, e + sub l + ld c, a ; c = e - l (difference in x, ignoring highest bit) + ld a, d + sub #dd + srl a + ld b, a ; b = (d - #dd) / 2 + ld a, h + sub #dd + srl a ; a = (h - #dd) / 2 + sub b ; a = ((h - #dd) / 2) - ((d - #dd) / 2) (difference in y) + add a, c ; "a" has (hl.y - de.y) + (de.x - hl.x) + ret m ; return if whatever is in "de" is rendered "lower on the screen" when projected, + jr nz, Lcdd5 + ld a, c ; c still contains e - l (difference in x) + or a + ret p ; return if whatever is in de has a higher x coordinate. +Lcdd5: + ld d, h + ld e, l + ret + + +; -------------------------------- +; Finds if there is a robot with the same map pointer as hl, and returns it in "iy". +; Input: +; - hl: map ptr +; Output: +; - iy: robot ptr +; - z: robot found +; - nz: no robot found +Lcdd8_get_robot_at_ptr: + ld iy, Lda00_player1_robots + ld b, MAX_ROBOTS_PER_PLAYER*2 +Lcdde_get_robot_below_player_loop: + ld a, (iy + ROBOT_STRUCT_MAP_PTR) + cp l + jr nz, Lcde9_next_robot + ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1) + cp h + ret z +Lcde9_next_robot: + push de + ld de, ROBOT_STRUCT_SIZE + add iy, de + pop de + djnz Lcdde_get_robot_below_player_loop + or 1 + ret + + +; -------------------------------- +; Find decoration at map pointer hl +; Input: +; - hl: map pointer to find a decoration for. +; Returns: +; - iy: ptr to a decoration that has "hl" as the map pointer (if found) +; - z: decoration found. +; - nz: decoration not found. +Lcdf5_find_building_decoration_with_ptr: + ld iy, Lff01_building_decorations + ld b, 56 +Lcdfb_loop: + ld a, (iy + BULLET_STRUCT_MAP_PTR) + cp l + jr nz, Lce06_skip + ld a, (iy + BULLET_STRUCT_MAP_PTR + 1) + cp h + ret z +Lce06_skip: + push de + ld de, 3 + add iy, de + pop de + djnz Lcdfb_loop + or 1 + ret + + +; -------------------------------- +; See if there is an object (robot, decoration, bullet) with map ptr equal to "hl" and draws it. +; Input: +; - hl: map ptr +; - de: isometric coordinates +Lce12_draw_object_to_map: + call Lcdd8_get_robot_at_ptr + jr z, Lce68_draw_robot_or_bullet ; if there is a robot, draw it + call Lcdf5_find_building_decoration_with_ptr + jr z, Lce38_draw_decoration ; if there is a decoration, draw it + ld iy, Ld7d3_bullets + ld b, MAX_BULLETS +Lce22_loop_bullet: + ld a, (iy + BULLET_STRUCT_MAP_PTR) + cp l + jr nz, Lce2e_next_bullet + ld a, (iy + BULLET_STRUCT_MAP_PTR + 1) + cp h + jr z, Lce68_draw_robot_or_bullet ; if there is a bullet, draw it +Lce2e_next_bullet: + push de + ld de, BULLET_STRUCT_SIZE + add iy, de + pop de + djnz Lce22_loop_bullet + ret + + +; -------------------------------- +; Draws a decoration to the map (a flag, the "H" in a warbase, pieces on top of factories.) +; Input: +; - iy: decoration ptr +; - de: isometric coordinates +Lce38_draw_decoration: + push hl + push de + ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE) + ld c, a + ld hl, Lce5f_decoration_drawing_elevations + call Ld351_add_hl_a + ld a, (hl) + ld (Lcf3f_selfmodifying_sprite_elevation), a + ld a, c + ld hl, Lce56_decoration_sprite_indexes + call Ld351_add_hl_a + ld a, (hl) + call Lcf2d_draw_sprite_to_buffer + pop de + pop hl + ret + +Lce56_decoration_sprite_indexes: + db #2c, #28, #25, #23, #20, #1d, #17, #2a, #2b +Lce5f_decoration_drawing_elevations: + db #13, #0f, #0f, #0f, #0f, #0f, #0f, #1a, #1a + + +; -------------------------------- +; Draws a bullet to the map. +; Input: +; - iy: bullet/robot struct ptr. +; - hl: map ptr. +; - d, e: isometric coordinates. +Lce68_draw_robot_or_bullet: + push de + ld d, h + ld e, l + call Lcd96_find_near_in_front_map_element + ; if "de" is different from "hl", update the ptr of the bullet/robot instead of drawing it: + ; This is because it could be that the object in "de" would overwrite the bottom of the + ; object in "hl". So, we are just "deferring" the rendering. + ld a, d + cp h + jr nz, Lce76_update_robot_bullet_ptr ; defer rendering + ld a, e + cp l + jr z, Lce82_draw_robot_or_bullet_continue ; if we only differ in "x" form the potential + ; occluder, continue +Lce76_update_robot_bullet_ptr: + ; Defer rendering to later, after we have drawn the map element in "de": + ex de, hl + set 6, (hl) + ld (iy + BULLET_STRUCT_MAP_PTR), l + ld (iy + BULLET_STRUCT_MAP_PTR + 1), h + ex de, hl + pop de + ret + +Lce82_draw_robot_or_bullet_continue: + pop de ; pop "de", which was pushed when we jumped here (isometric coordinates) + push de + ex de, hl ; de = original map ptr. + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld a, (iy + ROBOT_STRUCT_Y) + call Lcca6_compute_map_ptr ; recompute map ptr in "hl" from the x, y coordinates in "hl", + ; "a". + ; If the "Lcd96_find_near_in_front_map_element" call above found an object that will be + ; drawn later and would occlude this one, do not draw yet: + ld a, d + cp h + jr nz, Lce9c_object_was_deferred ; This means that the object was deferred for rendering + ; earlier, so, we draw it now. + ld a, e + cp l + jr nz, Lce9c_object_was_deferred ; This means that the object was deferred for rendering + ; earlier, so, we draw it now. + pop de + jr Lcec3_draw_robot_or_bullet_internal +Lce9c_object_was_deferred: + ; Reestablish the pointer of the object to its original value: + ld (iy + ROBOT_STRUCT_MAP_PTR), l + ld (iy + ROBOT_STRUCT_MAP_PTR + 1), h + ld b, h + ld c, l + ex de, hl + pop de + push de + push hl + res 6, (hl) ; remove the object from its deferred position + dec hl + dec e + ; Adjust the isometric coordinates to account for the fact that the object was moved to + ; defer its rendering. +Lceac_loop_x: + ld a, c + cp l + jr z, Lceb4_loop_y + inc hl + inc e + jr Lceac_loop_x +Lceb4_loop_y: + ld a, b + cp h + jr z, Lcebd_loop_exit + dec h + dec h + dec d + jr Lceb4_loop_y +Lcebd_loop_exit: + call Lcec3_draw_robot_or_bullet_internal + pop hl + pop de + ret + + +; -------------------------------- +; Draws the sprites corresponding to a bullet or robot to the double buffer. +; Input: +; - iy: robot/bullet ptr. +Lcec3_draw_robot_or_bullet_internal: + push iy + pop bc + ld a, b ; Potential optimization: push/pop not needed, just "la a,iyh" + cp #d8 ; bullets have pointers < #d800, if its bigger, it's a robot. + jp nc, Lcee8_draw_robot_to_buffer + ; Draw the bullet + push hl + push de + ld c, (iy + BULLET_STRUCT_TYPE) + ld a, (iy + BULLET_STRUCT_DIRECTION) + ; get the sprite # of the bullet: + cp 3 + ccf + rl c + ld a, (iy + BULLET_STRUCT_ALTITUDE) + ld (Lcf3f_selfmodifying_sprite_elevation), a + ; get the sprite # of the bullet (continued): + ld a, 43 + add a, c + call Lcf2d_draw_sprite_to_buffer + pop de + pop hl + ret + + +; -------------------------------- +; Input: +; - de: isometric coordinates +; - iy: pointer to the robot struct +Lcee8_draw_robot_to_buffer: + push hl + ld c, (iy + ROBOT_STRUCT_PIECES) ; which pieces are selected for the robot (1 bit per + ; piece). + ld b, 8 ; up to 8 different pieces + ld a, (iy + ROBOT_STRUCT_ALTITUDE) + ld (Lcf3f_selfmodifying_sprite_elevation), a +Lcef4_piece_loop: + rr c + call c, Lcefd_draw_robot_piece_to_buffer ; if the piece is selected, draw it. + djnz Lcef4_piece_loop + pop hl + ret + + +; -------------------------------- +; Input: +; - b: 8 - piece to draw +; - de: isometric coordinates +; - iy: robot ptr. +Lcefd_draw_robot_piece_to_buffer: + push bc + push de + ld a, 8 + sub b ; a = piece to draw (0 = bipod, 1 = tracks, etc.) + push af + ld c, (iy + ROBOT_STRUCT_DIRECTION) ; one-hot representation of the robot direction + ld b, 255 ; b will contain the direction (south-east, south-west, etc.) +Lcf08_direction_loop: + inc b + rr c + jr nc, Lcf08_direction_loop + add a, a + add a, a + add a, b ; a now contains the offset in the graphic indices table of the piece graphic + ; to draw. + ld hl, Ld6c8_piece_direction_graphic_indices + call Ld351_add_hl_a + ld a, (hl) ; a now contains the index of the piece graphic to draw in the graphics + ; table. + add a, 22 ; + 22, since this will be later multiplied by 2, and is to skip the first + ; 44 graphics in the "Ld6e8_additional_isometric_graphic_pointers" table. + call Lcf2d_draw_sprite_to_buffer + pop af + pop de + pop bc + ld hl, Ld7b4_piece_heights + call Ld351_add_hl_a ; get piece height + ld a, (Lcf3f_selfmodifying_sprite_elevation) + add a, (hl) + ld (Lcf3f_selfmodifying_sprite_elevation), a + ret + + +; -------------------------------- +; input: +; - a: index of the graphic to draw from Ld6e8_additional_isometric_graphic_pointers (divided by 2) +; - d, e: isometric coordinates. +Lcf2d_draw_sprite_to_buffer: + ld c, a ; we save the graphic to draw in c + ; calculate the screen x coordinate: + rlc e + ld a, e + add a, d + sub 24 + ld l, a ; l (x coordinate in nibbles) = e*2 + d - 24 + ; calculate the screen y coordinate: + rlc e + ld a, d + add a, a + add a, a + add a, a + add a, 100 + sub e +Lcf3f_selfmodifying_sprite_elevation: equ $ + 1 + sub 0 ; a = d*8+100 - e*4 - (Lcf3f_selfmodifying_sprite_elevation) ; mdl:self-modifying + ld h, a ; h: y coordinate to draw to in pixels (starting from the bottom of the sprite) + ld a, c ; restore the graphic to draw + and #3f + ; here l = x coordinate in nibbles + sra l ; we push the least significant bit to the carry (now l is x coordinate in bytes) + ; Here we have the coordinates where to draw: + ; - l: x coordinate in bytes + ; - h: y coordinate in pixels + adc a, a ; The carry is now added to the index, since each odd sprite is already + ; pre-calculated with a 4 pixel offset in the x axis. + push hl + ld hl, Ld6e8_additional_isometric_graphic_pointers + call Ld348_get_ptr_from_table + ld c, (hl) ; height in pixels + inc hl + ld b, (hl) ; width in bytes + inc hl + ex de, hl ; de: pointer to the actual graphic data + pop hl + xor a + ld (Lcfaf_selfmodifying_left_pixel_skip), a ; do not skip pixels from the left by default + ld a, l + cp 20 + ret p ; if we are drawing beyond the buffer right edge, we are done + ld a, h + cp 160 + jr c, Lcf77_clip_sprite_left + cp 226 + ret nc ; if we are drawing outside of the draw-able area from top/bottom, we are done + sub 159 + sub c ; if we are drawing starting outside the buffer area, and the sprite is not tall enough + ; to actually overlap with the viewable area, we are done. + ret p + neg + ld c, a ; update the height of the sprite to draw +Lcf6b_skip_line_outer_loop: + ; skip all the lines that would be drawn outside of the viewable area: + push bc +Lcf6c_skip_line_inner_loop: + inc de + inc de + djnz Lcf6c_skip_line_inner_loop + pop bc + dec h + ld a, h + cp 159 + jr nz, Lcf6b_skip_line_outer_loop +Lcf77_clip_sprite_left: + ld a, l ; start x coordinate + or a + jp p, Lcf85_clip_sprite_right + neg ; if sprite overflows from the left, clip sprite from the left: + ld (Lcfaf_selfmodifying_left_pixel_skip), a + ld l, 0 ; set drawing coordinate to 0 + cp b ; if we are skipping the whole sprite, we are done + ret nc +Lcf85_clip_sprite_right: + ; See if the sprite would overflow the buffer from the right, and clip sprite from the right if + ; necessary: + ld a, l ; start x coordinate + add a, b ; sprite width + cp 21 + jr c, Lcf95_calculate_buffer_pointer_to_draw_to + sub 20 ; a now has the number of bytes we want to skip from the left of the sprite + ld (Lcfaf_selfmodifying_left_pixel_skip), a + ; What this loop does is to move the pointer to draw to the left, and set the number of pixels + ; to skip from the left, so that, effectively, we are skipping pixels from the right: +Lcf90_skip_right_pixels_initially_loop: + dec de + dec de + dec a + jr nz, Lcf90_skip_right_pixels_initially_loop +Lcf95_calculate_buffer_pointer_to_draw_to: + push de + ; Calculate the pointer to where we want to draw the sprite in the buffer: + ; - l: x coordinate in bytes + ; - h: y coordinate in pixels + ld a, l + push af + ld l, h + ld h, 0 + add hl, hl + add hl, hl ; hl = h*4 + ld d, h + ld e, l + add hl, hl + add hl, hl + add hl, de + pop af + call Ld351_add_hl_a ; hl = h*20 + l + ld de, L5b00_double_buffer + add hl, de ; hl = buffer pointer where to start drawing + pop de + ex de, hl + ; Draws a sprite from "hl" to "de" ("de" points to a memory buffer with 20 bytes per row of + ; pixels): + ; - b: sprite width in bytes (b*8 pixels) + ; - c: sprite height in pixels +Lcfac_draw_loop_y: + push bc + push de +Lcfaf_selfmodifying_left_pixel_skip: equ $ + 1 + ld a, 0 ; mdl:self-modifying + or a ; if we are no skipping pixels from the left, skip the loop + jp z, Lcfbb_draw_loop_x + ; Skips "a*8" from the left of the sprite to draw: +Lcfb4_skip_left_pixels_loop: + inc hl + inc hl + dec b + dec a + jp nz, Lcfb4_skip_left_pixels_loop + ; Writes a row of "b*8" pixels from hl to de: +Lcfbb_draw_loop_x: + ld a, (de) ; read pixel from currently in the memory buffer + and (hl) ; applies and mask + inc hl + or (hl) ; applies or mask + ld (de), a ; write pixel to the screen again + inc hl + inc de + djnz Lcfbb_draw_loop_x + pop de + pop bc + ; move to the previous row in the buffer (20 bytes per row, as that's the width of the in-game + ; area) + ld a, -20 + add a, e + ld e, a ; e -= 20 + jp c, Lcfd2_no_msb_update ; if we don't need to update the most significant byte of the buffer + ; address, just skip + dec d + ld a, d + cp #5a ; we are drawing in a buffer that starts in #5b00, so, if the most-significant byte is + ; #5a, it means we are out of the buffer area, and we should stop drawing. + ret z +Lcfd2_no_msb_update: + dec c + jp nz, Lcfac_draw_loop_y + ret + + +; -------------------------------- +; Clears the screen buffer in #5b00, and draws the basic map frame (thw two diagonal cut-out +; patterns that can be seen in the game, to give the appearance of 3d). +Lcfd7_draw_blank_map_in_buffer: + call Lcffe_clear_5b00_buffer + call Ld026_draw_top_left_diagonal_map_edge + ld hl, Ld6a8_diagonal_pattern1 + ld b, 6 + ld de, L5b00_double_buffer + 10 + call Ld057_draw_diagonal_line ; draws the top-left edge of the map in screen + ld hl, Ld6a8_diagonal_pattern1 + ld b, 3 + ld de, L5b00_double_buffer + 136*20 + 18 + call Ld057_draw_diagonal_line ; draws the first part of the bottom-right edge of the map in + ; the screen. + ld hl, Ld6b8_diagonal_pattern2 + ld b, 4 + ld de, L5b00_double_buffer + 128*20 + 18 + jp Ld057_draw_diagonal_line ; draws the second part of the bottom-right edge of the map in the + ; screen. + + +; -------------------------------- +Lcffe_clear_5b00_buffer: + ; clears memory to 0 in the following ranges: + ; #5b00 - #6780 (6400 bytes) + ld (Lfd08_stack_ptr_buffer), sp + ld sp, L6780_graphic_patterns ; pointer to the definition of the " " character + ld b, 198 + ld hl, 0 + ; This loop clears from #5b20 - #6780 +Ld00a: + push hl + push hl + push hl + push hl + push hl + push hl + push hl + push hl + djnz Ld00a + ld sp, (Lfd08_stack_ptr_buffer) + ; This clears from #5b00 - #5b20. Potential optimization: just set b above to 200, and remove + ; the rest of this function. + ld hl, L5b00_double_buffer + ld de, L5b00_double_buffer+1 + ld bc, 31 + ld (hl), 0 + ldir + ret + + +; -------------------------------- +; Draws the top-left diagonal black part of the screen (at an 8x8 pixel resolution, the pixel-level +; edges are drawn later in the Ld057_draw_diagonal_line function). +Ld026_draw_top_left_diagonal_map_edge: + ld a, 10 + ld (Ld038_selfmodifying), a + ld (Ld041_selfmodifying), a + ld hl, L5b00_double_buffer + ld b, 5 +Ld033: + push bc + ld b, 8 +Ld036: + push bc +Ld038_selfmodifying: equ $ + 1 + ld b, 10 ; mdl:self-modifying + ld a, 255 +Ld03b: + ld (hl), a + inc hl + djnz Ld03b + pop bc +Ld041_selfmodifying: equ $ + 1 + ld a, 10 ; mdl:self-modifying + call Ld351_add_hl_a + djnz Ld036 + pop bc + push hl + ld hl, Ld038_selfmodifying + dec (hl) + dec (hl) + ld hl, Ld041_selfmodifying + inc (hl) + inc (hl) + pop hl + djnz Ld033 + ret + + +; -------------------------------- +; Draws one of the diagonal line patterns in either Ld6a8 or Ld6b8 to the rendering buffer +; Input: +; - hl: pointer to the source data (16 bytes) +; - de: pointer to the destination buffer to start drawing. At each repetition, we go down 8 +; pixels, and left 16 pixels (to draw a continuous diagonal line) +; - b: number of times to copy the patterh (each time is a 16*8 pixel block). +Ld057_draw_diagonal_line: +Ld057_draw_diagonal_line_loop: + push bc + push hl + ld bc, #08ff ; c to 255 (just a large enough value so that the auto decrement of ldi does + ; not get in the way of the djnz). + ; Draw the diagonal pattern once (16x8 pixels). +Ld05c_draw_diagonal_line_inner_loop: + ldi + ldi + ld a, 18 + add a, e + ld e, a + ld a, d + adc a, 0 + ld d, a ; de += 18 (i.e., 1 line down, since each line of the buffer is 20 bytes wide, and + ; each ldi already increments in one). + djnz Ld05c_draw_diagonal_line_inner_loop + pop hl + pop bc + dec de + dec de + djnz Ld057_draw_diagonal_line_loop + ret + + +; -------------------------------- +; Copies the 160x160 pixels buffer from #5b00 to video memory +Ld071_copy_game_area_buffer_to_screen: + ld hl, L5b00_double_buffer + ld de, L4000_VIDEOMEM_PATTERNS + 33 + ld c, 20 +Ld079_row_outer_loop: + ld b, 8 +Ld07b_row_inner_loop: + push bc + push de + ; copy one whole buffer row (20 bytes) + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + ldi + pop de + pop bc + inc d ; next pixel row + djnz Ld07b_row_inner_loop + ; update the video pointer to the next block of 8 rows: + ld a, e + add a, 32 + ld e, a + jr c, Ld0b4 + ld a, d + sub 8 + ld d, a +Ld0b4: + dec c + jp nz, Ld079_row_outer_loop + ret + + +; -------------------------------- +; Clear the screen +Ld0b9_clear_screen: + xor a + out (ULA_PORT), a ; set border to black, speaker off + ld hl, #4000 + ld de, #4001 + ld bc, 6911 + ld (hl), 0 + ldir + ret + + +; -------------------------------- +Ld0ca_draw_in_game_screen_and_hud: + call Ld0b9_clear_screen + call Lccbd_redraw_game_area + ; Draw white frame around the game area: + ; Top horizontal black line 1: + ld hl, L4000_VIDEOMEM_PATTERNS ; (x, y) = (0, 0) + ld de, L4000_VIDEOMEM_PATTERNS+1 + ld bc, 21 + ld (hl), 255 + ldir + ; Top horizontal black line 2: + ld hl, L4000_VIDEOMEM_PATTERNS + #0701 ; (x, y) = (8, 7) + ld de, L4000_VIDEOMEM_PATTERNS + #0702 + ld bc, 19 + ld (hl), 255 + ldir + ; Bottom horizontal black line 1: + ld hl, L4000_VIDEOMEM_PATTERNS + #10a1 ; (x, y) = (8, 168) + ld de, L4000_VIDEOMEM_PATTERNS + #10a2 + ld bc, 19 + ld (hl), 255 + ldir + ; Bottom horizontal black line 2: + ld hl, L4000_VIDEOMEM_PATTERNS + #17a0 ; (x, y) = (0, 175) + ld de, L4000_VIDEOMEM_PATTERNS + #17a1 + ld bc, 21 + ld (hl), 255 + ldir + ; top-left corner: + ld hl, L4000_VIDEOMEM_PATTERNS + #0100 ; (x, y) = (0, 1) + ld b, 6 +Ld109_loop: + ld (hl), 128 + inc h + djnz Ld109_loop + ; top-right corner: + ld hl, L4000_VIDEOMEM_PATTERNS + #0115 ; (x, y) = (168, 1) + ld b, 6 +Ld113_loop: + ld (hl), 1 + inc h + djnz Ld113_loop + ; bottom-left corner: + ld hl, L4000_VIDEOMEM_PATTERNS + #10a0 ; (x, y) = (0, 168) + ld b, 7 +Ld11d_loop: + ld (hl), 128 + inc h + djnz Ld11d_loop + ; bottom-right corner: + ld hl, L4000_VIDEOMEM_PATTERNS + #10b5 ; (x, y) = (168, 168) + ld b, 7 +Ld127_loop: + ld (hl), 1 + inc h + djnz Ld127_loop + ; left bar: + ld hl, L4000_VIDEOMEM_PATTERNS + #0700 ; (x, y) = (0, 7) + ld b, 162 +Ld131_loop: + ld (hl), 129 + call Ld32a_inc_video_ptr_y_hl + djnz Ld131_loop + ; right bar: + ld hl, L4000_VIDEOMEM_PATTERNS + #0715 ; (x, y) = (128, 7) + ld b, 162 +Ld13d_loop: + ld (hl), 129 + call Ld32a_inc_video_ptr_y_hl + djnz Ld13d_loop + + ; Set the screen attributes: + ; Whole thing to WHITE over BLACK to start: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + ld de, L5800_VIDEOMEM_ATTRIBUTES + 1 + ld bc, 767 + ld (hl), COLOR_WHITE + ldir + ; Black over white for the frame around the game (top)"" + ; Potential optimization: If we change the pixels in the border drawing code above, we can + ; remove all of the lines below for the frame attributes + ; Top line: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + ld de, L5800_VIDEOMEM_ATTRIBUTES + 1 + ld bc, 21 + ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER + ldir + ; Bottom line: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #02a0 + ld de, L5800_VIDEOMEM_ATTRIBUTES + #02a0 + 1 + ld bc, 21 + ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER + ldir + ; Side bars: + ld hl, 22560 + ld b, 20 +Ld170_loop: + ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER + ld a, 21 + call Ld351_add_hl_a + ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER + ld a, 11 + call Ld351_add_hl_a + djnz Ld170_loop + + ; In-game screen yellow color: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021 + ld bc, #1414 ; 20, 20 +Ld186_outer_loop: + push bc +Ld187_inner_loop: + ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER + inc hl + djnz Ld187_inner_loop + pop bc + ld a, 12 + call Ld351_add_hl_a + dec c + jr nz, Ld186_outer_loop + + ; blue 3-d effect in the bottom-right of the map: + ; Yellow -> blue border: + ld b, 4 + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0233 +Ld19a_loop: + ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER + COLOR_BLUE + inc hl + ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER + COLOR_BLUE + ld a, 29 + call Ld351_add_hl_a + djnz Ld19a_loop + ; Blue -> black border: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0253 + ld (hl), COLOR_BRIGHT + COLOR_BLUE + inc hl + ld (hl), COLOR_BRIGHT + COLOR_BLUE + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0271 + ld b, 4 +Ld1b3_loop: + ld (hl), COLOR_BRIGHT + COLOR_BLUE + inc hl + djnz Ld1b3_loop + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #028f + ld b, 6 +Ld1bd_loop: + ld (hl), COLOR_BRIGHT + COLOR_BLUE + inc hl + djnz Ld1bd_loop + + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_ATTRIBUTE, #57 + db CMD_SET_POSITION, #00, #16 + db CMD_SET_SCALE, #00 + db " DAY:" + db CMD_NEXT_LINE + db "TIME:" + db CMD_SET_POSITION, #16, #00 + db CMD_SET_SCALE, #21 + db CMD_SET_ATTRIBUTE, #45 + db "RADAR:" + db CMD_END + ; Script end: +Ld1e5_draw_in_game_right_hud: + call Ld2f6_clear_in_game_right_hud + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #03, #16 + db CMD_SET_ATTRIBUTE, #46 + db " STATUS" + db CMD_NEXT_LINE + db "INSG HUMN" + db CMD_SET_POSITION, #06, #17 + db CMD_SET_ATTRIBUTE, #45 + db "WARBASES" + db CMD_NEXT_LINE + db "ELECTR'S" + db CMD_NEXT_LINE + db "NUCLEAR" + db CMD_NEXT_LINE + db "PHASERS" + db CMD_NEXT_LINE + db "MISSILES" + db CMD_NEXT_LINE + db " CANNON" + db CMD_NEXT_LINE + db "CHASSIS" + db CMD_NEXT_LINE + db " ROBOTS" + db CMD_SET_POSITION, #0f, #17 + db CMD_SET_ATTRIBUTE, #46 + db "RESOURCES" + db CMD_NEXT_LINE + db CMD_NEXT_LINE + db CMD_SET_ATTRIBUTE, #44 + db "GENERAL" + db CMD_NEXT_LINE + db "ELECTR'" + db CMD_NEXT_LINE + db "NUCLEAR" + db CMD_NEXT_LINE + db "PHASERS" + db CMD_NEXT_LINE + db "MISSILE" + db CMD_NEXT_LINE + db "CANNON" + db CMD_NEXT_LINE + db "CHASSIS" + db CMD_END + ; Script end: +Ld293_update_stats_in_right_hud: + ld a, (Lfd39_current_in_game_right_hud) + or a + ret nz ; If the stats are not to be displayed now, just return + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #10, #1e + db CMD_SET_ATTRIBUTE, #4e + db CMD_SET_SCALE, #00 + db CMD_END + ; Script end: + ; Print player resources: + ld hl, Lfd22_player1_resource_counts + ld b, 7 +Ld2a8_player_resources_loop: + push bc + push hl + call Ld470_execute_command_3_next_line + pop hl + ld a, (hl) + inc hl + push hl + call Ld3e5_render_8bit_number + pop hl + pop bc + djnz Ld2a8_player_resources_loop + + ; Print AI stats: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #06, #16 + db CMD_SET_ATTRIBUTE, #47 + db CMD_END + ; Script end: + ld hl, Lfd42_player2_base_factory_counts + call Ld2e3_draw_warbase_factory_counts + ld a, (hl) + call Ld3ec_render_8bit_number_with_leading_zeroes + + ; Print Player stats: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #06, #1f + db CMD_END + ; Script end + ld hl, Lfd3a_player1_base_factory_counts + call Ld2e3_draw_warbase_factory_counts + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #0d, #1e + db CMD_END + ; Script end + ld a, (hl) + jp Ld3ec_render_8bit_number_with_leading_zeroes + + +; -------------------------------- +; Draws the number of warbases and factories of each type a given player owns. +; Inputs: +; - hl: counts pointer +Ld2e3_draw_warbase_factory_counts: + ld b, 7 +Ld2e5_draw_warbase_factory_counts_loop: + push bc + ld a, (hl) + inc hl + add a, 48 + call Ld427_draw_character_saving_registers + push hl + call Ld470_execute_command_3_next_line + pop hl + pop bc + djnz Ld2e5_draw_warbase_factory_counts_loop + ret + + +; -------------------------------- +; Clears the right-hand-size hud in-game, except for the day and time. +Ld2f6_clear_in_game_right_hud: + call Ld42d_execute_ui_script + ; Script start: + db CMD_SET_POSITION, #02, #16 + db CMD_SET_SCALE, #00 + db CMD_SET_ATTRIBUTE, #00 + db CMD_END + ; Script end: + ld b, 22 ; Clears 22 lines (everything but the top two, which is the day and time): +Ld303_loop: + call Ld42d_execute_ui_script + ; Script start: + db " " + db CMD_NEXT_LINE + db CMD_END + ; Script end: + djnz Ld303_loop + ret + + +; -------------------------------- +; Input: +; - de: video pointer to draw +; - hl: sprite ptr in RAM +; - b: prite width in bytes +; - c: sprite height in pixels +Ld315_draw_masked_sprite_bottom_up: +Ld315_draw_masked_sprite_x_loop: + push bc + push de +Ld317_draw_masked_sprite_y_loop: + ld a, (de) ; get a pixel from the screen + and (hl) ; and mask (clear some pixels) + inc hl + or (hl) ; or mask (draw pixels) + ld (de), a ; write back to the screen + inc hl ; next pixel + inc de + djnz Ld317_draw_masked_sprite_y_loop + pop de + pop bc + call Ld339_dec_video_ptr_y_de + dec c + jp nz, Ld315_draw_masked_sprite_x_loop + ret + + +; -------------------------------- +; Move a pointer 1 pixel down in the screen +; hl: video memory pointer as: 010ccaaa bbbxxxxx +; The y coordinate is ccbbbaaa +Ld32a_inc_video_ptr_y_hl: + inc h + ld a, #07 + and h + ret nz + ld a, l + add a, 32 + ld l, a + ret c + ld a, h + sub 8 + ld h, a + ret + + +; -------------------------------- +; Move a pointer 1 pixel up in the screen +; hl: video memory pointer as: 010ccaaa bbbxxxxx +; The y coordinate is ccbbbaaa +Ld339_dec_video_ptr_y_de: + ld a, d + dec d + and #07 + ret nz + ld a, e + sub 32 + ld e, a + ret c + ld a, d + add a, 8 + ld d, a + ret + + +; -------------------------------- +; input: +; - a, hl +; output: +; - hl = (hl + a*2) +Ld348_get_ptr_from_table: + add a, a + call Ld351_add_hl_a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ret + + +; -------------------------------- +; hl = hl + a +Ld351_add_hl_a: + add a, l + ld l, a + ld a, h + adc a, 0 + ld h, a + ret + + +; -------------------------------- +; Random number generation: uses a 4 byte seed buffer in #fd00 +; output: +; - a: next random number +; preserves: hl +Ld358_random: + push hl + ld hl, Lfd00_random_seed + ld a, (hl) + and 72 + add a, 56 + rlca + rlca + ld l, 3 + rl (hl) + dec l + rl (hl) + dec l + rl (hl) + dec l + rl (hl) +Ld370_selfmodifying: equ $ + 1 + ld l, 0 ; mdl:self-modifying + ld a, (hl) + and 3 + ld l, a + ld (Ld370_selfmodifying), a ; self-modifying: overwrites the argument of the instruction + ; marked above. + ld a, (hl) + pop hl + ret + + +; -------------------------------- +; Reads the keyboard and joystick input, and stores the state in (Lfd0c_keyboard_state). +; - If the user presses the pause key, this function is blocked until the user presses it again. +; Output: +; - a: keyboard state (also stored in "Lfd0c_keyboard_state") +Ld37c_read_keyboard_joystick_input: + call Ld38a_read_keyboard_joystick_input_internal + or a + ret p ; if pause key was not pressed, return +Ld381_pause: + call Ld38a_read_keyboard_joystick_input_internal + or a + jr z, Ld381_pause + jp m, Ld381_pause + +Ld38a_read_keyboard_joystick_input_internal: + ld hl, Ld3cc_key_pause + ld c, 1 ; set a 1 in the least significant bit, so that when we rotate this 8 times, + ; the carry flag is set to indicate end of iteration +Ld38f_key_loop: + ld a, (hl) ; keyboard matrix row to read + inc hl + in a, (ULA_PORT) ; a = high byte, ULA_PORT = low byte + and (hl) ; mask to isolate the desired key + inc hl + inc hl + ; at this point carry flag is always reset ("inc" does not touch it, and "and" resets it) + jr nz, Ld399_key_not_pressed + ccf ; set carry flag +Ld399_key_not_pressed: + rl c ; add the bit corresponding to one key to "c" (which was in the carry flag) + jr nc, Ld38f_key_loop ; carry flag will be set after 8 loops (checked al 8 keys) + ld a, (Ld3e4_input_type) + cp INPUT_KEMPSTON + jr z, Ld3ab_read_kempston + cp INPUT_INTERFACE2 + jr z, Ld3b2_read_interface2 + xor a + jr Ld3c7_all_inputs_read +Ld3ab_read_kempston: + xor a + in a, (KEMPSTON_JOYSTICK_PORT) ; read the kempston joystick state + and #1f + jr Ld3c7_all_inputs_read +Ld3b2_read_interface2: + ld a, INTERFACE2_JOYSTICK_PORT_MSB ; read the interface2 joystick state. + in a, (ULA_PORT) ; a = high byte, ULA_PORT = low byte + cpl + and #1f + ; reorder the interface2 bits so they are in the same order as they keyboard ones: + ld b, a + xor a + srl b + rla + srl b + rla + srl b + rla + rla + rla + or b +Ld3c7_all_inputs_read: + or c ; potentially add joystick inputs over to the keyboard ones + ld (Lfd0c_keyboard_state), a + ret + + +; -------------------------------- +; Array storing the redefined keys: +; - first byte is the high byte of the address to read from to get the correct keyboard matrix row. +; - the second is the mask we need to apply to the value read from the keyboard matrix to isolate +; the key. +; - third value is the ascii representation of the key. +Ld3cc_key_pause: + db #f7, #01, #31 ; 247, 1, "1" +Ld3cf_key_abort: + db #df, #04, #49 ; 223, 4, "I" +Ld3d2_key_save: + db #f7, #10, #35 ; 247, 16, "5" +Ld3d5_key_fire: + db #7f, #02, #82 ; 127, 2, 130 +Ld3d8_key_up: + db #fb, #01, #51 ; 251, 1, "Q" +Ld3db_key_down: + db #fd, #01, #41 ; 253, 1, "A" +Ld3de_key_left: + db #df, #02, #4f ; 223, 2, "O" +Ld3e1_key_right: + db #df, #01, #50 ; 223, 1, "P" +Ld3e4_input_type: + db #01 + + +; -------------------------------- +Ld3e5_render_8bit_number: + ld l, a + ld h, 0 + ld e, ' ' + jr Ld407_render_16bit_number_2digits + + +; -------------------------------- +Ld3ec_render_8bit_number_with_leading_zeroes: + ld l, a + ld h, 0 + ld e, 0 + jr Ld407_render_16bit_number_2digits + + +; -------------------------------- +; Draws a 16bit number to screen. +; input: +; - hl: the number to draw +Ld3f3_render_16bit_number: + ld bc, -10000 + ld e, ' ' + call Ld413_render_16bit_number_one_digit + ld bc, -1000 + call Ld413_render_16bit_number_one_digit +Ld401_render_16bit_number_3digits: + ld bc, -100 + call Ld413_render_16bit_number_one_digit +Ld407_render_16bit_number_2digits: + ld bc, -10 +Ld40a: + call Ld413_render_16bit_number_one_digit + ld a, l + add a, 48 + jp Ld427_draw_character_saving_registers + + +; -------------------------------- +; - hl: number to draw. +; - bc: unit to draw (-10 for tenths, -100 for hundreds, -1000 for thousands, etc.). +; - e: filler character to use in the left for the leading zeros. +Ld413_render_16bit_number_one_digit: + xor a +Ld414_remainder_loop: + add hl, bc + inc a + jr c, Ld414_remainder_loop + sbc hl, bc + dec a ; Here, a = hl / (-bc), and hl = hl % (-bc) + jr nz, Ld424 + ld a, e + cp 32 + jp z, Ld427_draw_character_saving_registers + xor a +Ld424: + inc e ; if the filler character was a space, change it so that the rest of + ; empty digits are rendered as zeros. + add a, 48 ; '0' +Ld427_draw_character_saving_registers: + exx + call Ld4b1_draw_character + exx + ret + + +; -------------------------------- +; Executes some data-defined scripts (pointer of the script is in the stack): +; Script definition: +; - 0: end of script +; - 1: set screen coordinates +; - 2: set attribute +; - 3: next line +; - 4: set scale +; - default: render a character +; input: +; - address of data to use is in the stack +Ld42d_execute_ui_script: + exx +Ld42e_loop: + pop hl + ld a, (hl) + inc hl + push hl + or a + jr z, Ld43a_done + call Ld43c_execute_one_command + jr Ld42e_loop +Ld43a_done: + exx + ret + + +; -------------------------------- +Ld43c_execute_one_command: + cp 1 + jr z, Ld461_execute_command_1_screen_coordinates + cp 2 + jr z, Ld457_execute_command_2_set_attribute + cp 3 + jr z, Ld470_execute_command_3_next_line + cp 4 + jr z, Ld47c_execute_command_4_set_scale + ld c, a + ld a, (Lfd17_script_scale_x) + or a + ld a, c + jr z, Ld4b1_draw_character + jp Ld4b1_draw_character_scaled + + +; -------------------------------- +Ld457_execute_command_2_set_attribute: + pop de + pop hl + ld a, (hl) + inc hl + push hl + push de + ld (Lfd13_script_attribute), a + ret + + +; -------------------------------- +Ld461_execute_command_1_screen_coordinates: + pop de + pop hl + ld b, (hl) + inc hl + ld c, (hl) + ld (Lfd31_script_coordinate), bc + inc hl + push hl + push de + jp Ld493_compute_videomem_ptrs + + +; -------------------------------- +Ld470_execute_command_3_next_line: + ld bc, (Lfd31_script_coordinate) + inc b + ld (Lfd31_script_coordinate), bc + jp Ld493_compute_videomem_ptrs + + +; -------------------------------- +; Reads one byte: yyyyxxxx, and sets the scale to draw characters from +; each of the two nibbles of that byte: +; - (Lfd16_script_scale_y) = xxxx +; - (Lfd16_script_scale_y) = yyyy +; Input: +; - in the stack: ptr to read a byte from (will be incremented) +Ld47c_execute_command_4_set_scale: + pop de + pop hl + ld a, (hl) + inc hl + push hl + push de + ld c, a + rrca + rrca + rrca + rrca + and 15 + ld (Lfd16_script_scale_y), a + ld a, c + and 15 + ld (Lfd17_script_scale_x), a + ret + + +; -------------------------------- +; Recalculate pattern table and attribute table pointers +; input: +; - bc: value of Lfd31_script_coordinate +; output: +; - Lfd04_script_video_pattern_ptr +; - Lfd14_script_video_attribute_ptr +Ld493_compute_videomem_ptrs: + ld a, b + and 248 ; #f8 + add a, 64 + ld h, a ; h = (b & #f8) + 64 + ld a, b + and 7 + rrca + rrca + rrca + add a, c + ld l, a ; l = "high 3 bits of b" + c + ld (Lfd04_script_video_pattern_ptr), hl + ld a, h + rrca + rrca + rrca + and 3 + or 88 + ld h, a + ld (Lfd14_script_video_attribute_ptr), hl + ret + + +; -------------------------------- +; input: +; - a: character to draw +; - (Lfd04_script_video_pattern_ptr) pointer to draw it to in video memory (will be incremented) +; - (Lfd14_script_video_attribute_ptr) pointer to set the attributes in video memory (will be +; incremented). +Ld4b1_draw_character: + ld h, 0 + ld l, a + add hl, hl + add hl, hl + add hl, hl + ld de, L6780_graphic_patterns - 32*8 ; there is only data for characters starting at ' ' (32) + add hl, de ; hl = a * 8 + #6680 : get ptr to character to draw + ld de, (Lfd04_script_video_pattern_ptr) + push de + ld b, 8 +Ld4c2_loop: + ld a, (hl) + ld (de), a + inc hl + inc d + djnz Ld4c2_loop + pop de + inc de + ld (Lfd04_script_video_pattern_ptr), de + ld hl, (Lfd14_script_video_attribute_ptr) + ld a, (Lfd13_script_attribute) + ld (hl), a + inc hl + ld (Lfd14_script_video_attribute_ptr), hl + ret + + +; -------------------------------- +; input: +; - a: character to draw +Ld4b1_draw_character_scaled: + ld h, 0 + ld l, a + add hl, hl + add hl, hl + add hl, hl + ld de, L6780_graphic_patterns - 32*8 ; there is only data for characters starting at ' ' (32) + add hl, de ; hl = a * 8 + #6680 : get ptr to character to draw + ld a, (Lfd17_script_scale_x) + cp 2 + jr nc, Ld502 + ex de, hl + ld hl, (Lfd04_script_video_pattern_ptr) + ld c, 8 +Ld4f1: + ld a, (Lfd16_script_scale_y) + ld b, a +Ld4f5: + ld a, (de) + ld (hl), a + call Ld32a_inc_video_ptr_y_hl + djnz Ld4f5 + inc de + dec c + jr nz, Ld4f1 + jr Ld532 +Ld502: + push ix + push hl + pop ix + ld hl, (Lfd04_script_video_pattern_ptr) + ld c, 8 +Ld50c: + ld a, (ix) + ld b, 8 +Ld511: + rlca + push af + rl e + rl d + pop af + rl e + rl d + djnz Ld511 + ld a, (Lfd16_script_scale_y) + ld b, a +Ld522: + ld (hl), d + inc l + ld (hl), e + dec l + call Ld32a_inc_video_ptr_y_hl + djnz Ld522 + inc ix + dec c + jr nz, Ld50c + pop ix +Ld532: + ld hl, (Lfd04_script_video_pattern_ptr) + ld a, (Lfd17_script_scale_x) + call Ld351_add_hl_a + ld (Lfd04_script_video_pattern_ptr), hl + ld hl, (Lfd14_script_video_attribute_ptr) + push hl + ld bc, (Lfd16_script_scale_y) + ld a, (Lfd13_script_attribute) + ld e, a +Ld54a: + push hl + push bc +Ld54c: + ld (hl), e + inc hl + djnz Ld54c + pop bc + pop hl + ld a, l + add a, 32 + ld l, a + ld a, h + adc a, 0 + ld h, a + dec c + jr nz, Ld54a + pop hl + ld a, b + call Ld351_add_hl_a + ld (Lfd14_script_video_attribute_ptr), hl + ret + + +; -------------------------------- +; Interrupt handler routine +Ld566_interrupt: + push af + push bc + push de + push hl + ; Increments the # of interrupts counter (for game timing purposes): + ld hl, Lfd34_n_interrupts_this_came_cycle + inc (hl) + ; Draw the radar (flickering): + ; Player and enemy robots are drawn to view1 and view2 respectively, and in this way, when + ; showing them, they show in different colors. + ld hl, Ld800_radar_view1 + ld c, COLOR_BRIGHT + COLOR_CYAN + PAPER_COLOR_MULTIPLIER * COLOR_BLUE + ld a, (Lfd1a_interrupt_parity) + xor 1 + ld (Lfd1a_interrupt_parity), a + jr z, Ld582_radar_flicker + ld hl, Ld900_radar_view2 + ld c, COLOR_BRIGHT + COLOR_YELLOW + PAPER_COLOR_MULTIPLIER * COLOR_BLUE +Ld582_radar_flicker: + call Ld59e_draw_radar + ld a, (Lfd53_produce_in_game_sound) + or a + jr z, Ld598_no_sound + inc a + cp 128 + jr nz, Ld591_keep_sound + xor a +Ld591_keep_sound: + ld (Lfd53_produce_in_game_sound), a + or a + call nz, Ld5c4_produce_in_game_sound +Ld598_no_sound: + pop hl + pop de + pop bc + pop af +Ld59c_empty_interrupt: + ei + ret + + +; -------------------------------- +; Draws the radar view to video memory +Ld59e_draw_radar: + ; Draw the radar to video memory: + push bc + ld b, 16 + ld de, L4000_VIDEOMEM_PATTERNS + #10c6 ; pointer to the "radar" view in video memory +Ld5a4_draw_radar_loop_y: + push bc + push de + ; Copy a radar row (16 bytes wide) + ld bc, 16 + ldir + pop de + ex de, hl + call Ld32a_inc_video_ptr_y_hl + ex de, hl + pop bc + djnz Ld5a4_draw_radar_loop_y + pop bc + ; Set the attributes: + ld hl, L5800_VIDEOMEM_ATTRIBUTES + #02c6 ; pointer to the attributes of the radar + call Ld5bd_set_radar_attributes_one_row + ld l, #e6 ; second line +Ld5bd_set_radar_attributes_one_row: + ld b, 16 +Ld5bf_radar_attributes_loop_x: + ld (hl), c + inc hl + djnz Ld5bf_radar_attributes_loop_x + ret + + +; -------------------------------- +; Produces in-game sound based on the value of "a". +; There are two types of possible sounds: +; - if a is positive, it'll produce some sound based on reading values from ROM (starting at 0 +; address). +; - if a is negative, it produces sound based on the random number generator. +; Input: +; - a: type of sound to produce +Ld5c4_produce_in_game_sound: + jp m, Ld5ec_random_noise + ; if "a" is positive, produce a different type of sound: + ld b, a + inc a + inc a + ld hl, 500 + ld e, a + ld d, 0 + ld c, 0 + xor a +Ld5d3: + inc c + sbc hl, de + jr nc, Ld5d3 + ld hl, 0 ; read values from the ROM at this address (which will be noise, but a different type + ; of noise). +Ld5db: + push bc + ld a, (hl) + inc hl + and 16 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) +Ld5e2: + djnz Ld5e2 + pop bc + dec c + jr nz, Ld5db + xor a + out (ULA_PORT), a ; change MIC/EAR state (sound off) + ret + + +; -------------------------------- +; Produce random noise for a short period of time: +Ld5ec_random_noise: + ld b, 30 +Ld5ee_loop: + call Ld358_random + and 16 + out (ULA_PORT), a ; change MIC/EAR state (to produce sound) + djnz Ld5ee_loop + ret + + +; -------------------------------- +; Updates the two radar buffers (Ld800_radar_view1, Ld800_radar_view2) with all the +; buildings and robots in the map. +Ld5f8_update_radar_buffers: + ld hl, Ld800_radar_view1 + ld de, (Lfd1c_radar_scroll_x) + ld a, d + add a, #dd + ld d, a ; de now has the pointer to the map buffer (Ldd00_map) corresponding to the radar view + ; Updates the contents of the radar: + ld bc, #1010 ; 16, 16 +Ld606_radar_update_loop_y: + push bc + push de +Ld608_radar_update_loop_x: + push bc + ld b, 8 +Ld60b_radar_update_loop_byte: + ld a, (de) + inc de + and #1f + cp #0f + ccf ; carry = 1 if the map has an element > 15 (building) + rl (hl) ; this inserts a 0/1 from the left of the byte. Since we iterate this loop 8 + ; times, it will eventually replace the old value of this byte in the radar + ; buffer. + djnz Ld60b_radar_update_loop_byte + inc hl + pop bc + djnz Ld608_radar_update_loop_x + pop de + pop bc + ; increment "y": + inc d + inc d + dec c + jr nz, Ld606_radar_update_loop_y + + ; Sync both radar views: + ld hl, Ld800_radar_view1 ; player and player robots will be drawn to view 1 + ld de, Ld900_radar_view2 ; enemy robots are drawn to view 2 + ld bc, 256 + ldir + + ; Update robots in the radar view: + ld iy, Lda00_player1_robots + ld b, MAX_ROBOTS_PER_PLAYER * 2 +Ld632: + push bc + ld a, (iy + 1) + or a + jr z, Ld651_next_robot ; If there is no robot in this struct, skip + ld l, (iy + ROBOT_STRUCT_X) + ld h, (iy + ROBOT_STRUCT_X + 1) + ld c, (iy + ROBOT_STRUCT_Y) + ld a, (iy + ROBOT_STRUCT_CONTROL) + rlca + and 1 + ld b, a ; b = 0 if player robot, and b = 1 if enemy robot. + ld a, (iy + ROBOT_STRUCT_CONTROL) + cp 2 + call nz, Ld65a_flip_2x2_radar_area +Ld651_next_robot: + ld de, ROBOT_STRUCT_SIZE + add iy, de + pop bc + djnz Ld632 + ret + + +; -------------------------------- +; Flicker a 2x2 area in the radar view. This function will get the pointer +; in the radar view corresponding to the given coordinates, and then flip +; the bits in a 2x2 area around it. +; Input: +; - hl: x coordinate +; - b: whether to use Ld800_radar_view1 (b == 0), or Ld900_radar_view2 (b == 1) +; - c: y coordinate +Ld65a_flip_2x2_radar_area: + call Ld67d_get_radar_view_pointer + ld c, a + ; Flip the first row of 2 bits: + push hl + ld a, (hl) + xor c + ld (hl), a + rrc c + jr nc, Ld667_not_crossing_to_the_next_byte + inc hl +Ld667_not_crossing_to_the_next_byte: + ld a, (hl) + xor c + ld (hl), a + pop hl + ; Flip the next row of 2 bits: + ld a, l + sub 16 + ld l, a + rlc c + ld a, (hl) + xor c + ld (hl), a + rrc c + jr nc, Ld679_not_crossing_to_the_next_byte + inc hl +Ld679_not_crossing_to_the_next_byte: + ld a, (hl) + xor c + ld (hl), a + ret + + +; -------------------------------- +; Get radar view pointer +; input: +; - hl: x coordinate +; - b: whether to use Ld800_radar_view1 (b == 0), or Ld900_radar_view2 (b == 1) +; - c: y coordinate +; output: +; - a: bit (one-hot representation) that corresponds to the given coordinates. +; - hl: byte in the radar view that corresponds to the given coordinates. +Ld67d_get_radar_view_pointer: + ld de, (Lfd1c_radar_scroll_x) + xor a + sbc hl, de + ld a, h + or a + ; return if when we subtracted "de" from the x coordinate, we don't get a number between 0 and + ; 127: + jr nz, Ld6a6_exit + ld a, l + cp 127 + jr nc, Ld6a6_exit + + ; here we know that hl - de is on [0,127] + ld a, Ld800_radar_view1 / 256 + add a, b + ld h, a ; h = b + #d8 + ld a, l + and #07 + inc a + ld b, a ; b = ((hl - de)%8) + 1 + ld a, l + rlca ; a = (hl - de)*2 -> xxxxxxx0 + and #f0 ; We keep only the upper 4 bits -> xxxx0000 + or c ; xxxxyyyy + rlca + rlca + rlca + rlca + ld l, a ; a = yyyyxxxx. Where yyyy is the y coordinate (in c), and xxxx are bits 3-6 of hl-de + xor a + scf +Ld6a2_shift_loop: + rra + djnz Ld6a2_shift_loop + ; here "a" is a one-hot representation of (hl - de)%8 + ret +Ld6a6_exit: + pop hl ; simulate a ret (so, we return from Ld65a_flip_2x2_radar_area, which is the only + ; caller of this function) + ret + + +; -------------------------------- +Ld6a8_diagonal_pattern1: ; diagonal line (top-left painted, bottom-left empty) + db #ff, #ff, #ff, #fc, #ff, #f0, #ff, #c0, #ff, #00, #fc, #00, #f0, #00, #c0, #00 +Ld6b8_diagonal_pattern2: ; diagonal line (top-left empty, bottom-left painted) + db #00, #03, #00, #0f, #00, #3f, #00, #ff, #03, #ff, #0f, #ff, #3f, #ff, #ff, #ff + + +; -------------------------------- +Ld6c8_piece_direction_graphic_indices: + ; Index of the graphic to draw for each piece in each of the 4 cardinal directions. + ; For example, notice how "nuclear" has the same graphic regardless of the direction. + ; To find the specific graphic in the "Ld740_isometric_graphic_pointers" table below, + ; multiply the index by 2 (as each graphic is stored twice, one with a precalculated + ; offset of 4 pixels). + db 2, 2, 3, 3 ; bipod + db 0, 0, 1, 1 ; tracks + db 4, 4, 4, 4 ; antigrav + db 5, 6, 7, 8 ; cannon + db 9, 9, 10, 10 ; missiles + db 11, 12, 13, 14 ; phasers + db 15, 15, 15, 15 ; nuclear + db 16, 17, 18, 19 ; electronics + + +; -------------------------------- +Ld6e8_additional_isometric_graphic_pointers: ; 44 pointers + dw L8e3a_iso_additional_graphic_0 + dw L8f2c_iso_additional_graphic_1 + dw L901e_iso_additional_graphic_2 + dw L90b0_iso_additional_graphic_3 + dw L9172_iso_additional_graphic_4 + dw L9172_iso_additional_graphic_4 + dw L91f2_iso_additional_graphic_5 + dw L91f2_iso_additional_graphic_5 + dw L9278_iso_additional_graphic_6 + dw L9278_iso_additional_graphic_6 + dw L92f8_iso_additional_graphic_7 + dw L92f8_iso_additional_graphic_7 + dw L9d9c_iso_additional_graphic_22 + dw L9e34_iso_additional_graphic_23 + dw L9ef6_iso_additional_graphic_24 + dw L9f8e_iso_additional_graphic_25 + dw L9372_iso_additional_graphic_8 + dw L9372_iso_additional_graphic_8 + dw L940a_iso_additional_graphic_9 + dw L940a_iso_additional_graphic_9 + dw L94a8_iso_additional_graphic_10 + dw L94a8_iso_additional_graphic_10 + dw L9534_iso_additional_graphic_11 + dw L9534_iso_additional_graphic_11 + dw L95c6_iso_additional_graphic_12 + dw L9640_iso_additional_graphic_13 + dw L96ea_iso_additional_graphic_14 + dw L9776_iso_additional_graphic_15 + dw L9820_iso_additional_graphic_16 + dw L98ac_iso_additional_graphic_17 + dw L9914_iso_additional_graphic_18 + dw L9a16_iso_additional_graphic_19 + dw L9b18_iso_additional_graphic_20 + dw L9c5a_iso_additional_graphic_21 + dw La0e2_iso_additional_graphic_27 + dw La1e4_iso_additional_graphic_28 + dw La2e6_iso_additional_graphic_29 + dw La428_iso_additional_graphic_30 + dw L8e3a_iso_additional_graphic_0 + dw L8e3a_iso_additional_graphic_0 + dw L8e3a_iso_additional_graphic_0 + dw L8e3a_iso_additional_graphic_0 + dw La050_iso_additional_graphic_26 + dw La050_iso_additional_graphic_26 + +Ld740_isometric_graphic_pointers: ; 58 pointers + dw L6980_iso_graphic_0 ; tracks + dw L6a24_iso_graphic_1 + dw L6afe_iso_graphic_2 + dw L6ba8_iso_graphic_3 + dw L6c8a_iso_graphic_4 ; bipod + dw L6d40_iso_graphic_5 + dw L6e32_iso_graphic_6 + dw L6ee2_iso_graphic_7 + dw L6fcc_iso_graphic_8 ; antigrav + dw L7058_iso_graphic_9 + dw L7112_iso_graphic_10 ; cannon + dw L71bc_iso_graphic_11 + dw L729e_iso_graphic_12 + dw L7354_iso_graphic_13 + dw L7446_iso_graphic_14 + dw L74fc_iso_graphic_15 + dw L75ee_iso_graphic_16 + dw L7686_iso_graphic_17 + dw L7750_iso_graphic_18 ; missiles + dw L77f4_iso_graphic_19 + dw L78ce_iso_graphic_20 + dw L7978_iso_graphic_21 + dw L7a5a_iso_graphic_22 ; phaser + dw L7b04_iso_graphic_23 + dw L7be6_iso_graphic_24 + dw L7c96_iso_graphic_25 + dw L7d80_iso_graphic_26 + dw L7e30_iso_graphic_27 + dw L7f1a_iso_graphic_28 + dw L7fb8_iso_graphic_29 + dw L808a_iso_graphic_30 ; nuclear + dw L813a_iso_graphic_31 + dw L8224_iso_graphic_32 + dw L82b6_iso_graphic_33 + dw L8348_iso_graphic_34 + dw L83da_iso_graphic_35 + dw L846c_iso_graphic_36 + dw L84fe_iso_graphic_37 + dw L8590_iso_graphic_38 + dw L8622_iso_graphic_39 + dw L86b4_iso_graphic_40 + dw L86f8_iso_graphic_41 + dw L8752_iso_graphic_42 + dw L8796_iso_graphic_43 + dw L87f0_iso_graphic_44 + dw L8858_iso_graphic_45 + dw L88e2_iso_graphic_46 + dw L8924_iso_graphic_47 + dw L8966_iso_graphic_48 + dw L89b6_iso_graphic_49 + dw L8a06_iso_graphic_50 + dw L8a8c_iso_graphic_51 + dw L8b3e_iso_graphic_52 + dw L8bc4_iso_graphic_53 + dw L8c76_iso_graphic_54 + dw L8cde_iso_graphic_55 + dw L8d46_iso_graphic_56 + dw L8dc0_iso_graphic_57 + + +; -------------------------------- +Ld7b4_piece_heights: + db 11 ; bipod + db 7 ; tracks + db 8 ; antigrav + db 6 ; cannon + db 6 ; missiles + db 7 ; phasers + db 7 ; nuclear + db 7 ; electronics + +Ld7bc_map_piece_heights: ; 23 elements + db #00, #00, #02, #02, #02, #02, #03, #03, #06, #06, #06, #06, #00, #00, #00, #07 + db #0f, #07, #0f, #00, #00, #63, #00 + + +; -------------------------------- +; RAM Variables: +Ld7d3_bullets: equ #d7d3 ; 5 * 9 bytes +Ld800_radar_view1: equ #d800 ; 256 bytes. Player and player robots are drawn here +Ld900_radar_view2: equ #d900 ; 256 bytes. Enemy robots are drawn here + + +; When saving a game, RAM is stored starting from here: +Ld92b_save_game_start: equ #d92b ; 213 bytes, buffer where a few things are copied before saving a + ; game: bullet state (45 bytes), and 168 bytes from + ; Lff01_building_decorations. +Lda00_player1_robots: equ #da00 ; 384 bytes (24 robots * 16 bytes per robot) +Ldb80_player2_robots: equ #db80 ; 384 bytes (24 robots * 16 bytes per robot) + +; Each byte of the map is organized as: +; - dcbaaaaa: +; - aaaaa: element type +; - b: as elements use a 2x2 position, only the bottom-left corner has this as 0 +; - c: indicates a robot/factory/warbase is here +; - d: indicates player is here +Ldd00_map: equ #dd00 ; map: 512*16 = 8192 bytes + +Lfd00_random_seed: equ #fd00 ; 4 bytes +Lfd04_script_video_pattern_ptr: equ #fd04 ; 2 bytes +Lfd06_scroll_ptr: equ #fd06 ; 2 bytes +Lfd08_stack_ptr_buffer: equ #fd08 ; 2 bytes +Lfd0a_scroll_x: equ #fd0a ; 2 bytes +Lfd0c_keyboard_state: equ #fd0c ; 1 byte +Lfd0d_player_y: equ #fd0d ; 1 byte. Narrow axis of the map. +Lfd0e_player_x: equ #fd0e ; 2 bytes. Long axis of the map +Lfd10_player_altitude: equ #fd10 ; 1 byte. +Lfd11_player_iso_coordinates_if_deferred: equ #fd11 ; 2 bytes. If rendering of the player is + ; sprite is deferred due to an overlapping + ; sprite, this will contain the original + ; isometric coordinates of the player sprite. +Lfd13_script_attribute: equ #fd13 ; 1 byte +Lfd14_script_video_attribute_ptr: equ #fd14 ; 2 bytes +Lfd16_script_scale_y: equ #fd16 ; 1 byte +Lfd17_script_scale_x: equ #fd17 ; 1 byte +; 2 unused bytes +Lfd1a_interrupt_parity: equ #fd1a ; 1 byte. Used to determine if we are in an even or odd + ; interrupt call. +Lfd1b_radar_scroll_x_tile: equ #fd1b ; 1 byte. Same as the variable below, but at tile resolution. +Lfd1c_radar_scroll_x: equ #fd1c ; 2 bytes +Lfd1e_player_visible_in_radar: equ #fd1e ; 1 byte. The least-significant bit of this variable + ; represents whether to draw the player in the radar or + ; not. It's used to make the player blink. +Lfd1f_cursor_position: equ #fd1f ; 2 bytes: x, y +Lfd21_construction_selected_pieces: equ #fd21 ; 1 byte +Lfd22_player1_resource_counts: equ #fd22 ; 7 bytes +Lfd29_resource_counts_buffer: equ #fd29 ; 7 bytes. Used, for example, in the robot construction + ; screen, to keep track of resources left after the + ; selected pieces are discounted from the resources. +Lfd30_player_elevate_timer: equ #fd30 ; 1 byte. If this is > 0, player ship elevates + ; automatically, until this reaches 0 (used when exiting a + ; robot / warbase, for example). +Lfd31_script_coordinate: equ #fd31 ; 2 bytes +Lfd33_title_color: equ #fd33 ; 1 byte. Used only in the title screen to do title color rotation. +Lfd34_n_interrupts_this_came_cycle: equ #fd34 ; 1 byte +Lfd35_minutes: equ #fd35 ; 1 byte +Lfd36_hours: equ #fd36 ; 1 byte +Lfd37_days: equ #fd37 ; 2 bytes +Lfd39_current_in_game_right_hud: equ #fd39 ; 1 byte. Stores which is the info/menu to display in + ; the right hud. +Lfd3a_player1_base_factory_counts: equ #fd3a ; 7 bytes +Lfd41_player1_robot_count: equ #fd41 ; 1 byte +Lfd42_player2_base_factory_counts: equ #fd42 ; 7 bytes +Lfd49_player2_robot_count: equ #fd49 ; 1 byte +Lfd4a_player2_resource_counts: equ #fd4a ; 7 bytes +Lfd51_current_robot_player_or_enemy: equ #fd51 ; 1 byte. Used to indicate if the robot we are + ; working with is controlled by the player or the + ; enemy AI. (0: player, 1: enemy AI). +Lfd52_update_radar_buffer_signal: equ #fd52 ; 1 byte. If this is set to 1, the radar buffer will + ; be updated this cycle. +Lfd53_produce_in_game_sound: equ #fd53 ; 1 byte. When != 0, it will make the game interrupt + ; produce some sound, incrementing once per cycle until + ; reaching 128 or 0, at which point the sound it will stop. +Lfd54_music_channel1_ret_address: equ #fd54 ; 2 bytes +Lfd56_music_channel2_ret_address: equ #fd56 ; 2 bytes +; 24 unused bytes +Lfd70_warbases: equ #fd70 +Lfd84_factories: equ Lfd70_warbases + N_WARBASES * BUILDING_STRUCT_SIZE +Lfdfc_save_game_end: equ #fdfc ; When saving a game, RAM is stored up to here. + + +Lfdfd_interrupt_jp: equ #fdfd ; 1 byte +Lfdfe_interrupt_pointer: equ #fdfe ; 2 bytes +Lfe00_interrupt_vector_table: equ #fe00 ; 257 bytes +Lff01_building_decorations: equ #ff01 ; 56 structs of 3 bytes each: map ptr (2 bytes), type (1 + ; byte) + diff --git a/netherearth-annotated.html b/netherearth-annotated.html new file mode 100644 index 0000000..42d5d85 --- /dev/null +++ b/netherearth-annotated.html @@ -0,0 +1,9864 @@ + +MDL: annotated source code + + + +

Source Code file: netherearth-annotated.asm
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddressPosition in BinarySizeTimingAssembledCode
#0000#0000
; --------------------------------
#0000#0000
;
#0000#0000
; "Nether Earth" by Argus Press Software
#0000#0000
; Disassembled by Santiago Ontañón in 2022
#0000#0000
; 
#0000#0000
; --------------------------------
#0000#0000
;
#0000#0000
; Notes:
#0000#0000
;
#0000#0000
; - All the symbol names and comments in this file are my own interpretation of the original source 
#0000#0000
;   code, they could be wrong. So, take them all with a grain of salt! And if you see any errors, 
#0000#0000
;   please report!
#0000#0000
;
#0000#0000
; - Game binary disassembled using MDL: https://github.com/santiontanon/mdlz80optimizer
#0000#0000
;
#0000#0000
; - I decided to prefix each label by their address, e.g. "La600_start" instead of just "start" as, 
#0000#0000
;   often, the code makes assumptions about these addresses. For example, when it checks if the 
#0000#0000
;   most-significant byte of a pointer if #dc or #fd to know we are out of bounds of a map. By 
#0000#0000
;   making the map label "Ldd00_map", it is at least clear that checking for "#dc" is to see if the 
#0000#0000
;   pointer is lower than #dd00, which is the beginning of the map.
#0000#0000
;
#0000#0000
; - There is some unreachable code (see label Lae29) in the code base, that contains code that is 
#0000#0000
;   probably left-over code.
#0000#0000
; 
#0000#0000
; - There are also two gaps in the zone of RAM designated for variables. So, probably some 
#0000#0000
;   variables were defined, but unused in the final version of the code (search for "unused bytes" 
#0000#0000
;   in this file).
#0000#0000
; 
#0000#0000
; - The music system is very interesting for a 48K Spectrum model:
#0000#0000
;     - Look at "Lc4a7_title_music_loop"
#0000#0000
;     - Basically, when playing music, the game runs a constant loop that iterates over 3 
#0000#0000
;       oscillators that produce sound.
#0000#0000
;     - These oscillators are just 3 loops in the code that make the speaker vibrate with some 
#0000#0000
;       fixed frequencies.
#0000#0000
;     - The interrupt routine has a script that, using self-modifiable code, modifies the
#0000#0000
;       oscillator parameters in the loop.
#0000#0000
;     - So, basically, the loop acts as a sound chip, and the interrupt basically sets its 
#0000#0000
;       parameters, mimicking 3 channel sound.
#0000#0000
;     - Since it's a dedicated loop, nothing can run in parallel with it. So, as soon as the player 
#0000#0000
;       presses any key, music stops.
#0000#0000
;
#0000#0000
; - SFX:
#0000#0000
;     - The game reads from the addresses in the Spectrum ROM and uses them to produce sound. This 
#0000#0000
;       is probably just some random sound (as those values are not a wave, but assembler code), 
#0000#0000
;       but the programmers chose different parts of the ROM that produce slightly different 
#0000#0000
;       sounds when reproduced, which is pretty smart.
#0000#0000
;
#0000#0000
; - Game-play details, not fully documented in the instructions:
#0000#0000
;     - Weapons all fly at the same altitude (10) regardless of the height of the robot.
#0000#0000
;     - Electronics:
#0000#0000
;         - increase the range of weapons by 1 tile (what the manual states being 3 miles).
#0000#0000
;         - they also increase the distance robots can "see" an opponent from 10 to 12 tiles.
#0000#0000
;     - Each player can have at most 24 robots.
#0000#0000
;     - There can only be 5 bullets at a time in the whole game:
#0000#0000
;         - one bullet for the player controlled robot
#0000#0000
;         - two bullets fired by friendly robots
#0000#0000
;         - two bullets fired by enemy robots
#0000#0000
;     - How much damage weapons deal is quite curious:
#0000#0000
;         - The game calculates (60 - (robot height + ground height))/4 as the "base damage".
#0000#0000
;         - Then cannon deals 2x the base damage, missiles 3x, and phasers 4x. (the Spanish 
#0000#0000
;           instruction manual is wrong here, stating that missiles do the same damage as cannon, 
#0000#0000
;           English is correct).
#0000#0000
;         - So, robots that are on high ground receive less damage! Stand on a mountain to make a 
#0000#0000
;           robot more resistant!
#0000#0000
;     - Since a robot can have at most 3 weapons, we have (see the 
#0000#0000
;       Ld7b4_piece_heights data below):
#0000#0000
;         - The maximum height of a robot is: 11 + 6 + 7 + 7 + 7 = 38 (bipod, missiles, phase, 
#0000#0000
;           nuclear, electronics). This is the most resistant robot!
#0000#0000
;         - The minimum height of a robot is: 7 + 6 = 13 (tracks, cannon). This is the weakest 
#0000#0000
;           robot!
#0000#0000
;     - So, for example: phasers against the weakest robot (at ground level) deal: ((60 - 13)/4)*4 
#0000#0000
;       = 44 damage.
#0000#0000
;     - The robot/enemy AI is extremely simple:
#0000#0000
;         - see "Lb154_robot_ai_update" for the code that implements the AI of the robots, 
#0000#0000
;           including their limited "path-finding", and targetting.
#0000#0000
;         - see "Lb7f4_update_enemy_ai" for the code that implements the strategy of the enemy 
#0000#0000
;           player.
#0000#0000
; 
#0000#0000
; - Terminology:
#0000#0000
;     - I often use the abbreviation "ptr." for "pointer".
#0000#0000
;     - I often use the term "one-hot" (vector/byte). This is a way to represent numbers, where 
#0000#0000
;       only one bit of the byte is set to 1, and the others are zero. The number encoded is the
#0000#0000
;       index of the bit that is set to 1. For example:
#0000#0000
;         - 1 encoded as a one-hot vector is: 00000001
#0000#0000
;         - 2 encoded as a one-hot vector is: 00000010
#0000#0000
;         - 3 encoded as a one-hot vector is: 00000100
#0000#0000
;         - 4 encoded as a one-hot vector is: 00001000
#0000#0000
;         - etc.
#0000#0000
;
#0000#0000
; --------------------------------
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; BIOS Functions and constants:
#0000#0000
; - Information obtained from:
#0000#0000
;   https://worldofspectrum.net/pub/sinclair/books/s/SpectrumMachineCodeReferenceGuideThe.pdf
#0000#0000
L0205_BIOS_KEYCODE_TABLE: equ #0205
#0000#0000
L028e_BIOS_POLL_KEYBOARD: equ #028e  ; Polls keyboard and builds up key code in DE
#0000#0000
L0556_BIOS_READ_FROM_TAPE: equ #0556  ; Load if carry set, load tape header if A=0 (nz=data). 
#0000#0000
                                      ; IX=address, DE=byte count
#0000#0000
L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS: equ #0562
#0000#0000
L04c2_BIOS_CASSETTE_SAVE: equ #04c2
#0000#0000
L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS: equ #04d0
#0000#0000
#0000#0000
L4000_VIDEOMEM_PATTERNS: equ #4000
#0000#0000
L5800_VIDEOMEM_ATTRIBUTES: equ #5800
#0000#0000
#0000#0000
ULA_PORT: equ #fe
#0000#0000
KEMPSTON_JOYSTICK_PORT: equ 31
#0000#0000
INTERFACE2_JOYSTICK_PORT_MSB: equ #ef
#0000#0000
#0000#0000
COLOR_BRIGHT: equ #40
#0000#0000
COLOR_BLACK: equ 0
#0000#0000
COLOR_BLUE: equ 1
#0000#0000
COLOR_RED: equ 2
#0000#0000
COLOR_PINK: equ 3
#0000#0000
COLOR_GREEN: equ 4
#0000#0000
COLOR_CYAN: equ 5
#0000#0000
COLOR_YELLOW: equ 6
#0000#0000
COLOR_WHITE: equ 7
#0000#0000
PAPER_COLOR_MULTIPLIER: equ 8
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; Commands recognized by Ld42d_execute_ui_script:
#0000#0000
CMD_END: equ 0
#0000#0000
CMD_SET_POSITION: equ 1
#0000#0000
CMD_SET_ATTRIBUTE: equ 2
#0000#0000
CMD_NEXT_LINE: equ 3
#0000#0000
CMD_SET_SCALE: equ 4
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
INPUT_KEYBOARD: equ 1
#0000#0000
INPUT_KEMPSTON: equ 2
#0000#0000
INPUT_INTERFACE2: equ 3
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; Game constants:
#0000#0000
INITIAL_PLAYER_RESOURCES: equ 20
#0000#0000
MAX_ROBOTS_PER_PLAYER: equ 24
#0000#0000
MAX_BULLETS: equ 5
#0000#0000
N_WARBASES: equ 4
#0000#0000
N_FACTORIES: equ 24
#0000#0000
BUILDING_CAPTURE_TIME: equ 144
#0000#0000
MIN_INTERRUPTS_PER_GAME_CYCLE: equ 10  ; game maximum speed is 5 frames per second.
#0000#0000
#0000#0000
MAX_PLAYER_ALTITUDE: equ 48
#0000#0000
MIN_PLAYER_X: equ 14
#0000#0000
MAX_PLAYER_X: equ 501
#0000#0000
#0000#0000
MAP_LENGTH: equ 512  ; x coordinate
#0000#0000
MAP_WIDTH: equ 16  ; y coordinate
#0000#0000
#0000#0000
ROBOT_ORDERS_STOP_AND_DEFEND: equ 0
#0000#0000
ROBOT_ORDERS_ADVANCE: equ 1
#0000#0000
ROBOT_ORDERS_RETREAT: equ 2
#0000#0000
ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS: equ 3
#0000#0000
ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES: equ 4
#0000#0000
ROBOT_ORDERS_DESTROY_ENEMY_WARBASES: equ 5
#0000#0000
ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES: equ 6
#0000#0000
ROBOT_ORDERS_CAPTURE_ENEMY_FACTORIES: equ 7
#0000#0000
ROBOT_ORDERS_CAPTURE_ENEMY_WARBASES: equ 8
#0000#0000
#0000#0000
ROBOT_CONTROL_AUTO: equ 0
#0000#0000
ROBOT_CONTROL_PLAYER_LANDED: equ 1
#0000#0000
ROBOT_CONTROL_DIRECT_CONTROL: equ 2
#0000#0000
ROBOT_CONTROL_ENEMY_AI: equ 128
#0000#0000
#0000#0000
WEAPON_RANGE_DEFAULT: equ 5
#0000#0000
WEAPON_RANGE_MISSILES: equ 7
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; Game structs:
#0000#0000
ROBOT_STRUCT_SIZE: equ 16
#0000#0000
ROBOT_STRUCT_MAP_PTR: equ 0  ; 2 bytes (the first byte set to 0 when there is no robot in this 
#0000#0000
                             ; struct).
#0000#0000
ROBOT_STRUCT_X: equ 2  ; 2 bytes
#0000#0000
ROBOT_STRUCT_Y: equ 4
#0000#0000
ROBOT_STRUCT_DESIRED_MOVE_DIRECTION: equ 5
#0000#0000
ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING: equ 6
#0000#0000
ROBOT_STRUCT_PIECES: equ 7
#0000#0000
ROBOT_STRUCT_DIRECTION: equ 8  ; one-hot representation: #01, #02, #04, #08
#0000#0000
ROBOT_STRUCT_HEIGHT: equ 9
#0000#0000
ROBOT_STRUCT_CONTROL: equ 10
#0000#0000
ROBOT_STRUCT_ORDERS: equ 11
#0000#0000
ROBOT_STRUCT_STRENGTH: equ 12
#0000#0000
ROBOT_STRUCT_ALTITUDE: equ 13
#0000#0000
ROBOT_STRUCT_ORDERS_ARGUMENT: equ 14  ; This can be # of miles, target robot index, etc.
#0000#0000
ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE: equ 15
#0000#0000
#0000#0000
#0000#0000
BULLET_STRUCT_SIZE: equ 9
#0000#0000
BULLET_STRUCT_MAP_PTR: equ 0  ; 2 bytes (the first byte set to 0 when there is no bullet in this 
#0000#0000
                              ; struct).
#0000#0000
BULLET_STRUCT_X: equ 2  ; 2 bytes
#0000#0000
BULLET_STRUCT_Y: equ 4
#0000#0000
BULLET_STRUCT_DIRECTION: equ 5
#0000#0000
BULLET_STRUCT_RANGE: equ 6
#0000#0000
BULLET_STRUCT_TYPE: equ 7  ; 1: cannon, 2: missiles, 3: phasers
#0000#0000
BULLET_STRUCT_ALTITUDE: equ 8
#0000#0000
#0000#0000
#0000#0000
BUILDING_STRUCT_SIZE: equ 5
#0000#0000
BUILDING_STRUCT_X: equ 0  ; 2 bytes
#0000#0000
BUILDING_STRUCT_Y: equ 2
#0000#0000
BUILDING_STRUCT_TYPE: equ 3  ; contains type + owner (owner in the most-significant bits: bit 6 
#0000#0000
                             ; player 1, bit 5 player 2). bit 7 indicates building is destroyed.
#0000#0000
BUILDING_STRUCT_TIMER: equ 4  ; this counts the time the building is occupied by a robot
#0000#0000
#0000#0000
#0000#0000
BUILDING_DECORATION_STRUCT_SIZE: equ 3
#0000#0000
BUILDING_DECORATION_STRUCT_MAP_PTR: equ 0
#0000#0000
BUILDING_DECORATION_STRUCT_TYPE: equ 2
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; RAM variables/buffers in the low region of RAM:
#0000#0000
; The first 3200 bytes (starting at #5b00) are used as a double buffer, to render
#0000#0000
; the screen there, before it is copied over to the video memory. 3200 bytes, as
#0000#0000
; the game area is 160x160 pixels wide. So, 160/8 = 20 bytes per line, and 20*160 = 3200.
#0000#0000
L5b00: equ #5b00
#0000#0000
L5b00_double_buffer: equ #5b00
#0000#0000
#0000#0000
#0000#0000
; --------------------------------
#0000#0000
; Game graphic data"
#0000#0000
    org #6780
#6780#0000
#678015850
    include "netherearth-annotated-data.asm"
#a56a#3dea150
    ds #a600 - $, 0  ; 150 bytes of empty space until the game code starts.
#a600#3e80
#a600#3e80
#a600#3e80
; --------------------------------
#a600#3e80
; Game entry point    
#a600#3e80
La600_start:
#a600#3e80
    ; Set up the interrupts:
#a600#3e8015
f3 
    di
#a601#3e81311
31 00 00 
        ld sp, 0
#a604#3e84311
21 00 fe 
        ld hl, Lfe00_interrupt_vector_table
#a607#3e87311
01 fd 00 
        ld bc, #00fd
#a60a#3e8a
        ; Write #fd to the interrupt vector table 257 times
#a60a#3e8a
La60a_interrupt_vector_table_init_loop:
#a60a#3e8a18
71 
        ld (hl), c
#a60b#3e8b17
23 
        inc hl
#a60c#3e8c214/9
10 fc 
        djnz La60a_interrupt_vector_table_init_loop
#a60e#3e8e18
71 
        ld (hl), c
#a60f#3e8f28
3e c3 
        ld a, #c3  ; jp opcode
#a611#3e91314
32 fd fd 
        ld (Lfdfd_interrupt_jp), a
#a614#3e94311
21 9c d5 
        ld hl, Ld59c_empty_interrupt
#a617#3e97317
22 fe fd 
        ld (Lfdfe_interrupt_pointer), hl  ; sets the interrupt routine
#a61a#3e9a28
3e fe 
        ld a, #fe
#a61c#3e9c211
ed 47 
        ld i, a  ; sets the interrupt vector tp #fe00
#a61e#3e9e210
ed 5e 
        im 2
#a620#3ea015
fb 
    ei
#a621#3ea1
#a621#3ea1
    ; Initialize the random number generator:
#a621#3ea1311
21 39 30 
    ld hl, 12345  ; random seed
#a624#3ea4317
22 00 fd 
    ld (Lfd00_random_seed), hl
#a627#3ea7317
22 02 fd 
    ld (Lfd00_random_seed + 2), hl
#a62a#3eaa318
cd 00 c1 
    call Lc100_title_screen
#a62d#3ead213/8
20 5f 
    jr nz, La68e_game_loop_start  ; Start from a saved game
#a62f#3eaf
#a62f#3eaf
    ; Start new game from scratch:
#a62f#3eaf
    ; Clear memory buffers:
#a62f#3eaf311
21 00 da 
    ld hl, Lda00_player1_robots
#a632#3eb2311
11 01 da 
    ld de, Lda00_player1_robots + 1
#a635#3eb5311
01 ff 02 
    ld bc, 2 * MAX_ROBOTS_PER_PLAYER * ROBOT_STRUCT_SIZE - 1
#a638#3eb8211
36 00 
    ld (hl), 0
#a63a#3eba223/18
ed b0 
    ldir
#a63c#3ebc311
21 04 fd 
    ld hl, Lfd04_script_video_pattern_ptr
#a63f#3ebf311
11 05 fd 
    ld de, Lfd04_script_video_pattern_ptr + 1
#a642#3ec2311
01 f8 00 
    ld bc, 248
#a645#3ec5211
36 00 
    ld (hl), 0
#a647#3ec7223/18
ed b0 
    ldir  ; This clears a whole set of in-game variables starting at Lfd04_script_video_pattern_ptr
#a649#3ec9311
21 01 ff 
    ld hl, Lff01_building_decorations
#a64c#3ecc311
11 02 ff 
    ld de, Lff01_building_decorations + 1
#a64f#3ecf311
01 c8 00 
    ld bc, 200  ; Potential optimization: change to 167 since only 168 bytes need to be cleared 
#a652#3ed2
                ; here.
#a652#3ed2211
36 00 
    ld (hl), 0
#a654#3ed4223/18
ed b0 
    ldir
#a656#3ed6311
21 d3 d7 
    ld hl, Ld7d3_bullets
#a659#3ed9311
11 d4 d7 
    ld de, Ld7d3_bullets + 1
#a65c#3edc311
01 2c 00 
    ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE - 1
#a65f#3edf211
36 00 
    ld (hl), 0
#a661#3ee1223/18
ed b0 
    ldir
#a663#3ee3
#a663#3ee3
    ; Initialize variables:
#a663#3ee3311
21 00 dd 
    ld hl, Ldd00_map
#a666#3ee6317
22 06 fd 
    ld (Lfd06_scroll_ptr), hl
#a669#3ee9311
21 00 00 
    ld hl, 0
#a66c#3eec317
22 0a fd 
    ld (Lfd0a_scroll_x), hl
#a66f#3eef311
21 11 00 
    ld hl, 17
#a672#3ef2317
22 0e fd 
    ld (Lfd0e_player_x), hl  ; set player start x
#a675#3ef528
3e 0a 
    ld a, 10
#a677#3ef7314
32 0d fd 
    ld (Lfd0d_player_y), a  ; set player start y
#a67a#3efa15
af 
    xor a
#a67b#3efb314
32 10 fd 
    ld (Lfd10_player_altitude), a  ; set player start altitude
#a67e#3efe28
3e 03 
    ld a, 3
#a680#3f00314
32 30 fd 
    ld (Lfd30_player_elevate_timer), a  ; make the player float a bit right at game start
#a683#3f0328
3e 14 
    ld a, INITIAL_PLAYER_RESOURCES
#a685#3f05314
32 22 fd 
    ld (Lfd22_player1_resource_counts), a
#a688#3f08314
32 4a fd 
    ld (Lfd4a_player2_resource_counts), a
#a68b#3f0b318
cd 6f bc 
    call Lbc6f_initialize_map
#a68e#3f0e
#a68e#3f0e
#a68e#3f0e
; --------------------------------
#a68e#3f0e
; This is the main game loop:
#a68e#3f0e
La68e_game_loop_start:
#a68e#3f0e318
cd d7 cf 
    call Lcfd7_draw_blank_map_in_buffer
#a691#3f11318
cd ca d0 
    call Ld0ca_draw_in_game_screen_and_hud
#a694#3f14311
21 66 d5 
    ld hl, Ld566_interrupt
#a697#3f17317
22 fe fd 
    ld (Lfdfe_interrupt_pointer), hl
#a69a#3f1a
La69a_game_loop:
#a69a#3f1a318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#a69d#3f1d318
cd 11 af 
    call Laf11_player_ship_keyboard_control
#a6a0#3f20318
cd ca b0 
    call Lb0ca_update_robots_bullets_and_ai
#a6a3#3f23318
cd bd cc 
    call Lccbd_redraw_game_area
#a6a6#3f26318
cd 62 ad 
    call Lad62_increase_time
#a6a9#3f29318
cd a0 cc 
    call Lcca0_compute_player_map_ptr
#a6ac#3f2c214
cb 76 
    bit 6, (hl)
#a6ae#3f2e213/8
28 5d 
    jr z, La70d_game_loop_continue
#a6b0#3f30318
cd d8 cd 
    call Lcdd8_get_robot_at_ptr
#a6b3#3f33213/8
20 13 
    jr nz, La6c8_not_landed_on_a_robot
#a6b5#3f3515
78 
    ld a, b
#a6b6#3f3628
fe 19 
    cp MAX_ROBOTS_PER_PLAYER + 1  ; if it's not one of the player's robots, ignore
#a6b8#3f38213/8
38 53 
    jr c, La70d_game_loop_continue
#a6ba#3f3a314
3a 10 fd 
    ld a, (Lfd10_player_altitude)
#a6bd#3f3d321
fd 96 09 
    sub (iy + ROBOT_STRUCT_HEIGHT)
#a6c0#3f40321
fd 96 0d 
    sub (iy + ROBOT_STRUCT_ALTITUDE)
#a6c3#3f43318/11
cc 20 a7 
    call z, La720_land_on_robot  ; if we are right on top of the robot, control it!
#a6c6#3f46213
18 45 
    jr La70d_game_loop_continue
#a6c8#3f48
#a6c8#3f48
La6c8_not_landed_on_a_robot:
#a6c8#3f48318
cd f5 cd 
    call Lcdf5_find_building_decoration_with_ptr
#a6cb#3f4b213/8
20 40 
    jr nz, La70d_game_loop_continue  ; player is not on top of any ownable building
#a6cd#3f4d321
fd 7e 02 
    ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE)
#a6d0#3f5015
b7 
    or a
#a6d1#3f51213/8
20 3a 
    jr nz, La70d_game_loop_continue  ; player is not on top of an "H" decoration
#a6d3#3f53314
3a 10 fd 
    ld a, (Lfd10_player_altitude)
#a6d6#3f5628
fe 0f 
    cp 15
#a6d8#3f58213/8
20 33 
    jr nz, La70d_game_loop_continue  ; player is not at the right height
#a6da#3f5a321
fd 6e 00 
    ld l, (iy + BUILDING_DECORATION_STRUCT_MAP_PTR)
#a6dd#3f5d321
fd 7e 01 
    ld a, (iy + BUILDING_DECORATION_STRUCT_MAP_PTR + 1)
#a6e0#3f6028
c6 08 
    add a, 8
#a6e2#3f6215
67 
    ld h, a
#a6e3#3f63
    ; check for bit 6 in a 2x2 rectangle around the building map ptr, this is to
#a6e3#3f63
    ; make sure the building is still there and not destroyed:
#a6e3#3f6318
7e 
    ld a, (hl)
#a6e4#3f6415
24 
    inc h
#a6e5#3f6515
24 
    inc h
#a6e6#3f6618
b6 
    or (hl)
#a6e7#3f6717
2b 
    dec hl
#a6e8#3f6818
b6 
    or (hl)
#a6e9#3f6917
23 
    inc hl
#a6ea#3f6a17
23 
    inc hl
#a6eb#3f6b18
b6 
    or (hl)
#a6ec#3f6c28
e6 40 
    and #40
#a6ee#3f6e213/8
20 1d 
    jr nz, La70d_game_loop_continue  ; not landed on a warbase
#a6f0#3f70318
cd 49 c8 
    call Lc849_robot_construction_if_possible
#a6f3#3f73
    ; Reset state of newly created robot:
#a6f3#3f73421
fd 36 05 04 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 4  ; more down by default
#a6f7#3f77421
fd 36 06 05 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 5  ; walk 5 steps after exiting the 
#a6fb#3f7b
                                                               ; base, and stop
#a6fb#3f7b421
fd 36 0b 00 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND
#a6ff#3f7f421
fd 36 0c 64 
    ld (iy + ROBOT_STRUCT_STRENGTH), 100
#a703#3f83421
fd 36 0f 01 
    ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), 1
#a707#3f87318
cd 40 bb 
    call Lbb40_count_robots
#a70a#3f8a318
cd 93 d2 
    call Ld293_update_stats_in_right_hud
#a70d#3f8d
La70d_game_loop_continue:
#a70d#3f8d314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#a710#3f90210
cb 77 
    bit 6, a  ; restart key
#a712#3f92311
c2 00 a6 
    jp nz, La600_start
#a715#3f95210
cb 6f 
    bit 5, a  ; save game key
#a717#3f97311
ca 9a a6 
    jp z, La69a_game_loop
#a71a#3f9a318
cd 8d c2 
    call Lc28d_save_game
#a71d#3f9d311
c3 8e a6 
    jp La68e_game_loop_start
#a720#3fa0
#a720#3fa0
#a720#3fa0
; --------------------------------
#a720#3fa0
; Player lands on a robot.
#a720#3fa0
; Input:
#a720#3fa0
; - iy: robot player landed on
#a720#3fa0
La720_land_on_robot:
#a720#3fa0217
fd e5 
    push iy
#a722#3fa2216
dd e1 
    pop ix
#a724#3fa4421
dd 36 0a 01 
    ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_PLAYER_LANDED
#a728#3fa828
3e 04 
    ld a, 4
#a72a#3faa314
32 1f fd 
    ld (Lfd1f_cursor_position), a
#a72d#3fad28
3e 01 
    ld a, 1
#a72f#3faf314
32 39 fd 
    ld (Lfd39_current_in_game_right_hud), a
#a732#3fb2
La732_land_on_robot_internal:
#a732#3fb2318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#a735#3fb5318
cd 2d d4 
    call Ld42d_execute_ui_script
#a738#3fb8
    ; script start:
#a738#3fb83
        db CMD_SET_POSITION, #04, #17
#a73b#3fbb2
        db CMD_SET_ATTRIBUTE, #4d
#a73d#3fbd8
        db "DIRECT  "
#a745#3fc51
        db CMD_NEXT_LINE
#a746#3fc68
        db " CONTROL"
#a74e#3fce1
        db CMD_NEXT_LINE
#a74f#3fcf1
        db CMD_NEXT_LINE
#a750#3fd08
        db "GIVE    "
#a758#3fd81
        db CMD_NEXT_LINE
#a759#3fd98
        db "  ORDERS"
#a761#3fe11
        db CMD_NEXT_LINE
#a762#3fe21
        db CMD_NEXT_LINE
#a763#3fe38
        db "COMBAT  "
#a76b#3feb1
        db CMD_NEXT_LINE
#a76c#3fec8
        db "    MODE"
#a774#3ff41
        db CMD_NEXT_LINE
#a775#3ff51
        db CMD_NEXT_LINE
#a776#3ff68
        db "LEAVE   "
#a77e#3ffe1
        db CMD_NEXT_LINE
#a77f#3fff8
        db "   ROBOT"
#a787#40073
        db CMD_SET_POSITION, #11, #17
#a78a#400a2
        db CMD_SET_ATTRIBUTE, #46
#a78c#400c8
        db "-ORDERS-"
#a794#40141
        db CMD_END
#a795#4015
    ; script end:
#a795#4015
    ; Print the robot current orders in the hud:
#a795#4015321
dd 46 0b 
    ld b, (ix + ROBOT_STRUCT_ORDERS)
#a798#401815
04 
    inc b
#a799#4019311
21 2d a8 
    ld hl, La848_possible_robot_order_names - 27
#a79c#401c311
11 1b 00 
    ld de, 27
#a79f#401f
La79f_get_orders_name_loop:
#a79f#401f112
19 
    add hl, de
#a7a0#4020214/9
10 fd 
    djnz La79f_get_orders_name_loop
#a7a2#4022
    ; Copy the current orders to the script below, so we can draw it:
#a7a2#4022311
11 b2 a7 
    ld de, La7b2_current_orders_buffer
#a7a5#4025311
01 1b 00 
    ld bc, 27
#a7a8#4028223/18
ed b0 
    ldir
#a7aa#402a318
cd 2d d4 
    call Ld42d_execute_ui_script
#a7ad#402d
    ; script start:
#a7ad#402d3
        db CMD_SET_POSITION, #12, #17
#a7b0#40302
        db CMD_SET_ATTRIBUTE, #45
#a7b2#4032
La7b2_current_orders_buffer:
#a7b2#403216
        db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00
#a7c2#404211
        db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00
#a7cd#404d
    ; script end:
#a7cd#404d321
dd 7e 0b 
    ld a, (ix + ROBOT_STRUCT_ORDERS)
#a7d0#405015
3d 
    dec a
#a7d1#405128
fe 02 
    cp 2
#a7d3#4053213/8
30 0f 
    jr nc, La7e4_no_miles
#a7d5#4055
    ; If there orders are advance/retreat, display the # of miles:
#a7d5#4055318
cd 2d d4 
    call Ld42d_execute_ui_script
#a7d8#4058
    ; script start:
#a7d8#40583
        db CMD_SET_POSITION, #13, #19
#a7db#405b1
        db CMD_END
#a7dc#405c
    ; script end:
#a7dc#405c321
dd 7e 0e 
    ld a, (ix + ROBOT_STRUCT_ORDERS_ARGUMENT)
#a7df#405f210
cb 3f 
    srl a
#a7e1#4061318
cd e5 d3 
    call Ld3e5_render_8bit_number
#a7e4#4064
La7e4_no_miles:
#a7e4#4064318
cd 1d a8 
    call La81d_draw_robot_strength
#a7e7#4067311
21 37 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0037
#a7ea#406a28
1e 05 
    ld e, 5
#a7ec#406c314
3a 1f fd 
    ld a, (Lfd1f_cursor_position)
#a7ef#406f318
cd d7 ac 
    call Lacd7_right_hud_menu_control
#a7f2#4072314
32 1f fd 
    ld (Lfd1f_cursor_position), a
#a7f5#407515
3d 
    dec a
#a7f6#4076311
ca 3b a9 
    jp z, La93b_direct_control
#a7f9#407915
3d 
    dec a
#a7fa#407a311
ca 71 a9 
    jp z, La971_give_orders
#a7fd#407d15
3d 
    dec a
#a7fe#407e311
ca 00 ac 
    jp z, Lac00_combat_mode
#a801#408128
3e 78 
    ld a, 120
#a803#4083318
cd ac cc 
    call Lccac_beep
#a806#408615
af 
    xor a
#a807#4087321
dd 77 06 
    ld (ix + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a
#a80a#408a321
dd 77 0a 
    ld (ix + ROBOT_STRUCT_CONTROL), a  ; robot controls itself again
#a80d#408d28
3e 05 
    ld a, 5
#a80f#408f314
32 30 fd 
    ld (Lfd30_player_elevate_timer), a  ; make the player float a bit after exiting a robot
#a812#4092
La812_exit_robot:
#a812#4092318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud  ; potential optimization: this line is not needed
#a815#409515
af 
    xor a
#a816#4096314
32 39 fd 
    ld (Lfd39_current_in_game_right_hud), a
#a819#4099318
cd e5 d1 
    call Ld1e5_draw_in_game_right_hud  ; potential optimization: tail recursion
#a81c#409c111
c9 
    ret
#a81d#409d
#a81d#409d
#a81d#409d
; --------------------------------
#a81d#409d
; Draws the remaining strength (hit points) of a robot.
#a81d#409d
La81d_draw_robot_strength:
#a81d#409d318
cd 2d d4 
    call Ld42d_execute_ui_script
#a820#40a0
    ; script start:
#a820#40a03
        db CMD_SET_POSITION, #16, #17
#a823#40a32
        db CMD_SET_ATTRIBUTE, #46
#a825#40a58
        db "STRENGTH"
#a82d#40ad3
        db CMD_SET_POSITION, #17, #19
#a830#40b02
        db CMD_SET_ATTRIBUTE, #47
#a832#40b21
        db CMD_END
#a833#40b3
    ; script end:
#a833#40b3321
dd 7e 0c 
    ld a, (ix + ROBOT_STRUCT_STRENGTH)
#a836#40b615
b7 
    or a
#a837#40b7311
f2 3b a8 
    jp p, La83b_positive_strength
#a83a#40ba15
af 
    xor a
#a83b#40bb
La83b_positive_strength:
#a83b#40bb15
6f 
    ld l, a
#a83c#40bc28
26 00 
    ld h, 0
#a83e#40be28
1e 20 
    ld e, " "
#a840#40c0318
cd 01 d4 
    call Ld401_render_16bit_number_3digits
#a843#40c328
3e 25 
    ld a, "%"
#a845#40c5311
c3 27 d4 
    jp Ld427_draw_character_saving_registers
#a848#40c8
#a848#40c8
#a848#40c8
; --------------------------------
#a848#40c8
La848_possible_robot_order_names:
#a848#40c88
    db "  STOP  "
#a850#40d01
    db CMD_NEXT_LINE
#a851#40d18
    db "  AND   "
#a859#40d91
    db CMD_NEXT_LINE
#a85a#40da8
    db " DEFEND "
#a862#40e21
    db CMD_END
#a863#40e3
#a863#40e38
    db "ADVANCE "
#a86b#40eb1
    db CMD_NEXT_LINE
#a86c#40ec8
    db "        "
#a874#40f41
    db CMD_NEXT_LINE
#a875#40f58
    db " MILES  "
#a87d#40fd1
    db CMD_END
#a87e#40fe
#a87e#40fe8
    db "RETREAT "
#a886#41061
    db CMD_NEXT_LINE
#a887#41078
    db "        "
#a88f#410f1
    db CMD_NEXT_LINE
#a890#41108
    db " MILES  "
#a898#41181
    db CMD_END
#a899#4119
#a899#41198
    db "DESTROY "
#a8a1#41211
    db CMD_NEXT_LINE
#a8a2#41228
    db " ENEMY  "
#a8aa#412a1
    db CMD_NEXT_LINE
#a8ab#412b8
    db " ROBOTS "
#a8b3#41331
    db CMD_END
#a8b4#4134
    
#a8b4#41348
    db "DESTROY "
#a8bc#413c1
    db CMD_NEXT_LINE
#a8bd#413d8
    db " ENEMY  "
#a8c5#41451
    db CMD_NEXT_LINE
#a8c6#41468
    db "FACTORYS"
#a8ce#414e1
    db CMD_END
#a8cf#414f
    
#a8cf#414f8
    db "DESTROY "
#a8d7#41571
    db CMD_NEXT_LINE
#a8d8#41588
    db " ENEMY  "
#a8e0#41601
    db CMD_NEXT_LINE
#a8e1#41618
    db "WARBASES"
#a8e9#41691
    db CMD_END
#a8ea#416a
    
#a8ea#416a8
    db "CAPTURE "
#a8f2#41721
    db CMD_NEXT_LINE
#a8f3#41738
    db "NEUTRAL "
#a8fb#417b1
    db CMD_NEXT_LINE
#a8fc#417c8
    db "FACTORYS"
#a904#41841
    db CMD_END
#a905#4185
    
#a905#41858
    db "CAPTURE "
#a90d#418d1
    db CMD_NEXT_LINE
#a90e#418e8
    db " ENEMY  "
#a916#41961
    db CMD_NEXT_LINE
#a917#41978
    db "FACTORYS"
#a91f#419f1
    db CMD_END
#a920#41a0
    
#a920#41a08
    db "CAPTURE "
#a928#41a81
    db CMD_NEXT_LINE
#a929#41a98
    db " ENEMY  "
#a931#41b11
    db CMD_NEXT_LINE
#a932#41b28
    db "WARBASES"
#a93a#41ba1
    db CMD_END
#a93b#41bb
#a93b#41bb
#a93b#41bb
; --------------------------------
#a93b#41bb
; Jumps to the direct-control interface, and goes back to the "land on robot" menu after that.
#a93b#41bb
La93b_direct_control:
#a93b#41bb318
cd 41 a9 
    call La941_direct_control_internal
#a93e#41be311
c3 32 a7 
    jp La732_land_on_robot_internal
#a941#41c1
#a941#41c1
#a941#41c1
; --------------------------------
#a941#41c1
; Direct control of a robot.
#a941#41c1
La941_direct_control_internal:
#a941#41c1421
dd 36 0a 02 
    ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_DIRECT_CONTROL
#a945#41c5421
dd 36 05 00 
    ld (ix + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 0  ; stop the automatic movement of the robot
#a949#41c9318
cd 57 ad 
    call Lad57_wait_until_no_keys_pressed
#a94c#41cc
La94c_direct_control_loop:
#a94c#41cc318
cd ca b0 
    call Lb0ca_update_robots_bullets_and_ai
#a94f#41cf318
cd bd cc 
    call Lccbd_redraw_game_area
#a952#41d2318
cd 48 b0 
    call Lb048_update_radar
#a955#41d5318
cd 62 ad 
    call Lad62_increase_time
#a958#41d8318
cd 1d a8 
    call La81d_draw_robot_strength
#a95b#41db321
dd 7e 01 
    ld a, (ix + 1)
#a95e#41de15
b7 
    or a
#a95f#41df112/6
c8 
    ret z  ; If the robot is destroyed, exit.
#a960#41e0318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#a963#41e328
e6 10 
    and 16  ; If we press "fire", exit
#a965#41e5213/8
28 e5 
    jr z, La94c_direct_control_loop
#a967#41e7421
dd 36 0a 01 
    ld (ix + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_PLAYER_LANDED
#a96b#41eb28
3e 78 
    ld a, 120
#a96d#41ed318
cd ac cc 
    call Lccac_beep
#a970#41f0111
c9 
    ret
#a971#41f1
#a971#41f1
#a971#41f1
; --------------------------------
#a971#41f1
; This function implements the menu to give new orders to a robot.
#a971#41f1
La971_give_orders:
#a971#41f1318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#a974#41f4318
cd 2d d4 
    call Ld42d_execute_ui_script
#a977#41f7
    ; script start:
#a977#41f73
        db CMD_SET_POSITION, #04, #18
#a97a#41fa2
        db CMD_SET_ATTRIBUTE, #47
#a97c#41fc6
        db "SELECT"
#a982#42021
        db CMD_NEXT_LINE
#a983#42036
        db "ORDERS"
#a989#42092
        db CMD_SET_ATTRIBUTE, #4d
#a98b#420b3
        db CMD_SET_POSITION, #07, #17
#a98e#420e8
        db "STOP AND"
#a996#42161
        db CMD_NEXT_LINE
#a997#42178
        db "  DEFEND"
#a99f#421f1
        db CMD_NEXT_LINE
#a9a0#42201
        db CMD_NEXT_LINE
#a9a1#42218
        db "ADVANCE "
#a9a9#42291
        db CMD_NEXT_LINE
#a9aa#422a8
        db "?? MILES"
#a9b2#42321
        db CMD_NEXT_LINE
#a9b3#42331
        db CMD_NEXT_LINE
#a9b4#42348
        db "RETREAT "
#a9bc#423c1
        db CMD_NEXT_LINE
#a9bd#423d8
        db "?? MILES"
#a9c5#42451
        db CMD_NEXT_LINE
#a9c6#42461
        db CMD_NEXT_LINE
#a9c7#42478
        db "SEARCH &"
#a9cf#424f1
        db CMD_NEXT_LINE
#a9d0#42508
        db " DESTROY"
#a9d8#42581
        db CMD_NEXT_LINE
#a9d9#42591
        db CMD_NEXT_LINE
#a9da#425a8
        db "SEARCH &"
#a9e2#42621
        db CMD_NEXT_LINE
#a9e3#42638
        db " CAPTURE"
#a9eb#426b1
        db CMD_END
#a9ec#426c
    ; script end:
#a9ec#426c318
cd 1d a8 
    call La81d_draw_robot_strength
#a9ef#426f311
21 97 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0097  ; ptr to the start of the menu attributes
#a9f2#427228
1e 06 
    ld e, 6  ; this menu has 5 options
#a9f4#427428
3e 01 
    ld a, 1  ; we start in option 1
#a9f6#4276318
cd d7 ac 
    call Lacd7_right_hud_menu_control
#a9f9#4279112
f5 
    push af
#a9fa#427a318
cd 57 ad 
        call Lad57_wait_until_no_keys_pressed
#a9fd#427d111
f1 
    pop af
#a9fe#427e15
3d 
    dec a
#a9ff#427f213/8
20 0b 
    jr nz, Laa0c_no_stop_and_defend
#aa01#4281321
dd 77 0b 
    ld (ix + ROBOT_STRUCT_ORDERS), a  ; stop and defend
#aa04#428428
3e 78 
    ld a, 120
#aa06#4286318
cd ac cc 
    call Lccac_beep
#aa09#4289311
c3 32 a7 
    jp La732_land_on_robot_internal
#aa0c#428c
Laa0c_no_stop_and_defend:
#aa0c#428c28
fe 03 
    cp 3
#aa0e#428e311
d2 cf aa 
    jp nc, Laacf_give_capture_or_destroy_orders
#aa11#4291
    ; We have selected advance or retreat:
#aa11#4291321
dd 77 0b 
    ld (ix + ROBOT_STRUCT_ORDERS), a
#aa14#4294112
f5 
    push af
#aa15#4295318
cd f6 d2 
        call Ld2f6_clear_in_game_right_hud
#aa18#4298111
f1 
    pop af
#aa19#429915
3d 
    dec a
#aa1a#429a213/8
20 13 
    jr nz, Laa2f_retreat
#aa1c#429c318
cd 2d d4 
    call Ld42d_execute_ui_script
#aa1f#429f
    ; Script start:
#aa1f#429f3
        db CMD_SET_POSITION, #05, #17
#aa22#42a22
        db CMD_SET_ATTRIBUTE, #4f
#aa24#42a48
        db "ADVANCE "
#aa2c#42ac1
        db CMD_END
#aa2d#42ad
    ; Script end:
#aa2d#42ad213
18 11 
    jr Laa40_advance_or_retreat_drawn
#aa2f#42af
Laa2f_retreat:
#aa2f#42af318
cd 2d d4 
    call Ld42d_execute_ui_script
#aa32#42b2
    ; Script start:
#aa32#42b23
        db CMD_SET_POSITION, #05, #17
#aa35#42b52
        db CMD_SET_ATTRIBUTE, #4f
#aa37#42b78
        db "RETREAT "
#aa3f#42bf1
        db CMD_END
#aa40#42c0
    ; Script end:
#aa40#42c0
Laa40_advance_or_retreat_drawn:
#aa40#42c0318
cd 2d d4 
    call Ld42d_execute_ui_script
#aa43#42c3
    ; Script start:
#aa43#42c31
        db CMD_NEXT_LINE
#aa44#42c48
        db "?? MILES"
#aa4c#42cc3
        db CMD_SET_POSITION, #09, #17
#aa4f#42cf2
        db CMD_SET_ATTRIBUTE, #45
#aa51#42d17
        db " SELECT"
#aa58#42d81
        db CMD_NEXT_LINE
#aa59#42d98
        db "DISTANCE"
#aa61#42e13
        db CMD_SET_POSITION, #0d, #18
#aa64#42e42
        db CMD_SET_ATTRIBUTE, #46
#aa66#42e67
        db "0 MILES"
#aa6d#42ed1
        db CMD_END
#aa6e#42ee
    ; Script end:
#aa6e#42ee28
16 00 
    ld d, 0  ; 0 miles to start
#aa70#42f0
Laa70_select_miles_loop:
#aa70#42f0112
d5 
    push de
#aa71#42f1318
cd 1d a8 
        call La81d_draw_robot_strength
#aa74#42f4318
cd ca b0 
        call Lb0ca_update_robots_bullets_and_ai
#aa77#42f7318
cd bd cc 
        call Lccbd_redraw_game_area
#aa7a#42fa318
cd 48 b0 
        call Lb048_update_radar
#aa7d#42fd318
cd 62 ad 
        call Lad62_increase_time
#aa80#4300111
d1 
    pop de
#aa81#4301321
dd 7e 01 
    ld a, (ix + 1)
#aa84#430415
b7 
    or a  ; If robot is destroyed, exit.
#aa85#4305311
ca 12 a8 
    jp z, La812_exit_robot
#aa88#4308318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#aa8b#430b210
cb 67 
    bit 4, a
#aa8d#430d213/8
20 29 
    jr nz, Laab8_miles_selected  ; If fire pressed
#aa8f#430f15
4a 
    ld c, d
#aa90#431015
0f 
    rrca
#aa91#431115
0f 
    rrca
#aa92#431228
e6 03 
    and 3
#aa94#4314213/8
28 da 
    jr z, Laa70_select_miles_loop  ; if we have not pressed up/down
#aa96#431628
e6 02 
    and 2
#aa98#431815
47 
    ld b, a
#aa99#431915
87 
    add a, a
#aa9a#431a15
87 
    add a, a
#aa9b#431b15
80 
    add a, b
#aa9c#431c28
d6 05 
    sub 5  ; If we have pressed up, a = 5, otherwise, a = -5
#aa9e#431e15
81 
    add a, c  ; c was storing the # of miles
#aa9f#431f28
fe 33 
    cp 51
#aaa1#4321213/8
30 cd 
    jr nc, Laa70_select_miles_loop  ; Limit miles to 50
#aaa3#432315
57 
    ld d, a  ; update the # miles
#aaa4#4324318
cd 2d d4 
    call Ld42d_execute_ui_script
#aaa7#4327
    ; Script start:
#aaa7#43273
        db CMD_SET_POSITION, #0d, #17
#aaaa#432a2
        db CMD_SET_ATTRIBUTE, #46
#aaac#432c1
        db CMD_END
#aaad#432d
    ; Script end
#aaad#432d15
7a 
    ld a, d
#aaae#432e318
cd e5 d3 
    call Ld3e5_render_8bit_number
#aab1#433128
3e 14 
    ld a, 20
#aab3#4333318
cd ac cc 
    call Lccac_beep
#aab6#4336213
18 b8 
    jr Laa70_select_miles_loop
#aab8#4338
#aab8#4338
Laab8_miles_selected:
#aab8#433815
7a 
    ld a, d
#aab9#433915
07 
    rlca  ; multiply by 2: 1 mile == 2 coordinate units
#aaba#433a321
dd 77 0e 
    ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), a  ; set the number of miles to advance
#aabd#433d15
b7 
    or a
#aabe#433e213/8
20 04 
    jr nz, Laac4  ; "advance/retreat 0 miles" is equivalent to stop and defend.
#aac0#4340421
dd 36 0b 00 
    ld (ix + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND
#aac4#4344
Laac4:
#aac4#434428
3e 78 
    ld a, 120
#aac6#4346318
cd ac cc 
    call Lccac_beep
#aac9#4349318
cd 57 ad 
    call Lad57_wait_until_no_keys_pressed
#aacc#434c311
c3 32 a7 
    jp La732_land_on_robot_internal
#aacf#434f
#aacf#434f
Laacf_give_capture_or_destroy_orders:
#aacf#434f311
c2 4e ab 
    jp nz, Lab4e_give_capture_orders
#aad2#4352
    ; Destroy:
#aad2#4352318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#aad5#4355318
cd 2d d4 
    call Ld42d_execute_ui_script
#aad8#4358
    ; Script start:
#aad8#43583
        db CMD_SET_POSITION, #04, #17
#aadb#435b2
        db CMD_SET_ATTRIBUTE, #4f
#aadd#435d8
        db "SEARCH &"
#aae5#43651
        db CMD_NEXT_LINE
#aae6#43668
        db " DESTROY"
#aaee#436e3
        db CMD_SET_POSITION, #08, #18
#aaf1#43712
        db CMD_SET_ATTRIBUTE, #45
#aaf3#43736
        db "SELECT"
#aaf9#43791
        db CMD_NEXT_LINE
#aafa#437a6
        db "TARGET"
#ab00#43803
        db CMD_SET_POSITION, #0c, #17
#ab03#43832
        db CMD_SET_ATTRIBUTE, #4d
#ab05#43858
        db "ENEMY   "
#ab0d#438d1
        db CMD_NEXT_LINE
#ab0e#438e8
        db "  ROBOTS"
#ab16#43961
        db CMD_NEXT_LINE
#ab17#43971
        db CMD_NEXT_LINE
#ab18#43988
        db "ENEMY   "
#ab20#43a01
        db CMD_NEXT_LINE
#ab21#43a18
        db "FACTORYS"
#ab29#43a91
        db CMD_NEXT_LINE
#ab2a#43aa1
        db CMD_NEXT_LINE
#ab2b#43ab8
        db "ENEMY   "
#ab33#43b31
        db CMD_NEXT_LINE
#ab34#43b48
        db "WARBASES"
#ab3c#43bc1
        db CMD_END
#ab3d#43bd
    ; Script end
#ab3d#43bd318
cd 1d a8 
    call La81d_draw_robot_strength
#ab40#43c0311
21 37 59 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0137  ; ptr to the attributes of the first menu option
#ab43#43c328
3e 01 
    ld a, 1  ; start at option 1
#ab45#43c528
1e 04 
    ld e, 4  ; 3 options menu
#ab47#43c7318
cd d7 ac 
    call Lacd7_right_hud_menu_control
#ab4a#43ca28
c6 02 
    add a, ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS - 1
#ab4c#43cc213
18 7a 
    jr Labc8_capture_or_destroy_order_selected
#ab4e#43ce
#ab4e#43ce
Lab4e_give_capture_orders:
#ab4e#43ce318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#ab51#43d1318
cd 2d d4 
    call Ld42d_execute_ui_script
#ab54#43d4
    ; Script start:
#ab54#43d43
        db CMD_SET_POSITION, #04, #17
#ab57#43d72
        db CMD_SET_ATTRIBUTE, #4f
#ab59#43d98
        db "SEARCH &"
#ab61#43e11
        db CMD_NEXT_LINE
#ab62#43e28
        db " CAPTURE"
#ab6a#43ea3
        db CMD_SET_POSITION, #08, #18
#ab6d#43ed2
        db CMD_SET_ATTRIBUTE, #45
#ab6f#43ef6
        db "SELECT"
#ab75#43f51
        db CMD_NEXT_LINE
#ab76#43f66
        db "TARGET"
#ab7c#43fc3
        db CMD_SET_POSITION, #0c, #17
#ab7f#43ff2
        db CMD_SET_ATTRIBUTE, #4d
#ab81#44018
        db "NEUTRAL "
#ab89#44091
        db CMD_NEXT_LINE
#ab8a#440a8
        db "FACTORYS"
#ab92#44121
        db CMD_NEXT_LINE
#ab93#44131
        db CMD_NEXT_LINE
#ab94#44148
        db "ENEMY   "
#ab9c#441c1
        db CMD_NEXT_LINE
#ab9d#441d8
        db "FACTORYS"
#aba5#44251
        db CMD_NEXT_LINE
#aba6#44261
        db CMD_NEXT_LINE
#aba7#44278
        db "ENEMY   "
#abaf#442f1
        db CMD_NEXT_LINE
#abb0#44308
        db "WARBASES"
#abb8#44381
        db CMD_END
#abb9#4439
    ; Script end:
#abb9#4439318
cd 1d a8 
    call La81d_draw_robot_strength
#abbc#443c311
21 37 59 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0137  ; ptr to the attributes of the first menu option
#abbf#443f28
3e 01 
    ld a, 1  ; start at option 1
#abc1#444128
1e 04 
    ld e, 4  ; 3 options menu
#abc3#4443318
cd d7 ac 
    call Lacd7_right_hud_menu_control
#abc6#444628
c6 05 
    add a, ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES - 1
#abc8#4448
#abc8#4448
Labc8_capture_or_destroy_order_selected:
#abc8#4448321
dd 77 0b 
    ld (ix + ROBOT_STRUCT_ORDERS), a
#abcb#444b28
fe 04 
    cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES
#abcd#444d213/8
38 0a 
    jr c, Labd9_orders_executable
#abcf#444f28
fe 06 
    cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES
#abd1#4451213/8
30 06 
    jr nc, Labd9_orders_executable
#abd3#4453
    ; Player has selected to destroy factories or warbases.
#abd3#4453
    ; For that purpose, the robot must be equipped with a nuclear weapon.
#abd3#4453
    ; Check if it does, and otherwise, just cancel the order:
#abd3#4453422
dd cb 07 76 
    bit 6, (ix + ROBOT_STRUCT_PIECES)
#abd7#4457213/8
28 18 
    jr z, Labf1_orders_not_executable
#abd9#4459
Labd9_orders_executable:
#abd9#4459321
dd 6e 02 
    ld l, (ix + ROBOT_STRUCT_X)
#abdc#445c321
dd 66 03 
    ld h, (ix + ROBOT_STRUCT_X + 1)
#abdf#445f112
f5 
    push af
#abe0#446015
af 
        xor a
#abe1#4461314
32 51 fd 
        ld (Lfd51_current_robot_player_or_enemy), a
#abe4#4464111
f1 
    pop af
#abe5#4465421
dd 36 0e ff 
    ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), #ff
#abe9#4469318
cd 4d b3 
    call Lb34d_find_capture_or_destroy_target
#abec#446c321
dd 72 0e 
    ld (ix + ROBOT_STRUCT_ORDERS_ARGUMENT), d
#abef#446f213/8
20 04 
    jr nz, Labf5_order_assignment_done
#abf1#4471
Labf1_orders_not_executable:
#abf1#4471421
dd 36 0b 00 
    ld (ix + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND
#abf5#4475
Labf5_order_assignment_done:
#abf5#447528
3e 78 
    ld a, 120
#abf7#4477318
cd ac cc 
    call Lccac_beep
#abfa#447a318
cd 57 ad 
    call Lad57_wait_until_no_keys_pressed
#abfd#447d311
c3 32 a7 
    jp La732_land_on_robot_internal
#ac00#4480
#ac00#4480
#ac00#4480
; --------------------------------    
#ac00#4480
; Combat mode menu loop.
#ac00#4480
Lac00_combat_mode:
#ac00#4480318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#ac03#4483318
cd 2d d4 
    call Ld42d_execute_ui_script
#ac06#4486
    ; Start script:
#ac06#44863
        db CMD_SET_POSITION, #04, #17
#ac09#44892
        db CMD_SET_ATTRIBUTE, #4d
#ac0b#448b8
        db "NUCLEAR "
#ac13#44931
        db CMD_NEXT_LINE
#ac14#44948
        db "    BOMB"
#ac1c#449c1
        db CMD_NEXT_LINE
#ac1d#449d1
        db CMD_NEXT_LINE
#ac1e#449e8
        db "FIRE    "
#ac26#44a61
        db CMD_NEXT_LINE
#ac27#44a78
        db " PHASERS"
#ac2f#44af1
        db CMD_NEXT_LINE
#ac30#44b01
        db CMD_NEXT_LINE
#ac31#44b18
        db "FIRE    "
#ac39#44b91
        db CMD_NEXT_LINE
#ac3a#44ba8
        db "MISSILES"
#ac42#44c21
        db CMD_NEXT_LINE
#ac43#44c31
        db CMD_NEXT_LINE
#ac44#44c48
        db "FIRE    "
#ac4c#44cc1
        db CMD_NEXT_LINE
#ac4d#44cd8
        db "  CANNON"
#ac55#44d51
        db CMD_NEXT_LINE
#ac56#44d61
        db CMD_NEXT_LINE
#ac57#44d78
        db "MOVE    "
#ac5f#44df1
        db CMD_NEXT_LINE
#ac60#44e08
        db "   ROBOT"
#ac68#44e81
        db CMD_NEXT_LINE
#ac69#44e91
        db CMD_NEXT_LINE
#ac6a#44ea8
        db "STOP    "
#ac72#44f21
        db CMD_NEXT_LINE
#ac73#44f38
        db "  COMBAT"
#ac7b#44fb1
        db CMD_END
#ac7c#44fc
    ; End script:
#ac7c#44fc318
cd 1d a8 
    call La81d_draw_robot_strength
#ac7f#44ff28
3e 06 
    ld a, 6  ; current option is the bottom
#ac81#4501
Lac81_combat_mode_loop:
#ac81#4501311
21 37 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0037
#ac84#450428
1e 07 
    ld e, 7  ; menu has 6 options
#ac86#4506318
cd d7 ac 
    call Lacd7_right_hud_menu_control
#ac89#450928
fe 06 
    cp 6  ; stop combat
#ac8b#450b311
ca 32 a7 
    jp z, La732_land_on_robot_internal
#ac8e#450e112
f5 
    push af
#ac8f#450f28
fe 05 
        cp 5
#ac91#4511213/8
20 06 
        jr nz, Lac99_weapon_fire_selected
#ac93#4513318
cd 41 a9 
        call La941_direct_control_internal
#ac96#4516111
f1 
    pop af
#ac97#4517213
18 e8 
    jr Lac81_combat_mode_loop
#ac99#4519
#ac99#4519
Lac99_weapon_fire_selected:
#ac99#451915
4f 
        ld c, a
#ac9a#451a15
47 
        ld b, a
#ac9b#451b15
04 
        inc b
#ac9c#451c321
dd 7e 07 
        ld a, (ix + ROBOT_STRUCT_PIECES)
#ac9f#451f
Lac9f:
#ac9f#451f15
07 
        rlca
#aca0#4520214/9
10 fd 
        djnz Lac9f
#aca2#4522213/8
30 2a 
        jr nc, Lacce_selected_weapon_not_present
#aca4#4524111
f1 
    pop af
#aca5#452528
fe 01 
    cp 1
#aca7#4527213/8
20 0a 
    jr nz, Lacb3_regular_weapon_fire
#aca9#4529
    ; nuclear bomb selected:
#aca9#4529217
dd e5 
    push ix
#acab#452b216
fd e1 
    pop iy
#acad#452d318
cd 9f b9 
    call Lb99f_fire_nuclear_bomb
#acb0#4530311
c3 12 a8 
    jp La812_exit_robot
#acb3#4533
#acb3#4533
Lacb3_regular_weapon_fire:
#acb3#4533
    ; Weapon to fire is in "c"
#acb3#4533112
f5 
    push af
#acb4#4534
        ; The first bullet record is used only for "combat mode". So, we only need to check if the 
#acb4#4534
        ; first bullet is available:
#acb4#4534416
fd 21 d3 d7 
        ld iy, Ld7d3_bullets
#acb8#4538321
fd 7e 01 
        ld a, (iy + 1)
#acbb#453b15
b7 
        or a  ; If there is already a weapon in use, we cannot fire
#acbc#453c213/8
20 10 
        jr nz, Lacce_selected_weapon_not_present
#acbe#453e28
3e 05 
        ld a, 5
#acc0#454015
91 
        sub c
#acc1#4541318
cd d6 b6 
        call Lb6d6_weapon_fire
#acc4#4544318
cd bd cc 
        call Lccbd_redraw_game_area
#acc7#4547318
cd 62 ad 
        call Lad62_increase_time
#acca#454a111
f1 
    pop af
#accb#454b311
c3 81 ac 
    jp Lac81_combat_mode_loop
#acce#454e
#acce#454e
Lacce_selected_weapon_not_present:
#acce#454e28
3e fa 
    ld a, 250
#acd0#4550318
cd ac cc 
    call Lccac_beep
#acd3#4553111
f1 
    pop af
#acd4#4554311
c3 81 ac 
    jp Lac81_combat_mode_loop
#acd7#4557
#acd7#4557
#acd7#4557
; --------------------------------
#acd7#4557
; Loop for moving around the options on a right-hand-side hud menu.
#acd7#4557
; Input:
#acd7#4557
; - a: cursor position.
#acd7#4557
; - e: number of options in the menu
#acd7#4557
Lacd7_right_hud_menu_control:
#acd7#4557112
f5 
    push af
#acd8#4558318
cd 57 ad 
        call Lad57_wait_until_no_keys_pressed
#acdb#455b111
f1 
    pop af
#acdc#455c15
57 
    ld d, a
#acdd#455d28
0e 4e 
    ld c, COLOR_BRIGHT + COLOR_BLUE * PAPER_COLOR_MULTIPLIER + COLOR_YELLOW
#acdf#455f318
cd 3c ad 
    call Lad3c_set_attributes_for_menu_option
#ace2#4562
Lace2_right_hud_menu_control_loop:
#ace2#4562321
dd 7e 01 
    ld a, (ix + 1)  ; check if the robot is destroyed
#ace5#456515
b7 
    or a
#ace6#4566213/8
20 04 
    jr nz, Lacec_robot_not_destroyed  ; if the robot is not destroyed, continue
#ace8#4568111
e1 
    pop hl  ; simulate a "ret"
#ace9#4569311
c3 12 a8 
    jp La812_exit_robot
#acec#456c
Lacec_robot_not_destroyed:
#acec#456c112
e5 
    push hl
#aced#456d318
cd 7c d3 
        call Ld37c_read_keyboard_joystick_input
#acf0#4570111
e1 
    pop hl
#acf1#457115
4a 
    ld c, d  ; d still has the cursor position
#acf2#4572314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#acf5#4575210
cb 67 
    bit 4, a  ; is "fire" pressed
#acf7#4577213/8
20 36 
    jr nz, Lad2f_menu_option_selected
#acf9#457915
0f 
    rrca
#acfa#457a28
e6 06 
    and 6
#acfc#457c213/8
28 1c 
    jr z, Lad1a_no_cursor_change  ; neither up nor down are pressed
#acfe#457e28
e6 02 
    and 2  ; if pressing down, a = 2, otherwise, a = 0
#ad00#458015
0d 
    dec c  ; more cursor up
#ad01#458115
81 
    add a, c  ; if we pressed down, a = option + 1, otherwise, option - 1
#ad02#4582213/8
28 16 
    jr z, Lad1a_no_cursor_change  ; if we pressed up and are at the top, no change
#ad04#458415
bb 
    cp e
#ad05#4585213/8
30 13 
    jr nc, Lad1a_no_cursor_change  ; if we pressed down and we are at the bottom, no change
#ad07#4587112
f5 
    push af
#ad08#458815
7a 
        ld a, d
#ad09#458928
0e 4d 
        ld c, COLOR_BRIGHT + COLOR_BLUE * PAPER_COLOR_MULTIPLIER + COLOR_CYAN
#ad0b#458b318
cd 3c ad 
        call Lad3c_set_attributes_for_menu_option
#ad0e#458e111
f1 
    pop af
#ad0f#458f15
57 
    ld d, a
#ad10#459028
0e 4e 
    ld c, COLOR_BRIGHT + COLOR_BLUE * PAPER_COLOR_MULTIPLIER + COLOR_YELLOW
#ad12#4592318
cd 3c ad 
    call Lad3c_set_attributes_for_menu_option
#ad15#459528
3e 14 
    ld a, 20
#ad17#4597318
cd ac cc 
    call Lccac_beep
#ad1a#459a
Lad1a_no_cursor_change:
#ad1a#459a112
d5 
    push de
#ad1b#459b112
e5 
    push hl
#ad1c#459c
        ; Advance on game tick:
#ad1c#459c318
cd ca b0 
        call Lb0ca_update_robots_bullets_and_ai
#ad1f#459f318
cd bd cc 
        call Lccbd_redraw_game_area
#ad22#45a2318
cd 48 b0 
        call Lb048_update_radar
#ad25#45a5318
cd 62 ad 
        call Lad62_increase_time
#ad28#45a8318
cd 1d a8 
        call La81d_draw_robot_strength
#ad2b#45ab111
e1 
    pop hl
#ad2c#45ac111
d1 
    pop de
#ad2d#45ad213
18 b3 
    jr Lace2_right_hud_menu_control_loop
#ad2f#45af
Lad2f_menu_option_selected:
#ad2f#45af15
7a 
    ld a, d  ; d still has the cursor position
#ad30#45b028
0e 4f 
    ld c, COLOR_BRIGHT + COLOR_BLUE * PAPER_COLOR_MULTIPLIER + COLOR_WHITE
#ad32#45b2318
cd 3c ad 
    call Lad3c_set_attributes_for_menu_option
#ad35#45b528
3e 64 
    ld a, 100
#ad37#45b7318
cd ac cc 
    call Lccac_beep
#ad3a#45ba15
7a 
    ld a, d  ; d still has the cursor position
#ad3b#45bb111
c9 
    ret
#ad3c#45bc
#ad3c#45bc
#ad3c#45bc
; --------------------------------
#ad3c#45bc
; Sets a 8x2 block in the attribute table to attribute "c". This is used to set the attributes of
#ad3c#45bc
; menu options in the right-hand-side hud.
#ad3c#45bc
; Input:
#ad3c#45bc
; - c: attribute value to set
#ad3c#45bc
; - a: which row to change attributes for (each row is 3 screen rows apart).
#ad3c#45bc
; - hl: attribute address of the first row
#ad3c#45bc
Lad3c_set_attributes_for_menu_option:
#ad3c#45bc15
47 
    ld b, a
#ad3d#45bd112
d5 
    push de
#ad3e#45be112
e5 
    push hl
#ad3f#45bf311
11 60 00 
        ld de, 32 * 3
#ad42#45c2
Lad42:
#ad42#45c2112
19 
        add hl, de
#ad43#45c3214/9
10 fd 
        djnz Lad42
#ad45#45c528
06 08 
        ld b, 8
#ad47#45c7318
cd db cb 
        call Lcbdb_set_attribute_loop  ; set 8 attribute positions to attribute "c"
#ad4a#45ca28
3e 18 
        ld a, 24
#ad4c#45cc318
cd 51 d3 
        call Ld351_add_hl_a  ; go one row down
#ad4f#45cf28
06 08 
        ld b, 8
#ad51#45d1318
cd db cb 
        call Lcbdb_set_attribute_loop  ; set 8 attribute positions to attribute "c"
#ad54#45d4111
e1 
    pop hl
#ad55#45d5111
d1 
    pop de
#ad56#45d6111
c9 
    ret
#ad57#45d7
#ad57#45d7
#ad57#45d7
; --------------------------------
#ad57#45d7
; Waits until the user is not pressing any key.
#ad57#45d7
Lad57_wait_until_no_keys_pressed:
#ad57#45d7112
c5 
    push bc
#ad58#45d8112
e5 
    push hl
#ad59#45d9
Lad59_wait_for_key_release_loop:
#ad59#45d9318
cd 7c d3 
        call Ld37c_read_keyboard_joystick_input
#ad5c#45dc15
b7 
        or a
#ad5d#45dd213/8
20 fa 
        jr nz, Lad59_wait_for_key_release_loop
#ad5f#45df111
e1 
    pop hl
#ad60#45e0111
c1 
    pop bc
#ad61#45e1111
c9 
    ret
#ad62#45e2
#ad62#45e2
#ad62#45e2
; --------------------------------
#ad62#45e2
; - increases time by 5 minutes, and checks if a whole day has passed, to give resources to the
#ad62#45e2
;   players
#ad62#45e2
Lad62_increase_time:
#ad62#45e2318
cd 58 d3 
    call Ld358_random
#ad65#45e5311
21 35 fd 
    ld hl, Lfd35_minutes
#ad68#45e818
7e 
    ld a, (hl)
#ad69#45e928
c6 05 
    add a, 5  ; add 5 minutes
#ad6b#45eb18
77 
    ld (hl), a
#ad6c#45ec28
fe 3c 
    cp 60
#ad6e#45ee213/8
20 15 
    jr nz, Lad85_increase_time_done
#ad70#45f0211
36 00 
    ld (hl), 0  ; reset minutes
#ad72#45f217
23 
    inc hl
#ad73#45f3112
34 
    inc (hl)  ; increase hour
#ad74#45f418
7e 
    ld a, (hl)
#ad75#45f528
fe 18 
    cp 24
#ad77#45f7213/8
20 0c 
    jr nz, Lad85_increase_time_done
#ad79#45f9211
36 00 
    ld (hl), 0  ; reset hour
#ad7b#45fb317
2a 37 fd 
    ld hl, (Lfd37_days)
#ad7e#45fe17
23 
    inc hl  ; increase days
#ad7f#45ff317
22 37 fd 
    ld (Lfd37_days), hl
#ad82#4602318
cd 38 ae 
    call Lae38_gain_day_resources
#ad85#4605
Lad85_increase_time_done:
#ad85#4605318
cd 2d d4 
    call Ld42d_execute_ui_script
#ad88#4608
    ; Start script:
#ad88#46083
        db CMD_SET_POSITION, #00, #1b
#ad8b#460b2
        db CMD_SET_SCALE, #00
#ad8d#460d2
        db CMD_SET_ATTRIBUTE, #57
#ad8f#460f1
        db CMD_END
#ad90#4610
    ; End script:
#ad90#4610317
2a 37 fd 
    ld hl, (Lfd37_days)
#ad93#4613318
cd f3 d3 
    call Ld3f3_render_16bit_number
#ad96#4616318
cd 70 d4 
    call Ld470_execute_command_3_next_line
#ad99#4619314
3a 36 fd 
    ld a, (Lfd36_hours)
#ad9c#461c318
cd ec d3 
    call Ld3ec_render_8bit_number_with_leading_zeroes
#ad9f#461f28
3e 2e 
    ld a, 46
#ada1#4621318
cd 27 d4 
    call Ld427_draw_character_saving_registers
#ada4#4624314
3a 35 fd 
    ld a, (Lfd35_minutes)
#ada7#4627318
cd ec d3 
    call Ld3ec_render_8bit_number_with_leading_zeroes
#adaa#462a318
cd 6b ae 
    call Lae6b_game_over_check
#adad#462d217
fd e5 
    push iy
#adaf#462f416
fd 21 70 fd 
        ld iy, Lfd70_warbases
#adb3#463328
06 1c 
        ld b, N_WARBASES + N_FACTORIES
#adb5#463528
0e 00 
        ld c, 0  ; c keeps track of how many captures happened this cycle
#adb7#4637
Ladb7_building_loop:
#adb7#4637321
fd 6e 00 
        ld l, (iy + BUILDING_STRUCT_X)
#adba#463a321
fd 66 01 
        ld h, (iy + BUILDING_STRUCT_X + 1)
#adbd#463d321
fd 7e 02 
        ld a, (iy + BUILDING_STRUCT_Y)
#adc0#4640318
cd a6 cc 
        call Lcca6_compute_map_ptr
#adc3#4643214
cb 76 
        bit 6, (hl)  ; check if building is still there
#adc5#4645213/8
20 06 
        jr nz, Ladcd_something_in_front_of_it
#adc7#4647421
fd 36 04 00 
        ld (iy + BUILDING_STRUCT_TIMER), 0
#adcb#464b213
18 38 
        jr Lae05_next_building
#adcd#464d
Ladcd_something_in_front_of_it:
#adcd#464d325
fd 34 04 
        inc (iy + BUILDING_STRUCT_TIMER)
#add0#4650321
fd 7e 04 
        ld a, (iy + BUILDING_STRUCT_TIMER)
#add3#465328
fe 90 
        cp BUILDING_CAPTURE_TIME
#add5#4655213/8
38 2e 
        jr c, Lae05_next_building
#add7#4657
        ; Something has been in front of the factory for BUILDING_CAPTURE_TIME cycles, capture!
#add7#4657421
fd 36 04 00 
        ld (iy + BUILDING_STRUCT_TIMER), 0
#addb#465b112
c5 
        push bc
#addc#465c217
fd e5 
            push iy
#adde#465e318
cd d8 cd 
                call Lcdd8_get_robot_at_ptr
#ade1#4661321
fd 7e 0a 
                ld a, (iy + ROBOT_STRUCT_CONTROL)
#ade4#466415
07 
                rlca
#ade5#466528
e6 01 
                and 1
#ade7#466715
5f 
                ld e, a  ; here e has the robot owner (0 = player, 1 = enemy AI)
#ade8#4668216
fd e1 
            pop iy
#adea#466a15
78 
            ld a, b  ; if b == 0, no robot was found
#adeb#466b15
b7 
            or a
#adec#466c213/8
28 16 
            jr z, Lae04_next_building_pop
#adee#466e111
c1 
        pop bc
#adef#466f15
0c 
        inc c
#adf0#4670112
c5 
        push bc
#adf1#467128
3e 1c 
            ld a, N_FACTORIES + N_WARBASES
#adf3#467315
90 
            sub b
#adf4#467428
fe 04 
            cp 4
#adf6#4676213/8
30 06 
            jr nc, Ladfe_factory
#adf8#467815
43 
            ld b, e
#adf9#4679318
cd 86 bb 
            call Lbb86_assign_warbase_to_player  ; warbase captured!
#adfc#467c213
18 06 
            jr Lae04_next_building_pop
#adfe#467e
Ladfe_factory:
#adfe#467e28
d6 04 
            sub 4
#ae00#468015
43 
            ld b, e
#ae01#4681318
cd 61 bb 
            call Lbb61_assign_factory_to_player  ; factory captured!
#ae04#4684
Lae04_next_building_pop:
#ae04#4684111
c1 
        pop bc
#ae05#4685
Lae05_next_building:
#ae05#4685
        ; next building (as BUILDING_STRUCT_SIZE == 5):
#ae05#4685212
fd 23 
        inc iy
#ae07#4687212
fd 23 
        inc iy
#ae09#4689212
fd 23 
        inc iy
#ae0b#468b212
fd 23 
        inc iy
#ae0d#468d212
fd 23 
        inc iy
#ae0f#468f214/9
10 a6 
        djnz Ladb7_building_loop
#ae11#4691216
fd e1 
    pop iy
#ae13#469315
79 
    ld a, c  ; "c" has the number of buildings captured this cycle.
#ae14#469415
b7 
    or a
#ae15#4695213/8
28 06 
    jr z, Lae1d_no_new_captures
#ae17#4697318
cd 09 bb 
    call Lbb09_update_players_warbase_and_factory_counts
#ae1a#469a318
cd 93 d2 
    call Ld293_update_stats_in_right_hud
#ae1d#469d
Lae1d_no_new_captures:
#ae1d#469d314
3a 34 fd 
    ld a, (Lfd34_n_interrupts_this_came_cycle)
#ae20#46a028
fe 0a 
    cp MIN_INTERRUPTS_PER_GAME_CYCLE
#ae22#46a2213/8
38 f9 
    jr c, Lae1d_no_new_captures  ; Loop to make sure games does not run too fast
#ae24#46a415
af 
    xor a
#ae25#46a5314
32 34 fd 
    ld (Lfd34_n_interrupts_this_came_cycle), a
#ae28#46a8111
c9 
    ret
#ae29#46a9
#ae29#46a9
#ae29#46a9
; --------------------------------
#ae29#46a9
; Unused/unreachable code:
#ae29#46a9
; - I did not find anywhere in the code that could jump here. It could be some left-over code from
#ae29#46a9
;   a previous version of the game.
#ae29#46a9
; - It does not make sense to jump to the BIOS address #04b0 from this game, in any case, since it 
#ae29#46a9
;   contains BASIC-related code. So, this code can be removed.
#ae29#46a9
Lae29:
#ae29#46a928
3e ef 
    ld a, INTERFACE2_JOYSTICK_PORT_MSB
#ae2b#46ab212
db fe 
    in a, (ULA_PORT)  ; read the interface2 joystick state
#ae2d#46ad28
e6 18 
    and #18  ; button 1 or "up"
#ae2f#46af112/6
c0 
    ret nz
#ae30#46b0311
21 00 a6 
    ld hl, La600_start
#ae33#46b3112
e5 
    push hl
#ae34#46b415
f3 
    di
#ae35#46b5311
c3 b0 04 
    jp #04b0
#ae38#46b8
#ae38#46b8
#ae38#46b8
; --------------------------------
#ae38#46b8
; Update the resources each player has adding their daily gains, and updates the hud.
#ae38#46b8
Lae38_gain_day_resources:
#ae38#46b8311
21 22 fd 
    ld hl, Lfd22_player1_resource_counts
#ae3b#46bb311
11 3a fd 
    ld de, Lfd3a_player1_base_factory_counts
#ae3e#46be318
cd 4e ae 
    call Lae4e_gain_day_resources_player
#ae41#46c1311
21 4a fd 
    ld hl, Lfd4a_player2_resource_counts
#ae44#46c4311
11 42 fd 
    ld de, Lfd42_player2_base_factory_counts
#ae47#46c7318
cd 4e ae 
    call Lae4e_gain_day_resources_player
#ae4a#46ca318
cd 93 d2 
    call Ld293_update_stats_in_right_hud
#ae4d#46cd111
c9 
    ret
#ae4e#46ce
#ae4e#46ce
#ae4e#46ce
; --------------------------------
#ae4e#46ce
; - adds 5 times the number of bases to the general resources
#ae4e#46ce
; - adds 2 times the number of factories of each type to the part-specific resources
#ae4e#46ce
; input:
#ae4e#46ce
; - de: pointer to the # of bases and factories of a given player
#ae4e#46ce
; - hl: pointer to the resources of a given player
#ae4e#46ce
Lae4e_gain_day_resources_player:
#ae4e#46ce18
1a 
    ld a, (de)
#ae4f#46cf15
4f 
    ld c, a
#ae50#46d015
87 
    add a, a
#ae51#46d115
87 
    add a, a
#ae52#46d215
81 
    add a, c  ; a = (de)*5
#ae53#46d3318
cd 62 ae 
    call Lae62_add_limit_100  ; (hl) += (de)*5
#ae56#46d628
06 06 
    ld b, 6
#ae58#46d8
Lae58_factory_loop:
#ae58#46d817
23 
    inc hl
#ae59#46d917
13 
    inc de
#ae5a#46da18
1a 
    ld a, (de)
#ae5b#46db15
87 
    add a, a
#ae5c#46dc318
cd 62 ae 
    call Lae62_add_limit_100
#ae5f#46df214/9
10 f7 
    djnz Lae58_factory_loop
#ae61#46e1111
c9 
    ret
#ae62#46e2
#ae62#46e2
#ae62#46e2
; --------------------------------
#ae62#46e2
; Adds a to (hl), keeping the result smaller than 100
#ae62#46e2
Lae62_add_limit_100:
#ae62#46e218
86 
    add a, (hl)
#ae63#46e328
fe 64 
    cp 100
#ae65#46e5213/8
38 02 
    jr c, Lae69_smaller_than_100
#ae67#46e728
3e 63 
    ld a, 99
#ae69#46e9
Lae69_smaller_than_100:
#ae69#46e918
77 
    ld (hl), a
#ae6a#46ea111
c9 
    ret
#ae6b#46eb
#ae6b#46eb
#ae6b#46eb
; --------------------------------
#ae6b#46eb
; Checks if one of the players does not have any bases left,
#ae6b#46eb
; and shows the victory or defeat messages.
#ae6b#46eb
Lae6b_game_over_check:
#ae6b#46eb314
3a 42 fd 
    ld a, (Lfd42_player2_base_factory_counts)
#ae6e#46ee15
b7 
    or a
#ae6f#46ef213/8
28 40 
    jr z, Laeb1_game_over_victory
#ae71#46f1314
3a 3a fd 
    ld a, (Lfd3a_player1_base_factory_counts)
#ae74#46f415
b7 
    or a
#ae75#46f5112/6
c0 
    ret nz
#ae76#46f6
    ; Game over defeat:
#ae76#46f6318
cd 00 af 
    call Laf00_set_default_hud_and_empty_interrupt
#ae79#46f9318
cd 2d d4 
    call Ld42d_execute_ui_script
#ae7c#46fc
    ; script start:
#ae7c#46fc3
        db CMD_SET_POSITION, 22, 0
#ae7f#46ff2
        db CMD_SET_ATTRIBUTE, 69
#ae81#470122
        db "YOU HAVE NO BASES LEFT"
#ae97#47171
        db CMD_NEXT_LINE
#ae98#471822
        db "BETTER LUCK NEXT TIME!"
#aeae#472e1
        db CMD_END
#aeaf#472f
    ; script end:
#aeaf#472f213
18 39 
    jr Laeea_game_over_message_drawn
#aeb1#4731
Laeb1_game_over_victory:
#aeb1#4731318
cd 00 af 
    call Laf00_set_default_hud_and_empty_interrupt
#aeb4#4734318
cd 2d d4 
    call Ld42d_execute_ui_script
#aeb7#4737
    ; script start:
#aeb7#47373
        db CMD_SET_POSITION, 22, 0
#aeba#473a2
        db CMD_SET_ATTRIBUTE, 69
#aebc#473c22
        db " INSIGNIANS DESTROYED "
#aed2#47521
        db CMD_NEXT_LINE
#aed3#475322
        db "    YOU HAVE WON !    "
#aee9#47691
        db CMD_END
#aeea#476a
    ; script end:
#aeea#476a
Laeea_game_over_message_drawn:
#aeea#476a
    ; Produce a sound, wait for player to press some key, and restart the game.
#aeea#476a28
3e fa 
    ld a, 250
#aeec#476c318
cd ac cc 
    call Lccac_beep
#aeef#476f28
06 64 
    ld b, 100  ; wait 2 seconds
#aef1#4771
Laef1_wait_loop:
#aef1#477115
76 
    halt
#aef2#4772214/9
10 fd 
    djnz Laef1_wait_loop
#aef4#4774318
cd 57 ad 
    call Lad57_wait_until_no_keys_pressed
#aef7#4777
Laef7_wait_for_any_key:
#aef7#4777318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#aefa#477a15
b7 
    or a
#aefb#477b213/8
28 fa 
    jr z, Laef7_wait_for_any_key
#aefd#477d311
c3 00 a6 
    jp La600_start
#af00#4780
#af00#4780
Laf00_set_default_hud_and_empty_interrupt:
#af00#478015
af 
    xor a
#af01#4781314
32 39 fd 
    ld (Lfd39_current_in_game_right_hud), a
#af04#4784318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud  ; Potential optimization: not needed, as this is already 
#af07#4787
                                        ; called in the function below
#af07#4787318
cd e5 d1 
    call Ld1e5_draw_in_game_right_hud
#af0a#478a311
21 9c d5 
    ld hl, Ld59c_empty_interrupt
#af0d#478d317
22 fe fd 
    ld (Lfdfe_interrupt_pointer), hl
#af10#4790111
c9 
    ret
#af11#4791
#af11#4791
#af11#4791
; --------------------------------
#af11#4791
; Controls the player ship using keyboard.
#af11#4791
Laf11_player_ship_keyboard_control:
#af11#4791318
cd 1d b0 
    call Lb01d_remove_player_from_map
#af14#4794
    ; If the player is pressing up/down, reduce the effect of Lfd30_player_elevate_timer: 
#af14#4794314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#af17#479728
e6 0c 
    and #0c  ; down/up
#af19#4799213/8
28 0a 
    jr z, Laf25_player_ship_keyboard_control_x  ; Potential optimization: the following lines 
#af1b#479b
                                                ; implement a random behavior (reduce elevate timer 
#af1b#479b
                                                ; if you are pressing up/down) that can be removed.
#af1b#479b314
3a 30 fd 
    ld a, (Lfd30_player_elevate_timer)
#af1e#479e15
b7 
    or a
#af1f#479f213/8
28 04 
    jr z, Laf25_player_ship_keyboard_control_x
#af21#47a115
3d 
    dec a
#af22#47a2314
32 30 fd 
    ld (Lfd30_player_elevate_timer), a
#af25#47a5
#af25#47a5
Laf25_player_ship_keyboard_control_x:
#af25#47a5314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#af28#47a828
e6 03 
    and #03
#af2a#47aa213/8
28 4b 
    jr z, Laf77_player_ship_keyboard_control_y  ; if left/right are not pressed
#af2c#47ac28
fe 03 
    cp 3
#af2e#47ae213/8
28 47 
    jr z, Laf77_player_ship_keyboard_control_y  ; if left/right are pressed simultaneously
#af30#47b0317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#af33#47b315
0f 
    rrca
#af34#47b4213/8
38 0c 
    jr c, Laf42_move_right
#af36#47b6
    ; Move left:
#af36#47b615
7c 
    ld a, h
#af37#47b715
b7 
    or a
#af38#47b8213/8
20 05 
    jr nz, Laf3f
#af3a#47ba15
7d 
    ld a, l
#af3b#47bb28
fe 0e 
    cp MIN_PLAYER_X
#af3d#47bd213/8
28 38 
    jr z, Laf77_player_ship_keyboard_control_y
#af3f#47bf
Laf3f:
#af3f#47bf17
2b 
    dec hl
#af40#47c0213
18 0a 
    jr Laf4c_move_player_if_no_collision
#af42#47c2
Laf42_move_right:
#af42#47c215
7c 
    ld a, h
#af43#47c315
b7 
    or a
#af44#47c4213/8
28 05 
    jr z, Laf4b
#af46#47c615
7d 
    ld a, l
#af47#47c728
fe f5 
    cp MAX_PLAYER_X - 256
#af49#47c9213/8
28 2c 
    jr z, Laf77_player_ship_keyboard_control_y
#af4b#47cb
Laf4b:
#af4b#47cb17
23 
    inc hl
#af4c#47cc
Laf4c_move_player_if_no_collision:
#af4c#47cc314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#af4f#47cf318
cd 52 b0 
    call Lb052_check_player_collision
#af52#47d2213/8
38 03 
    jr c, Laf57_collision
#af54#47d4317
22 0e fd 
    ld (Lfd0e_player_x), hl
#af57#47d7
Laf57_collision:
#af57#47d7
    ; See if we need to scroll the map:
#af57#47d7317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#af5a#47da422
ed 5b 0a fd 
    ld de, (Lfd0a_scroll_x)
#af5e#47de15
af 
    xor a
#af5f#47df217
ed 52 
    sbc hl, de
#af61#47e115
7d 
    ld a, l
#af62#47e228
fe 0d 
    cp 13  ; player in the left screen edge
#af64#47e4213/8
20 01 
    jr nz, Laf67_no_scroll_left
#af66#47e617
1b 
    dec de
#af67#47e7
Laf67_no_scroll_left:
#af67#47e728
fe 16 
    cp 22  ; player in the right screen edge
#af69#47e9213/8
20 01 
    jr nz, Laf6c_no_scroll_right
#af6b#47eb17
13 
    inc de
#af6c#47ec
Laf6c_no_scroll_right:
#af6c#47ec422
ed 53 0a fd 
    ld (Lfd0a_scroll_x), de
#af70#47f0311
21 00 dd 
    ld hl, Ldd00_map
#af73#47f3112
19 
    add hl, de
#af74#47f4317
22 06 fd 
    ld (Lfd06_scroll_ptr), hl
#af77#47f7
#af77#47f7
Laf77_player_ship_keyboard_control_y:
#af77#47f7314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#af7a#47fa15
4f 
    ld c, a
#af7b#47fb314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#af7e#47fe15
0f 
    rrca
#af7f#47ff15
0f 
    rrca
#af80#480028
e6 03 
    and #03
#af82#4802213/8
28 1e 
    jr z, Lafa2_player_ship_keyboard_control_altitude  ; up/down not pressed
#af84#480428
fe 03 
    cp 3
#af86#4806213/8
28 1a 
    jr z, Lafa2_player_ship_keyboard_control_altitude  ; up/down pressed simultaneously
#af88#480815
0f 
    rrca
#af89#4809213/8
30 01 
    jr nc, Laf8c_no_move_down  ; no move down
#af8b#480b15
0c 
    inc c
#af8c#480c
Laf8c_no_move_down:
#af8c#480c15
0f 
    rrca
#af8d#480d213/8
30 01 
    jr nc, Laf90_no_move_up
#af8f#480f15
0d 
    dec c
#af90#4810
Laf90_no_move_up:
#af90#481015
79 
    ld a, c
#af91#481128
e6 0f 
    and #0f
#af93#4813213/8
28 0d 
    jr z, Lafa2_player_ship_keyboard_control_altitude  ; do not go beyond map borders
#af95#4815317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#af98#481815
47 
    ld b, a
#af99#4819318
cd 52 b0 
    call Lb052_check_player_collision
#af9c#481c213/8
38 04 
    jr c, Lafa2_player_ship_keyboard_control_altitude  ; collision
#af9e#481e15
78 
    ld a, b
#af9f#481f314
32 0d fd 
    ld (Lfd0d_player_y), a
#afa2#4822
#afa2#4822
Lafa2_player_ship_keyboard_control_altitude:
#afa2#4822314
3a 30 fd 
    ld a, (Lfd30_player_elevate_timer)
#afa5#482515
b7 
    or a
#afa6#4826213/8
28 06 
    jr z, Lafae_no_auto_elevate
#afa8#482815
3d 
    dec a
#afa9#4829314
32 30 fd 
    ld (Lfd30_player_elevate_timer), a
#afac#482c213
18 07 
    jr Lafb5_elevate
#afae#482e
Lafae_no_auto_elevate:
#afae#482e314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#afb1#483128
e6 10 
    and #10
#afb3#4833213/8
28 0e 
    jr z, Lafc3_gravity
#afb5#4835
Lafb5_elevate:
#afb5#4835314
3a 10 fd 
    ld a, (Lfd10_player_altitude)
#afb8#483828
fe 30 
    cp MAX_PLAYER_ALTITUDE
#afba#483a213/8
30 1f 
    jr nc, Lafdb_continue
#afbc#483c28
c6 02 
    add a, 2
#afbe#483e314
32 10 fd 
    ld (Lfd10_player_altitude), a
#afc1#4841213
18 18 
    jr Lafdb_continue
#afc3#4843
#afc3#4843
Lafc3_gravity:
#afc3#4843314
3a 10 fd 
    ld a, (Lfd10_player_altitude)
#afc6#484615
3d 
    dec a  ; Player ship falls with gravity
#afc7#4847311
fa db af 
    jp m, Lafdb_continue
#afca#484a15
47 
    ld b, a
#afcb#484b314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#afce#484e317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#afd1#4851318
cd 52 b0 
    call Lb052_check_player_collision
#afd4#485415
78 
    ld a, b
#afd5#485515
b9 
    cp c
#afd6#4856213/8
38 03 
    jr c, Lafdb_continue  ; collision when going down
#afd8#4858314
32 10 fd 
    ld (Lfd10_player_altitude), a
#afdb#485b
#afdb#485b
Lafdb_continue:
#afdb#485b318
cd e6 af 
    call Lafe6_radar_scroll
#afde#485e311
21 1e fd 
    ld hl, Lfd1e_player_visible_in_radar  ; Potential optimization: are these last lines needed? (
#afe1#4861
                                          ; this is already done in "Lb048_update_radar" each 
#afe1#4861
                                          ; cycle, so, maybe this just does even more blinking).
#afe1#4861112
34 
    inc (hl)
#afe2#4862318
cd 24 b0 
    call Lb024_add_player_to_map_and_update_radar  ; Potential optimization: tail recursion.
#afe5#4865111
c9 
    ret
#afe6#4866
#afe6#4866
#afe6#4866
; --------------------------------
#afe6#4866
; Check if we need to scroll the radar screen due to player movement.
#afe6#4866
Lafe6_radar_scroll:
#afe6#4866317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#afe9#4869314
3a 1b fd 
    ld a, (Lfd1b_radar_scroll_x_tile)
#afec#486c15
4f 
    ld c, a
#afed#486d15
7d 
    ld a, l
#afee#486e210
cb 1c 
    rr h
#aff0#487015
1f 
    rra
#aff1#4871210
cb 3f 
    srl a
#aff3#4873210
cb 3f 
    srl a  ; a = (Lfd0e_player_x) / 8
#aff5#487515
91 
    sub c  ; c = (Lfd0e_player_x) / 8 - (Lfd1b_radar_scroll_x_tile)
#aff6#487628
fe 02 
    cp 2  ; if we are in the left-edge, scroll left
#aff8#4878213/8
38 05 
    jr c, Lafff_radar_scroll_left
#affa#487a28
fe 0e 
    cp 14  ; if we are in the right-edge, scroll right
#affc#487c213/8
30 07 
    jr nc, Lb005_radar_scroll_right
#affe#487e111
c9 
    ret
#afff#487f
Lafff_radar_scroll_left:
#afff#487f15
79 
    ld a, c
#b000#488028
d6 08 
    sub 8
#b002#4882112/6
f8 
    ret m
#b003#4883213
18 06 
    jr Lb00b_update_radar_scroll
#b005#4885
Lb005_radar_scroll_right:
#b005#488515
79 
    ld a, c
#b006#488628
c6 08 
    add a, 8
#b008#488828
fe 38 
    cp 56
#b00a#488a112/6
c8 
    ret z
#b00b#488b
Lb00b_update_radar_scroll:
#b00b#488b314
32 1b fd 
    ld (Lfd1b_radar_scroll_x_tile), a
#b00e#488e15
87 
    add a, a
#b00f#488f15
87 
    add a, a
#b010#489015
6f 
    ld l, a
#b011#489128
26 00 
    ld h, 0
#b013#4893112
29 
    add hl, hl
#b014#4894317
22 1c fd 
    ld (Lfd1c_radar_scroll_x), hl
#b017#489728
3e 01 
    ld a, 1
#b019#4899314
32 52 fd 
    ld (Lfd52_update_radar_buffer_signal), a
#b01c#489c111
c9 
    ret
#b01d#489d
#b01d#489d
#b01d#489d
; --------------------------------
#b01d#489d
; Removes the player from the map (bit 7), and then draws the player in the radar view.
#b01d#489d
Lb01d_remove_player_from_map:
#b01d#489d318
cd a0 cc 
    call Lcca0_compute_player_map_ptr
#b020#48a0217
cb be 
    res 7, (hl)  ; mark player is no longer here
#b022#48a2213
18 12 
    jr Lb036_flicker_player_in_radar
#b024#48a4
#b024#48a4
#b024#48a4
; --------------------------------
#b024#48a4
; Marks that the player is in the map (bit 7), and
#b024#48a4
; also updates the radar buffers with buildings/robots and player.
#b024#48a4
Lb024_add_player_to_map_and_update_radar:
#b024#48a4318
cd a0 cc 
    call Lcca0_compute_player_map_ptr
#b027#48a7217
cb fe 
    set 7, (hl)  ; mark player is here
#b029#48a9
Lb029_update_radar_view_if_necessary:
#b029#48a9
    ; Update the radar view if necessary:
#b029#48a9314
3a 52 fd 
    ld a, (Lfd52_update_radar_buffer_signal)
#b02c#48ac15
b7 
    or a
#b02d#48ad213/8
28 07 
    jr z, Lb036_flicker_player_in_radar
#b02f#48af318
cd f8 d5 
    call Ld5f8_update_radar_buffers
#b032#48b215
af 
    xor a
#b033#48b3314
32 52 fd 
    ld (Lfd52_update_radar_buffer_signal), a
#b036#48b6
Lb036_flicker_player_in_radar:
#b036#48b6314
3a 1e fd 
    ld a, (Lfd1e_player_visible_in_radar)
#b039#48b928
e6 01 
    and 1
#b03b#48bb112/6
c8 
    ret z  ; Do not draw player in radar
#b03c#48bc317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#b03f#48bf314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#b042#48c215
4f 
    ld c, a
#b043#48c328
06 00 
    ld b, 0
#b045#48c5311
c3 5a d6 
    jp Ld65a_flip_2x2_radar_area
#b048#48c8
#b048#48c8
#b048#48c8
; --------------------------------
#b048#48c8
; Increments whether the player is visible in the radar or not, and updates the radar.
#b048#48c8
Lb048_update_radar:
#b048#48c8318
cd 36 b0 
    call Lb036_flicker_player_in_radar
#b04b#48cb311
21 1e fd 
    ld hl, Lfd1e_player_visible_in_radar
#b04e#48ce112
34 
    inc (hl)
#b04f#48cf311
c3 29 b0 
    jp Lb029_update_radar_view_if_necessary
#b052#48d2
#b052#48d2
#b052#48d2
; --------------------------------
#b052#48d2
; Checks whether there would be a collision with the player altitude in a 3x3 area
#b052#48d2
; centered around a given set of coordinates:
#b052#48d2
; Input:
#b052#48d2
; - hl: x
#b052#48d2
; - a: y
#b052#48d2
; Return:
#b052#48d2
; - carry flag: set for collision, unset for no collision.
#b052#48d2
Lb052_check_player_collision:
#b052#48d2112
e5 
    push hl
#b053#48d3318
cd a6 cc 
        call Lcca6_compute_map_ptr
#b056#48d615
eb 
        ex de, hl
#b057#48d728
0e 00 
        ld c, 0
#b059#48d9318
cd 96 b0 
        call Lb096_get_map_altitude_including_robots_and_decorations
#b05c#48dc17
13 
        inc de  ; x += 1
#b05d#48dd318
cd 96 b0 
        call Lb096_get_map_altitude_including_robots_and_decorations
#b060#48e015
15 
        dec d
#b061#48e115
15 
        dec d  ; y -= 1
#b062#48e2318
cd 96 b0 
        call Lb096_get_map_altitude_including_robots_and_decorations
#b065#48e517
1b 
        dec de  ; x -= 1
#b066#48e6318
cd 96 b0 
        call Lb096_get_map_altitude_including_robots_and_decorations
#b069#48e917
1b 
        dec de  ; x -= 1
#b06a#48ea318
cd 99 b0 
        call Lb099_get_robot_or_decoration_altitude
#b06d#48ed15
14 
        inc d
#b06e#48ee15
14 
        inc d  ; y += 1
#b06f#48ef318
cd 99 b0 
        call Lb099_get_robot_or_decoration_altitude
#b072#48f215
14 
        inc d
#b073#48f315
14 
        inc d  ; y += 1
#b074#48f415
7a 
        ld a, d
#b075#48f528
fe fd 
        cp #fd  ; edge of the map
#b077#48f7213/8
30 0b 
        jr nc, Lb084
#b079#48f9318
cd 99 b0 
        call Lb099_get_robot_or_decoration_altitude
#b07c#48fc17
13 
        inc de  ; x += 1
#b07d#48fd318
cd 99 b0 
        call Lb099_get_robot_or_decoration_altitude
#b080#490017
13 
        inc de  ; x += 1
#b081#4901318
cd 99 b0 
        call Lb099_get_robot_or_decoration_altitude
#b084#4904
Lb084:
#b084#4904314
3a 10 fd 
        ld a, (Lfd10_player_altitude)
#b087#490715
b9 
        cp c
#b088#4908111
e1 
    pop hl
#b089#4909111
c9 
    ret
#b08a#490a
#b08a#490a
#b08a#490a
; --------------------------------
#b08a#490a
; Gets the altitude of a position in the map, and if it is higher
#b08a#490a
; than the current of value in "c", it gets updated.
#b08a#490a
; Input:
#b08a#490a
; - de: map pointer
#b08a#490a
; Output:
#b08a#490a
; - a: map altitude
#b08a#490a
; - c: max of "c" and map altitude in "de".
#b08a#490a
Lb08a_get_map_altitude:
#b08a#490a18
1a 
    ld a, (de)
#b08b#490b28
e6 1f 
    and #1f
#b08d#490d311
21 bc d7 
    ld hl, Ld7bc_map_piece_heights
#b090#4910318
cd 51 d3 
    call Ld351_add_hl_a
#b093#491318
7e 
    ld a, (hl)
#b094#4914213
18 15 
    jr Lb0ab_max_of_a_and_c
#b096#4916
#b096#4916
#b096#4916
; --------------------------------
#b096#4916
; Gets the altitude at a particular position, including robots and decorations.
#b096#4916
; Input:
#b096#4916
; - de: map pointer
#b096#4916
; - c: initial altitude
#b096#4916
; Output:
#b096#4916
; - c: max of "c" and map altitude in "de" (including robots and decorations).
#b096#4916
Lb096_get_map_altitude_including_robots_and_decorations:
#b096#4916318
cd 8a b0 
    call Lb08a_get_map_altitude
#b099#4919
Lb099_get_robot_or_decoration_altitude:
#b099#491915
62 
    ld h, d
#b09a#491a15
6b 
    ld l, e
#b09b#491b214
cb 76 
    bit 6, (hl)
#b09d#491d112/6
c8 
    ret z
#b09e#491e112
c5 
    push bc
#b09f#491f318
cd d8 cd 
        call Lcdd8_get_robot_at_ptr
#b0a2#4922213/8
20 0c 
        jr nz, Lb0b0_get_decoration_altitude
#b0a4#4924111
c1 
    pop bc
#b0a5#4925321
fd 7e 09 
    ld a, (iy + ROBOT_STRUCT_HEIGHT)
#b0a8#4928321
fd 86 0d 
    add a, (iy + ROBOT_STRUCT_ALTITUDE)
#b0ab#492b
    ; jp Lb0ab_max_of_a_and_c
#b0ab#492b
#b0ab#492b
#b0ab#492b
; --------------------------------
#b0ab#492b
; c = max(c, a)
#b0ab#492b
Lb0ab_max_of_a_and_c:
#b0ab#492b15
b9 
    cp c
#b0ac#492c213/8
38 01 
    jr c, Lb0af_c_larger
#b0ae#492e15
4f 
    ld c, a
#b0af#492f
Lb0af_c_larger:
#b0af#492f111
c9 
    ret
#b0b0#4930
#b0b0#4930
#b0b0#4930
; --------------------------------
#b0b0#4930
; Gets the altitude of a decoration (like a "flag") if present.
#b0b0#4930
; Input:
#b0b0#4930
; - de: map pointer
#b0b0#4930
; - c: initial altitude
#b0b0#4930
; Output:
#b0b0#4930
; - c: max of "c" and decoration altitude in "de" if present.
#b0b0#4930
Lb0b0_get_decoration_altitude:
#b0b0#4930318
cd f5 cd 
        call Lcdf5_find_building_decoration_with_ptr
#b0b3#4933111
c1 
    pop bc
#b0b4#4934112/6
c0 
    ret nz
#b0b5#4935321
fd 7e 02 
    ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE)
#b0b8#4938311
21 c1 b0 
    ld hl, Lb0c1_decoration_altitudes
#b0bb#493b318
cd 51 d3 
    call Ld351_add_hl_a
#b0be#493e18
7e 
    ld a, (hl)
#b0bf#493f213
18 ea 
    jr Lb0ab_max_of_a_and_c
#b0c1#4941
#b0c1#4941
Lb0c1_decoration_altitudes:
#b0c1#49411
    db #0f  ; warbase "H"
#b0c2#49426
    db #16, #15, #15, #16, #16, #16  ; pieces on top of factories
#b0c8#49482
    db #19, #19  ; flags
#b0ca#494a
#b0ca#494a
#b0ca#494a
; --------------------------------
#b0ca#494a
; Executes one update cycle for each robot and bullet in the game.
#b0ca#494a
Lb0ca_update_robots_bullets_and_ai:
#b0ca#494a318
cd f4 b7 
    call Lb7f4_update_enemy_ai
#b0cd#494d28
06 30 
    ld b, MAX_ROBOTS_PER_PLAYER * 2
#b0cf#494f416
fd 21 00 da 
    ld iy, Lda00_player1_robots
#b0d3#4953
Lb0d3_robot_update_loop:
#b0d3#4953112
c5 
    push bc
#b0d4#4954321
fd 7e 01 
        ld a, (iy + 1)
#b0d7#495715
b7 
        or a
#b0d8#4958318/11
c4 fa b0 
        call nz, Lb0fa_robot_update  ; If robot is not destroyed, execute one update cycle
#b0db#495b311
11 10 00 
        ld de, ROBOT_STRUCT_SIZE
#b0de#495e217
fd 19 
        add iy, de
#b0e0#4960111
c1 
    pop bc
#b0e1#4961214/9
10 f0 
    djnz Lb0d3_robot_update_loop
#b0e3#4963416
fd 21 d3 d7 
    ld iy, Ld7d3_bullets
#b0e7#496728
06 05 
    ld b, MAX_BULLETS
#b0e9#4969
Lb0e9_bullet_update_loop:
#b0e9#4969112
c5 
    push bc
#b0ea#496a321
fd 7e 01 
        ld a, (iy + 1)
#b0ed#496d15
b7 
        or a
#b0ee#496e318/11
c4 0d b7 
        call nz, Lb70d_bullet_update  ; If there is a bullet, execute one update cycle
#b0f1#4971311
11 09 00 
        ld de, BULLET_STRUCT_SIZE
#b0f4#4974217
fd 19 
        add iy, de
#b0f6#4976111
c1 
    pop bc
#b0f7#4977214/9
10 f0 
    djnz Lb0e9_bullet_update_loop
#b0f9#4979111
c9 
    ret
#b0fa#497a
#b0fa#497a
#b0fa#497a
; --------------------------------
#b0fa#497a
; Update cycle of a robot, checking if it has to be destroyed or not.
#b0fa#497a
Lb0fa_robot_update:
#b0fa#497a321
fd 7e 0c 
    ld a, (iy + ROBOT_STRUCT_STRENGTH)
#b0fd#497d15
b7 
    or a
#b0fe#497e213/8
28 16 
    jr z, Lb116_robot_destroyed
#b100#4980311
f2 54 b1 
    jp p, Lb154_robot_ai_update
#b103#4983
    ; negative energy: robot is destroyed, so we are just going to make it blink
#b103#4983325
fd 34 0c 
    inc (iy + ROBOT_STRUCT_STRENGTH)
#b106#4986321
fd 6e 00 
    ld l, (iy + ROBOT_STRUCT_MAP_PTR)
#b109#4989321
fd 66 01 
    ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b10c#498c28
e6 01 
    and 1
#b10e#498e213/8
20 03 
    jr nz, Lb113
#b110#4990217
cb b6 
    res 6, (hl)  ; blink out
#b112#4992111
c9 
    ret
#b113#4993
Lb113:
#b113#4993217
cb f6 
    set 6, (hl)  ; blink in
#b115#4995111
c9 
    ret
#b116#4996
Lb116_robot_destroyed:
#b116#4996321
fd 6e 00 
    ld l, (iy + ROBOT_STRUCT_MAP_PTR)
#b119#4999321
fd 66 01 
    ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b11c#499c217
cb b6 
    res 6, (hl)  ; remove the mark in the map
#b11e#499e
    ; Check if there is something in the map or not. If there is nothing in the  map,
#b11e#499e
    ; we will add some random garbage.
#b11e#499e18
7e 
    ld a, (hl)
#b11f#499f17
23 
    inc hl
#b120#49a018
b6 
    or (hl)
#b121#49a115
25 
    dec h
#b122#49a215
25 
    dec h
#b123#49a318
b6 
    or (hl)
#b124#49a417
2b 
    dec hl
#b125#49a518
b6 
    or (hl)
#b126#49a615
24 
    inc h
#b127#49a715
24 
    inc h
#b128#49a828
e6 3f 
    and #3f
#b12a#49aa213/8
20 0a 
    jr nz, Lb136_map_not_empty  ; There is something in the map
#b12c#49ac318
cd 58 d3 
    call Ld358_random
#b12f#49af28
e6 01 
    and 1
#b131#49b128
c6 06 
    add a, 6
#b133#49b3318
cd 91 bd 
    call Lbd91_add_element_to_map  ; Add some debris to the map
#b136#49b6
Lb136_map_not_empty:
#b136#49b6321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b139#49b9321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b13c#49bc321
fd 4e 04 
    ld c, (iy + ROBOT_STRUCT_Y)
#b13f#49bf321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#b142#49c215
07 
    rlca
#b143#49c328
e6 01 
    and 1
#b145#49c515
47 
    ld b, a  ; b = 0 if it's a player robot, and b = 1 if it's an enemy AI robot.
#b146#49c6318
cd 5a d6 
    call Ld65a_flip_2x2_radar_area  ; remove robot out of the map
#b149#49c9421
fd 36 01 00 
    ld (iy + 1), 0  ; mark the robot as removed
#b14d#49cd318
cd 40 bb 
    call Lbb40_count_robots
#b150#49d0318
cd 93 d2 
    call Ld293_update_stats_in_right_hud  ; Potential optimization: tail recursion.
#b153#49d3111
c9 
    ret
#b154#49d4
#b154#49d4
#b154#49d4
; --------------------------------
#b154#49d4
; Update cycle for robots behavior.
#b154#49d4
; Input:
#b154#49d4
; - iy: robot ptr.
#b154#49d4
Lb154_robot_ai_update:
#b154#49d4321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#b157#49d728
fe 01 
    cp ROBOT_CONTROL_PLAYER_LANDED
#b159#49d9112/6
c8 
    ret z  ; If the player has landed on top of the robot, do not update
#b15a#49da
    
#b15a#49da15
07 
    rlca
#b15b#49db28
e6 01 
    and 1
#b15d#49dd314
32 51 fd 
    ld (Lfd51_current_robot_player_or_enemy), a
#b160#49e0325
fd 35 0f 
    dec (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE)
#b163#49e3112/6
c0 
    ret nz  ; if we do not yet need to update this robot, skip
#b164#49e4
#b164#49e4321
fd 6e 00 
    ld l, (iy + ROBOT_STRUCT_MAP_PTR)
#b167#49e7321
fd 66 01 
    ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b16a#49ea217
cb b6 
    res 6, (hl)  ; remove the mark of this robot in the map for now
#b16c#49ec112
e5 
    push hl
#b16d#49ed321
fd 6e 02 
        ld l, (iy + ROBOT_STRUCT_X)
#b170#49f0321
fd 66 03 
        ld h, (iy + ROBOT_STRUCT_X + 1)
#b173#49f3321
fd 4e 04 
        ld c, (iy + ROBOT_STRUCT_Y)
#b176#49f6321
fd 7e 0a 
        ld a, (iy + ROBOT_STRUCT_CONTROL)
#b179#49f915
07 
        rlca
#b17a#49fa28
e6 01 
        and 1
#b17c#49fc15
47 
        ld b, a  ; potential optimization: this was already computed above.
#b17d#49fd318
cd 5a d6 
        call Ld65a_flip_2x2_radar_area
#b180#4a00111
e1 
    pop hl
#b181#4a01318
cd 13 b5 
    call Lb513_get_robot_movement_possibilities
#b184#4a04321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#b187#4a0728
fe 02 
    cp ROBOT_CONTROL_DIRECT_CONTROL
#b189#4a09311
ca 50 b4 
    jp z, Lb450_robot_control_direct_control
#b18c#4a0c112
c5 
    push bc
#b18d#4a0d318
cd 26 b6 
        call Lb626_check_directions_with_enemy_robots
#b190#4a10111
c1 
    pop bc
#b191#4a1115
7b 
    ld a, e
#b192#4a1215
b7 
    or a
#b193#4a13213/8
28 54 
    jr z, Lb1e9_no_enemy_robots_in_sight
#b195#4a15
#b195#4a15321
fd a6 08 
    and (iy + ROBOT_STRUCT_DIRECTION)
#b198#4a18213/8
28 3d 
    jr z, Lb1d7_no_enemy_robots_in_the_current_direction
#b19a#4a1a
    ; If we are here, there is an enemy robot just ahead
#b19a#4a1a15
a1 
    and c
#b19b#4a1b321
fd 77 05 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), a
#b19e#4a1e217
dd e5 
    push ix
#b1a0#4a20217
fd e5 
    push iy
#b1a2#4a22217
fd e5 
        push iy
#b1a4#4a24216
dd e1 
        pop ix
#b1a6#4a26318
cd b8 b6 
        call Lb6b8_find_new_bullet_ptr
#b1a9#4a29213/8
20 22 
        jr nz, Lb1cd_do_not_fire
#b1ab#4a2b318
cd 58 d3 
        call Ld358_random  ; pick one of our weapons at random
#b1ae#4a2e28
e6 38 
        and #38  ; bits corresponding to weapons (cannon, missiles, phaser)
#b1b0#4a30321
dd a6 07 
        and (ix + ROBOT_STRUCT_PIECES)
#b1b3#4a33213/8
28 18 
        jr z, Lb1cd_do_not_fire
#b1b5#4a35
        ; Get the index of the lowest bit in "a" that is 1, corresponding to a weapon piece:
#b1b5#4a3528
0e 06 
        ld c, 6
#b1b7#4a37
Lb1b7:
#b1b7#4a3715
0d 
        dec c
#b1b8#4a3815
07 
        rlca
#b1b9#4a39213/8
30 fc 
        jr nc, Lb1b7
#b1bb#4a3b15
79 
        ld a, c
#b1bc#4a3c318
cd d6 b6 
        call Lb6d6_weapon_fire
#b1bf#4a3f216
fd e1 
    pop iy
#b1c1#4a41216
dd e1 
    pop ix
#b1c3#4a43421
fd 36 05 00 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 0
#b1c7#4a47421
fd 36 06 01 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 1
#b1cb#4a4b213
18 40 
    jr Lb20d_move_robot
#b1cd#4a4d
Lb1cd_do_not_fire:
#b1cd#4a4d216
fd e1 
    pop iy
#b1cf#4a4f216
dd e1 
    pop ix
#b1d1#4a51421
fd 36 06 01 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 1
#b1d5#4a55213
18 36 
    jr Lb20d_move_robot
#b1d7#4a57
Lb1d7_no_enemy_robots_in_the_current_direction:
#b1d7#4a5715
4b 
    ld c, e
#b1d8#4a5815
41 
    ld b, c
#b1d9#4a59318
cd 05 b5 
    call Lb505_check_number_of_directions_is_one
#b1dc#4a5c318/11
c4 3e b3 
    call nz, Lb33e_pick_direction_at_random
#b1df#4a5f321
fd 71 05 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c
#b1e2#4a62421
fd 36 06 02 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 2
#b1e6#4a66311
c3 0d b2 
    jp Lb20d_move_robot
#b1e9#4a69
Lb1e9_no_enemy_robots_in_sight:
#b1e9#4a69325
fd 35 06 
    dec (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING)
#b1ec#4a6c311
fa f5 b1 
    jp m, Lb1f5_move_in_a_new_direction
#b1ef#4a6f321
fd 7e 05 
    ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION)
#b1f2#4a7215
a1 
    and c
#b1f3#4a73213/8
20 18 
    jr nz, Lb20d_move_robot
#b1f5#4a75
Lb1f5_move_in_a_new_direction:
#b1f5#4a75
    ; pick a random number of steps:
#b1f5#4a75318
cd 58 d3 
    call Ld358_random
#b1f8#4a7828
e6 03 
    and 3
#b1fa#4a7a28
c6 03 
    add a, 3
#b1fc#4a7c321
fd 77 06 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a
#b1ff#4a7f318
cd 05 b5 
    call Lb505_check_number_of_directions_is_one
#b202#4a82318/11
d4 22 b2 
    call nc, Lb222_choose_direction_to_move
#b205#4a85321
fd 7e 01 
    ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b208#4a8815
b7 
    or a
#b209#4a89112/6
c8 
    ret z
#b20a#4a8a321
fd 71 05 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c
#b20d#4a8d
#b20d#4a8d
Lb20d_move_robot:
#b20d#4a8d321
fd 7e 05 
    ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION)
#b210#4a90321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b213#4a93321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b216#4a96321
fd 46 04 
    ld b, (iy + ROBOT_STRUCT_Y)
#b219#4a99318
cd 71 b4 
    call Lb471_move_robot_one_step_in_desired_direction
#b21c#4a9c318
cd f3 b5 
    call Lb5f3_determine_speed_based_on_terrain
#b21f#4a9f311
c3 7c cc 
    jp Lcc7c_set_robot_position
#b222#4aa2
#b222#4aa2
#b222#4aa2
; --------------------------------
#b222#4aa2
; Chooses a direction for a robot to move to, considering the orders and target.
#b222#4aa2
; Input:
#b222#4aa2
; - iy: robot ptr.
#b222#4aa2
; - c: one-hot representation of the directions we can to move the robot in.
#b222#4aa2
; Output:
#b222#4aa2
; - c: direction to move.
#b222#4aa2
Lb222_choose_direction_to_move:
#b222#4aa215
41 
    ld b, c
#b223#4aa3321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b226#4aa615
b7 
    or a
#b227#4aa7213/8
20 02 
    jr nz, Lb22b_choose_direction_to_move_continue
#b229#4aa915
4f 
    ld c, a  ; if orders are "stop and defend", just set direction = 0
#b22a#4aaa111
c9 
    ret
#b22b#4aab
#b22b#4aab
Lb22b_choose_direction_to_move_continue:
#b22b#4aab28
fe 03 
    cp ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS
#b22d#4aad311
da 26 b3 
    jp c, Lb326_choose_direction_orders_with_possible_directions
#b230#4ab0213/8
20 57 
    jr nz, Lb289_choose_direction_orders_with_building_targets
#b232#4ab2
#b232#4ab2
    ; Destroy enemy robots orders:
#b232#4ab2321
fd 7e 0e 
    ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b235#4ab515
b7 
    or a
#b236#4ab6311
fa 58 b2 
    jp m, Lb258_find_new_robot_target
#b239#4ab9318
cd f9 b3 
    call Lb3f9_find_orders_target_robot_ptr
#b23c#4abc17
23 
    inc hl
#b23d#4abd18
7e 
    ld a, (hl)
#b23e#4abe15
b7 
    or a
#b23f#4abf213/8
28 17 
    jr z, Lb258_find_new_robot_target  ; if our current target was already destroyed, pick a new one
#b241#4ac117
23 
    inc hl
#b242#4ac218
7e 
    ld a, (hl)
#b243#4ac317
23 
    inc hl
#b244#4ac418
66 
    ld h, (hl)
#b245#4ac515
6f 
    ld l, a  ; hl now is target robot "x"
#b246#4ac6321
fd 5e 02 
    ld e, (iy + ROBOT_STRUCT_X)
#b249#4ac9321
fd 56 03 
    ld d, (iy + ROBOT_STRUCT_X + 1)
#b24c#4acc318
cd ca b3 
    call Lb3ca_distance_from_hl_to_de
#b24f#4acf15
7c 
    ld a, h
#b250#4ad015
b7 
    or a
#b251#4ad1213/8
20 05 
    jr nz, Lb258_find_new_robot_target  ; If robot target is too far, pick a new one.
#b253#4ad315
7d 
    ld a, l
#b254#4ad428
fe 32 
    cp 50
#b256#4ad6213/8
38 15 
    jr c, Lb26d_choose_direction_to_target_robot  ; If robot target is too far, pick a new one.
#b258#4ad8
Lb258_find_new_robot_target:
#b258#4ad8321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b25b#4adb321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b25e#4ade421
fd 36 0e ff 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), #ff
#b262#4ae2112
c5 
    push bc
#b263#4ae3318
cd 1d b4 
        call Lb41d_find_nearest_opponent_robot
#b266#4ae6111
c1 
    pop bc
#b267#4ae7321
fd 72 0e 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d
#b26a#4aea311
ca 3e b3 
    jp z, Lb33e_pick_direction_at_random  ; if no nearest robot, pick a direction at random.
#b26d#4aed
#b26d#4aed
Lb26d_choose_direction_to_target_robot:
#b26d#4aed318
cd f9 b3 
    call Lb3f9_find_orders_target_robot_ptr
#b270#4af017
23 
    inc hl
#b271#4af117
23 
    inc hl
#b272#4af218
5e 
    ld e, (hl)
#b273#4af317
23 
    inc hl
#b274#4af418
56 
    ld d, (hl)  ; "de" now has the target robot "x"
#b275#4af517
23 
    inc hl
#b276#4af6321
fd 7e 04 
    ld a, (iy + ROBOT_STRUCT_Y)
#b279#4af918
96 
    sub (hl)
#b27a#4afa15
47 
    ld b, a  ; "b" now has "y" - "target robot y"
#b27b#4afb321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b27e#4afe321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b281#4b0115
af 
    xor a
#b282#4b02217
ed 52 
    sbc hl, de  ; "hl" now has "x" - "target robot x"
#b284#4b0415
57 
    ld d, a  ; "d" = 0 to indicate same x ("Lb2d5_choose_direction_to_target_coordinates" will 
#b285#4b05
             ; overwrite if they are not).
#b285#4b05213/8
28 55 
    jr z, Lb2dc_choose_direction_to_target_coordinates_x_alread_considered
#b287#4b07213
18 4c 
    jr Lb2d5_choose_direction_to_target_coordinates
#b289#4b09
#b289#4b09
Lb289_choose_direction_orders_with_building_targets:
#b289#4b09
    ; If we are here, orders are to capture/destroy some building.
#b289#4b09318
cd d5 b3 
    call Lb3d5_prepare_robot_order_building_target_search
#b28c#4b0c321
fd 7e 0e 
    ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b28f#4b0f15
47 
    ld b, a
#b290#4b1015
87 
    add a, a
#b291#4b1115
87 
    add a, a
#b292#4b1215
80 
    add a, b  ; a *= BUILDING_STRUCT_SIZE
#b293#4b13318
cd 51 d3 
    call Ld351_add_hl_a  ; hl has the pointer to the target
#b296#4b1618
7e 
    ld a, (hl)
#b297#4b1728
e6 e0 
    and #e0  ; keep just the flags
#b299#4b1915
bb 
    cp e  ; see if the flags match the orders target
#b29a#4b1a213/8
28 1f 
    jr z, Lb2bb_choose_direction_to_target_building
#b29c#4b1c
    ; Pick a new target building:
#b29c#4b1c321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b29f#4b1f112
c5 
    push bc
#b2a0#4b20321
fd 6e 02 
        ld l, (iy + ROBOT_STRUCT_X)
#b2a3#4b23321
fd 66 03 
        ld h, (iy + ROBOT_STRUCT_X + 1)
#b2a6#4b26318
cd 4d b3 
        call Lb34d_find_capture_or_destroy_target
#b2a9#4b29111
c1 
    pop bc
#b2aa#4b2a213/8
20 0c 
    jr nz, Lb2b8_target_found
#b2ac#4b2c
    ; We could not find any target:
#b2ac#4b2c28
0e 00 
    ld c, 0
#b2ae#4b2e422
fd cb 0a 7e 
    bit 7, (iy + ROBOT_STRUCT_CONTROL)
#b2b2#4b32112/6
c8 
    ret z
#b2b3#4b33
    ; if it's an enemy AI controlled robot, switch to targeting player robots:
#b2b3#4b33421
fd 36 0b 03 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS
#b2b7#4b37111
c9 
    ret
#b2b8#4b38
#b2b8#4b38
Lb2b8_target_found:
#b2b8#4b38321
fd 72 0e 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d
#b2bb#4b3b
Lb2bb_choose_direction_to_target_building:
#b2bb#4b3b
    ; Calculate the relative target coordinates:
#b2bb#4b3b17
2b 
    dec hl
#b2bc#4b3c321
fd 7e 04 
    ld a, (iy + ROBOT_STRUCT_Y)
#b2bf#4b3f18
96 
    sub (hl)
#b2c0#4b4015
47 
    ld b, a  ; "b" now has "y" - "target robot y"
#b2c1#4b4117
2b 
    dec hl
#b2c2#4b4218
56 
    ld d, (hl)
#b2c3#4b4317
2b 
    dec hl
#b2c4#4b4418
5e 
    ld e, (hl)
#b2c5#4b45321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b2c8#4b48321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b2cb#4b4b15
af 
    xor a
#b2cc#4b4c217
ed 52 
    sbc hl, de  ; "hl" now has "x" - "target robot x"
#b2ce#4b4e15
57 
    ld d, a  ; "d" = 0 to indicate same x ("Lb2d5_choose_direction_to_target_coordinates" will 
#b2cf#4b4f
             ; overwrite if they are not).
#b2cf#4b4f213/8
28 0b 
    jr z, Lb2dc_choose_direction_to_target_coordinates_x_alread_considered
#b2d1#4b5115
78 
    ld a, b
#b2d2#4b5228
d6 03 
    sub 3
#b2d4#4b5415
47 
    ld b, a
#b2d5#4b55
Lb2d5_choose_direction_to_target_coordinates:
#b2d5#4b55
    ; At this point we have the relative position of the target to the robot in "hl", "b"
#b2d5#4b5515
7c 
    ld a, h
#b2d6#4b5615
0f 
    rrca
#b2d7#4b5728
e6 03 
    and #03  ; a = (h/2) mod 4
#b2d9#4b5928
ee 02 
    xor 2  ; flip the second bit
#b2db#4b5b15
57 
    ld d, a  ; d = 1 if difference in "x" is negative, d = 2 if difference is positive
#b2dc#4b5c
Lb2dc_choose_direction_to_target_coordinates_x_alread_considered:
#b2dc#4b5c15
78 
    ld a, b
#b2dd#4b5d15
b7 
    or a
#b2de#4b5e213/8
28 08 
    jr z, Lb2e8_target_directions_calculated
#b2e0#4b60
    ; different y:
#b2e0#4b60
    ; accumulate in "d" the good directions to go toward the target:
#b2e0#4b6015
0f 
    rrca
#b2e1#4b6115
0f 
    rrca
#b2e2#4b6228
e6 0c 
    and #0c
#b2e4#4b6428
ee 08 
    xor 8
#b2e6#4b6615
b2 
    or d
#b2e7#4b6715
57 
    ld d, a  ; d now has "1"s in the up/down directions pointing toward the target
#b2e8#4b68
Lb2e8_target_directions_calculated:
#b2e8#4b6815
7a 
    ld a, d
#b2e9#4b6915
b7 
    or a
#b2ea#4b6a213/8
20 1a 
    jr nz, Lb306_not_at_target
#b2ec#4b6c
    ; We are at the target position:
#b2ec#4b6c15
4f 
    ld c, a
#b2ed#4b6d321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b2f0#4b7028
fe 04 
    cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES
#b2f2#4b72213/8
38 05 
    jr c, Lb2f9_inconsistent_orders
#b2f4#4b7428
fe 06 
    cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES
#b2f6#4b76311
da 9f b9 
    jp c, Lb99f_fire_nuclear_bomb
#b2f9#4b79
Lb2f9_inconsistent_orders:
#b2f9#4b79
    ; If we reached here, something went wrong (we have orders ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS, 
#b2f9#4b79
    ; but are exactly on target, which is weird, so, just keep moving)
#b2f9#4b79321
fd 7e 08 
    ld a, (iy + ROBOT_STRUCT_DIRECTION)
#b2fc#4b7c28
fe 04 
    cp 4
#b2fe#4b7e112/6
c8 
    ret z
#b2ff#4b7f28
0e 04 
    ld c, 4  ; desired direction is down, and go until collision, then reconsider.
#b301#4b81421
fd 36 06 ff 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), #ff
#b305#4b85111
c9 
    ret
#b306#4b86
Lb306_not_at_target:
#b306#4b86
    ; get the absolute difference of the "x" difference:
#b306#4b8615
7d 
    ld a, l
#b307#4b8715
b7 
    or a
#b308#4b88311
f2 0e b3 
    jp p, Lb30e_x_diff_positive
#b30b#4b8b210
ed 44 
    neg
#b30d#4b8d15
6f 
    ld l, a
#b30e#4b8e
Lb30e_x_diff_positive:
#b30e#4b8e28
fe 08 
    cp 8
#b310#4b9015
41 
    ld b, c
#b311#4b9115
7a 
    ld a, d
#b312#4b92213/8
30 12 
    jr nc, Lb326_choose_direction_orders_with_possible_directions  ; if target is further than 8 
#b314#4b94
                                                                   ; positions away follow the 
#b314#4b94
                                                                   ; target directions.
#b314#4b94
    ; If we are closer than 8 cells (in "x") to the target, we will move at random until reaching 
#b314#4b94
    ; it:
#b314#4b9415
a1 
    and c
#b315#4b95213/8
28 27 
    jr z, Lb33e_pick_direction_at_random  ; if we have no good directions, pick one at random
#b317#4b9715
47 
    ld b, a
#b318#4b9828
e6 03 
    and #03
#b31a#4b9a213/8
28 22 
    jr z, Lb33e_pick_direction_at_random  ; If we cannot go left/right, pick a direction at random.
#b31c#4b9c15
7d 
    ld a, l
#b31d#4b9d15
b7 
    or a
#b31e#4b9e213/8
28 1e 
    jr z, Lb33e_pick_direction_at_random  ; if we are at the same "x", pick a direction at random
#b320#4ba015
3d 
    dec a  ; set the number of steps to keep walking to the distance to the target in "x" - 1
#b321#4ba1321
fd 77 06 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), a
#b324#4ba4213
18 18 
    jr Lb33e_pick_direction_at_random
#b326#4ba6
#b326#4ba6
Lb326_choose_direction_orders_with_possible_directions:
#b326#4ba6
    ; If we are here is that "a" has the good directions to move in.
#b326#4ba628
e6 03 
    and #03
#b328#4ba815
57 
    ld d, a
#b329#4ba928
ee fc 
    xor #fc  ; here we reverse the up/down directions, to try something different if we fail to 
#b32b#4bab
             ; pick a direction.
#b32b#4bab15
5f 
    ld e, a
#b32c#4bac15
79 
    ld a, c  ; c has the possible directions we can move in
#b32d#4bad15
a2 
    and d  ; if stop&defend, a = 0, if it's advance/retreat: a direction compatible with it if 
#b32e#4bae
           ; available.
#b32e#4bae213/8
28 0e 
    jr z, Lb33e_pick_direction_at_random  ; if no direction compatible with orders, pick one at 
#b330#4bb0
                                          ; random.
#b330#4bb0
    ; Otherwise, try twice to pick a direction among the ones that are compatible:
#b330#4bb015
4a 
    ld c, d
#b331#4bb1318
cd 58 d3 
    call Ld358_random
#b334#4bb415
a2 
    and d
#b335#4bb5112/6
c0 
    ret nz  ; first attempt
#b336#4bb6318
cd 58 d3 
    call Ld358_random
#b339#4bb915
a2 
    and d
#b33a#4bba112/6
c0 
    ret nz  ; second attempt
#b33b#4bbb15
78 
    ld a, b  ; b still has the available directions of movement
#b33c#4bbc15
a3 
    and e
#b33d#4bbd15
47 
    ld b, a  ; now b has compatible directions (with up/down flipped). So, we pick one at random 
#b33e#4bbe
             ; from those:
#b33e#4bbe
#b33e#4bbe
Lb33e_pick_direction_at_random:
#b33e#4bbe15
48 
    ld c, b
#b33f#4bbf
    ; keep generating random numbers, and masking with the possible directions,
#b33f#4bbf
    ; until we get just 1 direction, and use it:
#b33f#4bbf
Lb33f_pick_direction_at_random_loop:
#b33f#4bbf318
cd 58 d3 
    call Ld358_random
#b342#4bc215
a1 
    and c
#b343#4bc315
4f 
    ld c, a
#b344#4bc4318
cd 05 b5 
    call Lb505_check_number_of_directions_is_one
#b347#4bc7112/6
c8 
    ret z
#b348#4bc8213/8
30 f5 
    jr nc, Lb33f_pick_direction_at_random_loop
#b34a#4bca15
48 
    ld c, b
#b34b#4bcb213
18 f2 
    jr Lb33f_pick_direction_at_random_loop
#b34d#4bcd
#b34d#4bcd
#b34d#4bcd
; --------------------------------
#b34d#4bcd
; Finds the target for a capture or destroy order. This can be
#b34d#4bcd
; the index of a robot, or the index of a building.
#b34d#4bcd
; Input:
#b34d#4bcd
; - a: orders
#b34d#4bcd
; Output:
#b34d#4bcd
; - d: target.
#b34d#4bcd
; - z: no target found.
#b34d#4bcd
; - nz: target found.
#b34d#4bcd
Lb34d_find_capture_or_destroy_target:
#b34d#4bcd28
fe 03 
    cp ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS
#b34f#4bcf311
ca 1d b4 
    jp z, Lb41d_find_nearest_opponent_robot
#b352#4bd2112
f5 
    push af
#b353#4bd315
08 
        ex af, af'
#b354#4bd4111
f1 
    pop af
#b355#4bd5318
cd 11 b4 
    call Lb411_prepare_nearest_robot_or_building_search_registers
#b358#4bd8318
cd d5 b3 
    call Lb3d5_prepare_robot_order_building_target_search
#b35b#4bdb
Lb35b_building_loop:
#b35b#4bdb18
7e 
    ld a, (hl)
#b35c#4bdc28
e6 e0 
    and #e0
#b35e#4bde15
bb 
    cp e  ; check if they match the order target flags
#b35f#4bdf318/11
cc 6c b3 
    call z, Lb36c_check_if_building_is_available_and_nearest_than_current_nearest
#b362#4be2
    ; next building:
#b362#4be215
7d 
    ld a, l
#b363#4be328
c6 05 
    add a, BUILDING_STRUCT_SIZE
#b365#4be515
6f 
    ld l, a
#b366#4be615
0c 
    inc c
#b367#4be7214/9
10 f2 
    djnz Lb35b_building_loop
#b369#4be915
7a 
    ld a, d  ; d has the nearest building that was available as a target.
#b36a#4bea15
3c 
    inc a  ; check if we found a target (d == #ff means no target found).
#b36b#4beb111
c9 
    ret
#b36c#4bec
#b36c#4bec
#b36c#4bec
; --------------------------------
#b36c#4bec
; Given a building (index "c"), checks to make sure no other robot with the same
#b36c#4bec
; orders as the current robot has that building as its target already. Then, if
#b36c#4bec
; this is not the case, checks to see if this is closer than the previous target
#b36c#4bec
; we had found. IF it is, set this building as the current target.
#b36c#4bec
; Input:
#b36c#4bec
; - a': orders
#b36c#4bec
; - c: current building index
#b36c#4bec
Lb36c_check_if_building_is_available_and_nearest_than_current_nearest:
#b36c#4bec217
fd e5 
    push iy
#b36e#4bee112
c5 
    push bc
#b36f#4bef112
d5 
    push de
#b370#4bf015
08 
            ex af, af'
#b371#4bf115
5f 
                ld e, a  ; retrieve the orders
#b372#4bf215
08 
            ex af, af'
#b373#4bf3
        ; Check if there is already another robot with the same orders, and that
#b373#4bf3
        ; already has this target:
#b373#4bf3
        ; Determine if we are searching over player or enemy robots:
#b373#4bf3416
fd 21 00 da 
        ld iy, Lda00_player1_robots
#b377#4bf7314
3a 51 fd 
        ld a, (Lfd51_current_robot_player_or_enemy)
#b37a#4bfa15
b7 
        or a
#b37b#4bfb213/8
28 04 
        jr z, Lb381_target_robots_ptr_set
#b37d#4bfd416
fd 21 80 db 
        ld iy, Ldb80_player2_robots
#b381#4c01
Lb381_target_robots_ptr_set:
#b381#4c0128
06 18 
        ld b, MAX_ROBOTS_PER_PLAYER
#b383#4c03
Lb383:
#b383#4c03321
fd 7e 01 
        ld a, (iy + 1)
#b386#4c0615
b7 
        or a
#b387#4c07213/8
28 0c 
        jr z, Lb395_next_robot
#b389#4c09321
fd 7e 0b 
        ld a, (iy + ROBOT_STRUCT_ORDERS)
#b38c#4c0c15
bb 
        cp e  ; Check if robot has the same orders
#b38d#4c0d213/8
20 06 
        jr nz, Lb395_next_robot
#b38f#4c0f321
fd 7e 0e 
        ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b392#4c1215
b9 
        cp c  ; check if the other robot already has this building as the target
#b393#4c13213/8
28 19 
        jr z, Lb3ae_skip_building
#b395#4c15
Lb395_next_robot:
#b395#4c15112
d5 
        push de
#b396#4c16311
11 10 00 
            ld de, ROBOT_STRUCT_SIZE
#b399#4c19217
fd 19 
            add iy, de
#b39b#4c1b111
d1 
        pop de
#b39c#4c1c214/9
10 e5 
        djnz Lb383
#b39e#4c1e111
d1 
    pop de
#b39f#4c1f111
c1 
    pop bc
#b3a0#4c20216
fd e1 
    pop iy
#b3a2#4c22
    ; If we reached this point, it means that there is no other robot that has
#b3a2#4c22
    ; this building as its target. See if it's closer than the current closest:
#b3a2#4c22112
e5 
    push hl
#b3a3#4c2317
2b 
        dec hl
#b3a4#4c2417
2b 
        dec hl
#b3a5#4c2518
7e 
        ld a, (hl)
#b3a6#4c2617
2b 
        dec hl
#b3a7#4c2718
6e 
        ld l, (hl)
#b3a8#4c2815
67 
        ld h, a
#b3a9#4c29318
cd b3 b3 
        call Lb3b3_check_if_nearer_than_current_nearest
#b3ac#4c2c111
e1 
    pop hl
#b3ad#4c2d111
c9 
    ret
#b3ae#4c2e
Lb3ae_skip_building:
#b3ae#4c2e111
d1 
    pop de
#b3af#4c2f111
c1 
    pop bc
#b3b0#4c30216
fd e1 
    pop iy
#b3b2#4c32111
c9 
    ret
#b3b3#4c33
#b3b3#4c33
#b3b3#4c33
; --------------------------------
#b3b3#4c33
; Check if the coordinate "hl" (x) is nearer than the current robot
#b3b3#4c33
; believed to be the nearest to the reference robot (only considering "x").
#b3b3#4c33
; Input:
#b3b3#4c33
; - hl: x coordinate to check
#b3b3#4c33
Lb3b3_check_if_nearer_than_current_nearest:
#b3b3#4c33112
e5 
    push hl
#b3b4#4c3415
d9 
    exx
#b3b5#4c35111
e1 
        pop hl
#b3b6#4c36318
cd ca b3 
        call Lb3ca_distance_from_hl_to_de  ; distance from "hl" to reference robot
#b3b9#4c3915
7c 
        ld a, h
#b3ba#4c3a15
b8 
        cp b
#b3bb#4c3b213/8
38 06 
        jr c, Lb3c3_new_closest
#b3bd#4c3d213/8
20 09 
        jr nz, Lb3c8
#b3bf#4c3f15
7d 
        ld a, l
#b3c0#4c4015
b9 
        cp c
#b3c1#4c41213/8
30 05 
        jr nc, Lb3c8
#b3c3#4c43
Lb3c3_new_closest:
#b3c3#4c4315
44 
        ld b, h  ; update the "closest distance"
#b3c4#4c4415
4d 
        ld c, l
#b3c5#4c4515
d9 
    exx
#b3c6#4c4615
51 
    ld d, c  ; update the index of the closest robot
#b3c7#4c47111
c9 
    ret
#b3c8#4c48
Lb3c8:
#b3c8#4c4815
d9 
    exx
#b3c9#4c49111
c9 
    ret
#b3ca#4c4a
#b3ca#4c4a
#b3ca#4c4a
; --------------------------------
#b3ca#4c4a
; Returns the absolute value of |hl - de|.
#b3ca#4c4a
Lb3ca_distance_from_hl_to_de:
#b3ca#4c4a15
af 
    xor a
#b3cb#4c4b217
ed 52 
    sbc hl, de
#b3cd#4c4d112/6
f0 
    ret p
#b3ce#4c4e15
95 
    sub l
#b3cf#4c4f15
6f 
    ld l, a
#b3d0#4c5028
3e 00 
    ld a, 0
#b3d2#4c5215
9c 
    sbc a, h
#b3d3#4c5315
67 
    ld h, a
#b3d4#4c54111
c9 
    ret
#b3d5#4c55
#b3d5#4c55
#b3d5#4c55
; --------------------------------
#b3d5#4c55
; Given the orders of the current robot, prepares the registers to look for a potential
#b3d5#4c55
; target.
#b3d5#4c55
; Input:
#b3d5#4c55
; - a: robot orders
#b3d5#4c55
; Output:
#b3d5#4c55
; - hl: ptr to factories or warbases
#b3d5#4c55
; - b: # buildings to search 
#b3d5#4c55
; - e: target flags (whether we are looking for friendly, enemy or neutral buildings).
#b3d5#4c55
Lb3d5_prepare_robot_order_building_target_search:
#b3d5#4c55311
21 87 fd 
    ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE
#b3d8#4c5828
06 18 
    ld b, N_FACTORIES
#b3da#4c5a28
fe 05 
    cp ROBOT_ORDERS_DESTROY_ENEMY_WARBASES
#b3dc#4c5c213/8
28 04 
    jr z, Lb3e2_look_for_a_warbase
#b3de#4c5e28
fe 08 
    cp ROBOT_ORDERS_CAPTURE_ENEMY_WARBASES
#b3e0#4c60213/8
20 05 
    jr nz, Lb3e7_continue
#b3e2#4c62
Lb3e2_look_for_a_warbase:
#b3e2#4c62311
21 73 fd 
    ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE
#b3e5#4c6528
06 04 
    ld b, N_WARBASES
#b3e7#4c67
Lb3e7_continue:
#b3e7#4c6728
1e 20 
    ld e, #20  ; bit 5 (indicates enemy)
#b3e9#4c69112
f5 
    push af
#b3ea#4c6a314
3a 51 fd 
        ld a, (Lfd51_current_robot_player_or_enemy)
#b3ed#4c6d15
b7 
        or a
#b3ee#4c6e213/8
28 02 
        jr z, Lb3f2_player
#b3f0#4c70210
cb 03 
        rlc e  ; changes to bit 6 (indicates player)
#b3f2#4c72
Lb3f2_player:
#b3f2#4c72111
f1 
    pop af
#b3f3#4c7328
fe 06 
    cp ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES
#b3f5#4c75112/6
c0 
    ret nz
#b3f6#4c7628
1e 00 
    ld e, 0  ; if we are looking for neutral buildings, set e to 0 (neither player nor enemy)
#b3f8#4c78111
c9 
    ret
#b3f9#4c79
#b3f9#4c79
#b3f9#4c79
; --------------------------------
#b3f9#4c79
; Gets the target robot index, based on the orders argument.
#b3f9#4c79
; Input:
#b3f9#4c79
; - iy: robot
#b3f9#4c79
; Output:
#b3f9#4c79
; - hl: ptr to target robot
#b3f9#4c79
Lb3f9_find_orders_target_robot_ptr:
#b3f9#4c79311
11 00 da 
    ld de, Lda00_player1_robots
#b3fc#4c7c314
3a 51 fd 
    ld a, (Lfd51_current_robot_player_or_enemy)
#b3ff#4c7f15
b7 
    or a
#b400#4c80213/8
20 03 
    jr nz, Lb405_target_is_player_1
#b402#4c82311
11 80 db 
    ld de, Ldb80_player2_robots
#b405#4c85
Lb405_target_is_player_1:
#b405#4c85321
fd 7e 0e 
    ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b408#4c8815
87 
    add a, a
#b409#4c8915
87 
    add a, a
#b40a#4c8a15
87 
    add a, a
#b40b#4c8b15
6f 
    ld l, a
#b40c#4c8c28
26 00 
    ld h, 0
#b40e#4c8e112
29 
    add hl, hl
#b40f#4c8f112
19 
    add hl, de  ; hl = Lda00_player1/2_robots + ROBOT_STRUCT_SIZE * argument
#b410#4c90111
c9 
    ret
#b411#4c91
#b411#4c91
#b411#4c91
; --------------------------------
#b411#4c91
; Initializes some ghost registers for preparing to find the "closest" robot/building.
#b411#4c91
; - Copies "hl" to "de'" (x of the reference robot)
#b411#4c91
; - set "bc'" = 8192 (min distance)
#b411#4c91
; - c = 0  ; current robot/building we are checking
#b411#4c91
; - d = #ff  ; will store the index of the closest robot/building
#b411#4c91
Lb411_prepare_nearest_robot_or_building_search_registers:
#b411#4c91112
e5 
    push hl
#b412#4c9215
d9 
    exx
#b413#4c93111
d1 
        pop de
#b414#4c94311
01 00 20 
        ld bc, 8192
#b417#4c9715
d9 
    exx
#b418#4c9828
0e 00 
    ld c, 0
#b41a#4c9a28
16 ff 
    ld d, #ff
#b41c#4c9c111
c9 
    ret
#b41d#4c9d
#b41d#4c9d
#b41d#4c9d
; --------------------------------
#b41d#4c9d
; Finds the opponent robot that is nearest to the current robot.
#b41d#4c9d
; Input:
#b41d#4c9d
; - iy: current robot ptr.
#b41d#4c9d
; Output:
#b41d#4c9d
; - d: nearest robot index.
#b41d#4c9d
; - z: no nearest robot.
#b41d#4c9d
; - nz: some nearest robot found.
#b41d#4c9d
Lb41d_find_nearest_opponent_robot:
#b41d#4c9d318
cd 11 b4 
    call Lb411_prepare_nearest_robot_or_building_search_registers
#b420#4ca0217
fd e5 
    push iy
#b422#4ca2
        ; Choose either "Lda00_player1_robots" or "Ldb80_player2_robots", 
#b422#4ca2
        ; depending on whether the current robot belongs to player or enemy AI.
#b422#4ca2416
fd 21 00 da 
        ld iy, Lda00_player1_robots  ; if current robot is enemy, search through 
#b426#4ca6
                                     ; "Lda00_player1_robots"
#b426#4ca6314
3a 51 fd 
        ld a, (Lfd51_current_robot_player_or_enemy)
#b429#4ca915
b7 
        or a
#b42a#4caa213/8
20 04 
        jr nz, Lb430
#b42c#4cac416
fd 21 80 db 
        ld iy, Ldb80_player2_robots  ; if current robot is player, search through 
#b430#4cb0
                                     ; "Lda00_player2_robots"
#b430#4cb0
Lb430:
#b430#4cb028
06 18 
        ld b, MAX_ROBOTS_PER_PLAYER
#b432#4cb2
Lb432_loop_robot:
#b432#4cb2321
fd 7e 01 
        ld a, (iy + 1)
#b435#4cb515
b7 
        or a
#b436#4cb6213/8
28 09 
        jr z, Lb441_next_robot
#b438#4cb8321
fd 6e 02 
        ld l, (iy + ROBOT_STRUCT_X)
#b43b#4cbb321
fd 66 03 
        ld h, (iy + ROBOT_STRUCT_X + 1)
#b43e#4cbe318
cd b3 b3 
        call Lb3b3_check_if_nearer_than_current_nearest
#b441#4cc1
Lb441_next_robot:
#b441#4cc1112
d5 
        push de
#b442#4cc2311
11 10 00 
            ld de, ROBOT_STRUCT_SIZE
#b445#4cc5217
fd 19 
            add iy, de
#b447#4cc7111
d1 
        pop de
#b448#4cc815
0c 
        inc c  ; next robot index
#b449#4cc9214/9
10 e7 
        djnz Lb432_loop_robot
#b44b#4ccb216
fd e1 
    pop iy
#b44d#4ccd15
7a 
    ld a, d
#b44e#4cce15
3c 
    inc a
#b44f#4ccf111
c9 
    ret
#b450#4cd0
#b450#4cd0
#b450#4cd0
; --------------------------------
#b450#4cd0
; Updates a robot while we are moving it in combat mode.
#b450#4cd0
; Input:
#b450#4cd0
; - iy: robot ptr.
#b450#4cd0
; - c: possible move directions (along which there would be no collision).
#b450#4cd0
Lb450_robot_control_direct_control:
#b450#4cd0112
c5 
    push bc
#b451#4cd1318
cd 7c d3 
        call Ld37c_read_keyboard_joystick_input
#b454#4cd4111
c1 
    pop bc
#b455#4cd515
41 
    ld b, c
#b456#4cd6321
fd be 08 
    cp (iy + ROBOT_STRUCT_DIRECTION)
#b459#4cd9
    ; Since when we are requesting the robot to turn, collisions do not matter, we do not filter
#b459#4cd9
    ; by collisions:
#b459#4cd9213/8
20 01 
    jr nz, Lb45c_keyboard_input_different_from_current_robot_direction
#b45b#4cdb15
a1 
    and c  ; we filter keyboard input keys by those directions we can actually move the robot in.
#b45c#4cdc
Lb45c_keyboard_input_different_from_current_robot_direction:
#b45c#4cdc15
4f 
    ld c, a  ; "c" now has the directions we want to move the robot towards, and are possible.
#b45d#4cdd318
cd 05 b5 
    call Lb505_check_number_of_directions_is_one
#b460#4ce0213/8
28 05 
    jr z, Lb467_only_one_direction
#b462#4ce2321
fd 7e 05 
    ld a, (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION)  ; get the current desired direction
#b465#4ce515
a0 
    and b  ; "b" still had the possible move directions.
#b466#4ce615
4f 
    ld c, a  ; if we can still move in the desired, keep moving, otherwise, stop.
#b467#4ce7
Lb467_only_one_direction:
#b467#4ce7321
fd 71 05 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), c
#b46a#4cea15
79 
    ld a, c
#b46b#4ceb314
32 0c fd 
    ld (Lfd0c_keyboard_state), a  ; overwrite the keyboard state with the filtered direction
#b46e#4cee311
c3 0d b2 
    jp Lb20d_move_robot
#b471#4cf1
#b471#4cf1
#b471#4cf1
; --------------------------------
#b471#4cf1
; Moves the robot one step in the desired direction (if currently facing it), or rotates it if
#b471#4cf1
; needed.
#b471#4cf1
; Input:
#b471#4cf1
; - a: robot desired move direction.
#b471#4cf1
Lb471_move_robot_one_step_in_desired_direction:
#b471#4cf115
b7 
    or a
#b472#4cf2112/6
c8 
    ret z  ; If robot does not want to move, return.
#b473#4cf3321
fd be 08 
    cp (iy + ROBOT_STRUCT_DIRECTION)
#b476#4cf6213/8
28 1d 
    jr z, Lb495  ; if robot is facing the right direction, just move
#b478#4cf8
    ; rotate robot:
#b478#4cf815
4f 
    ld c, a
#b479#4cf9321
fd b6 08 
    or (iy + ROBOT_STRUCT_DIRECTION)
#b47c#4cfc28
fe 03 
    cp #03
#b47e#4cfe213/8
20 06 
    jr nz, Lb486
#b480#4d00210
cb 01 
    rlc c  ; because of the way they organized the direction bits, to rotate 90 degrees, we need to 
#b482#4d02
           ; shift the bits w positions. Potential optimization: all the direction code can be 
#b482#4d02
           ; greatly simplified if direction bits are reordered.
#b482#4d02210
cb 01 
    rlc c
#b484#4d04213
18 08 
    jr Lb48e_new_direction_calculated
#b486#4d06
Lb486:
#b486#4d0628
fe 0c 
    cp #0c
#b488#4d08213/8
20 04 
    jr nz, Lb48e_new_direction_calculated
#b48a#4d0a210
cb 09 
    rrc c  ; because of the way they organized the direction bits, to rotate 90 degrees, we need to 
#b48c#4d0c
           ; shift the bits w positions
#b48c#4d0c210
cb 09 
    rrc c
#b48e#4d0e
Lb48e_new_direction_calculated:
#b48e#4d0e
    ; We now have the new robot direction:
#b48e#4d0e321
fd 71 08 
    ld (iy + ROBOT_STRUCT_DIRECTION), c
#b491#4d11325
fd 34 06 
    inc (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING)  ; since this was not a move, it does 
#b494#4d14
                                                             ; not count toward the # of steps we 
#b494#4d14
                                                             ; want to move.
#b494#4d14111
c9 
    ret
#b495#4d15
Lb495:
#b495#4d15
    ; Make the robot actually advance:
#b495#4d15318
cd b9 b4 
    call Lb4b9_robot_advance
#b498#4d18318
cd d6 b5 
    call Lb5d6_map_altitude_2x2
#b49b#4d1b321
fd 77 0d 
    ld (iy + ROBOT_STRUCT_ALTITUDE), a
#b49e#4d1e321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)  ; update the altitude of the robot based on the terrain 
#b4a1#4d21
                                       ; underneath.
#b4a1#4d2128
fe 02 
    cp ROBOT_CONTROL_DIRECT_CONTROL
#b4a3#4d23112/6
c0 
    ret nz
#b4a4#4d24
    ; If we are here it means the player is controlling the robot directly.
#b4a4#4d24112
c5 
    push bc
#b4a5#4d25112
e5 
    push hl
#b4a6#4d26217
fd e5 
    push iy
#b4a8#4d28
        ; This just has the effect of making the player mimic the robot movement:
#b4a8#4d28318/11
cc 11 af 
        call z, Laf11_player_ship_keyboard_control  ; Potential optimization: (not really an 
#b4ab#4d2b
                                                    ; optimization), the "z," is not needed.
#b4ab#4d2b216
fd e1 
    pop iy
#b4ad#4d2d111
e1 
    pop hl
#b4ae#4d2e111
c1 
    pop bc
#b4af#4d2f321
fd 7e 09 
    ld a, (iy + ROBOT_STRUCT_HEIGHT)
#b4b2#4d32321
fd 86 0d 
    add a, (iy + ROBOT_STRUCT_ALTITUDE)
#b4b5#4d35314
32 10 fd 
    ld (Lfd10_player_altitude), a
#b4b8#4d38111
c9 
    ret
#b4b9#4d39
#b4b9#4d39
#b4b9#4d39
; --------------------------------
#b4b9#4d39
; Moves a robot in the direction it wants to move, and update the
#b4b9#4d39
; order parameters in case they were advance or retreat.
#b4b9#4d39
; Input:
#b4b9#4d39
; - a: desired move direction (one-hot encoding)
#b4b9#4d39
Lb4b9_robot_advance:
#b4b9#4d3915
0f 
    rrca
#b4ba#4d3a213/8
30 0b 
    jr nc, Lb4c7_not_right
#b4bc#4d3c
    ; move right:
#b4bc#4d3c17
23 
    inc hl
#b4bd#4d3d321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b4c0#4d4015
3d 
    dec a
#b4c1#4d41213/8
28 2f 
    jr z, Lb4f2_advance_in_direction_of_orders
#b4c3#4d4315
3d 
    dec a
#b4c4#4d44213/8
28 18 
    jr z, Lb4de_advance_against_direction_of_orders
#b4c6#4d46111
c9 
    ret
#b4c7#4d47
#b4c7#4d47
Lb4c7_not_right:
#b4c7#4d4715
0f 
    rrca
#b4c8#4d48213/8
30 0b 
    jr nc, Lb4d5_not_left
#b4ca#4d4a
    ; move left:
#b4ca#4d4a17
2b 
    dec hl
#b4cb#4d4b321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b4ce#4d4e15
3d 
    dec a
#b4cf#4d4f213/8
28 0d 
    jr z, Lb4de_advance_against_direction_of_orders
#b4d1#4d5115
3d 
    dec a
#b4d2#4d52213/8
28 1e 
    jr z, Lb4f2_advance_in_direction_of_orders
#b4d4#4d54111
c9 
    ret
#b4d5#4d55
#b4d5#4d55
Lb4d5_not_left:
#b4d5#4d5515
0f 
    rrca
#b4d6#4d56213/8
30 02 
    jr nc, Lb4da_not_down
#b4d8#4d58
    ; move down:
#b4d8#4d5815
04 
    inc b
#b4d9#4d59111
c9 
    ret
#b4da#4d5a
#b4da#4d5a
Lb4da_not_down:
#b4da#4d5a15
0f 
    rrca
#b4db#4d5b112/6
d0 
    ret nc
#b4dc#4d5c
    ; move up:
#b4dc#4d5c15
05 
    dec b
#b4dd#4d5d111
c9 
    ret
#b4de#4d5e
#b4de#4d5e
Lb4de_advance_against_direction_of_orders:
#b4de#4d5e
    ; The robot moved against the direction it wants to go (e.g., its orders
#b4de#4d5e
    ; were "retreat", but it moved to the right). So, we increment the argument
#b4de#4d5e
    ; of the orders to compensate:
#b4de#4d5e321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#b4e1#4d6128
fe 02 
    cp ROBOT_CONTROL_DIRECT_CONTROL
#b4e3#4d63112/6
c8 
    ret z
#b4e4#4d64325
fd 34 0e 
    inc (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b4e7#4d67321
fd 7e 0e 
    ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b4ea#4d6a28
fe 64 
    cp 100
#b4ec#4d6c112/6
d8 
    ret c  ; do not go beyond 99 in the distance to travel.
#b4ed#4d6d421
fd 36 0e 63 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 99
#b4f1#4d71111
c9 
    ret
#b4f2#4d72
#b4f2#4d72
Lb4f2_advance_in_direction_of_orders:
#b4f2#4d72
    ; The robot moved towards the direction it wants to go (e.g., its orders
#b4f2#4d72
    ; were "retreat", and it moved to the left). So, we decrement the argument
#b4f2#4d72
    ; of the orders to compensate:
#b4f2#4d72321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#b4f5#4d7528
fe 02 
    cp ROBOT_CONTROL_DIRECT_CONTROL
#b4f7#4d77112/6
c8 
    ret z
#b4f8#4d78325
fd 35 0e 
    dec (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b4fb#4d7b112/6
c0 
    ret nz
#b4fc#4d7c
    ; When the robot advances/retreats the desired number of miles, 
#b4fc#4d7c
    ; switch to "stop & defend":
#b4fc#4d7c421
fd 36 0b 00 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND
#b500#4d80421
fd 36 06 00 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 0
#b504#4d84111
c9 
    ret
#b505#4d85
#b505#4d85
#b505#4d85
; --------------------------------
#b505#4d85
; Counts the number of bits in the lower nibble of "c" that are set to 1, and checks
#b505#4d85
; if there is only 1 such bit on.
#b505#4d85
; Input: 
#b505#4d85
; - c: one-hot representation of the directions we want to move the robot in.
#b505#4d85
Lb505_check_number_of_directions_is_one:
#b505#4d85
Lb505_count_number_of_active_bits_in_the_lower_nibble:
#b505#4d85112
c5 
    push bc
#b506#4d8628
06 04 
        ld b, 4  ; only consider the lower 4 bis
#b508#4d8815
af 
        xor a
#b509#4d89
Lb509_direction_loop:
#b509#4d89210
cb 19 
        rr c
#b50b#4d8b28
ce 00 
        adc a, 0  ; if the bit was set, increment a, otherwise do not increment.
#b50d#4d8d214/9
10 fa 
        djnz Lb509_direction_loop
#b50f#4d8f111
c1 
    pop bc
#b510#4d9028
fe 01 
    cp 1  ; check that the number of bits set to 1 was just 1.
#b512#4d92111
c9 
    ret
#b513#4d93
#b513#4d93
#b513#4d93
; --------------------------------
#b513#4d93
; Checks which directions can a robot move in, and in which it will collide.
#b513#4d93
; Input:
#b513#4d93
; - iy: robot ptr.
#b513#4d93
; Output:
#b513#4d93
; - c: lower 4 bits indicate if robot can move right, left, up, down.
#b513#4d93
Lb513_get_robot_movement_possibilities:
#b513#4d9328
0e 00 
    ld c, 0
#b515#4d95
    ; Check if the player is above or below robot height, to see if the player
#b515#4d95
    ; is an obstacle or not.
#b515#4d95314
3a 10 fd 
    ld a, (Lfd10_player_altitude)
#b518#4d98321
fd 96 09 
    sub (iy + ROBOT_STRUCT_HEIGHT)
#b51b#4d9b321
fd 96 0d 
    sub (iy + ROBOT_STRUCT_ALTITUDE)
#b51e#4d9e28
e6 80 
    and 128  ; If the player is lower than the robot height, player is also an obstable
#b520#4da028
f6 40 
    or #40
#b522#4da215
5f 
    ld e, a  ; e contains a mask to check if a given position in the map is not walkable due to 
#b523#4da3
             ; player or another robot.
#b523#4da3321
fd 7e 07 
    ld a, (iy + ROBOT_STRUCT_PIECES)
#b526#4da628
16 08 
    ld d, 8  ; if chassis is bipod, d = 8
#b528#4da815
0f 
    rrca
#b529#4da9213/8
38 07 
    jr c, Lb532
#b52b#4dab28
16 0c 
    ld d, 12  ; if chassis is tracks, d = 12
#b52d#4dad15
0f 
    rrca
#b52e#4dae213/8
38 02 
    jr c, Lb532
#b530#4db028
16 0f 
    ld d, 15  ; if chassis is antigrav, d = 15
#b532#4db2
Lb532:
#b532#4db2112
e5 
    push hl
#b533#4db3318
cd 57 b5 
        call Lb557_check_robot_collision_inc_x
#b536#4db6111
e1 
    pop hl
#b537#4db7213/8
20 02 
    jr nz, Lb53b_collision_right
#b539#4db9210
cb c1 
    set 0, c  ; mark that we can move to the right
#b53b#4dbb
Lb53b_collision_right:
#b53b#4dbb112
e5 
    push hl
#b53c#4dbc318
cd 6f b5 
        call Lb56f_check_robot_collision_dec_x
#b53f#4dbf111
e1 
    pop hl
#b540#4dc0213/8
20 02 
    jr nz, Lb544_collision_left
#b542#4dc2210
cb c9 
    set 1, c  ; mark that we can move to the left
#b544#4dc4
Lb544_collision_left:
#b544#4dc4112
e5 
    push hl
#b545#4dc5318
cd 8f b5 
        call Lb58f_check_robot_collision_inc_y
#b548#4dc8111
e1 
    pop hl
#b549#4dc9213/8
20 02 
    jr nz, Lb54d_collision_down
#b54b#4dcb210
cb d1 
    set 2, c  ; mark that we can move down
#b54d#4dcd
Lb54d_collision_down:
#b54d#4dcd112
e5 
    push hl
#b54e#4dce318
cd b1 b5 
        call Lb5b1_check_robot_collision_dec_y
#b551#4dd1111
e1 
    pop hl
#b552#4dd2213/8
20 02 
    jr nz, Lb556_up
#b554#4dd4210
cb d9 
    set 3, c  ; mark that we can move up
#b556#4dd6
Lb556_up:
#b556#4dd6111
c9 
    ret
#b557#4dd7
#b557#4dd7
#b557#4dd7
; --------------------------------
#b557#4dd7
; Checks if a robot can walk to the right (incrementing x).
#b557#4dd7
; Input:
#b557#4dd7
; - hl: map pointer
#b557#4dd7
; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk 
#b557#4dd7
;      over).
#b557#4dd7
; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable).
#b557#4dd7
;      But it could be #c0 when the player is lower than the height of the robot in consideration,
#b557#4dd7
;      to consider the player as an obstacle.
#b557#4dd7
Lb557_check_robot_collision_inc_x:
#b557#4dd717
23 
    inc hl
#b558#4dd817
23 
    inc hl  ; x += 2
#b559#4dd915
25 
    dec h
#b55a#4dda15
25 
    dec h  ; y -= 1
#b55b#4ddb318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b55e#4dde112/6
c0 
    ret nz  ; collision
#b55f#4ddf15
24 
    inc h  ; y += 1
#b560#4de015
24 
    inc h
#b561#4de1318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b564#4de4112/6
c0 
    ret nz  ; collision
#b565#4de515
24 
    inc h  ; y += 1
#b566#4de615
24 
    inc h
#b567#4de715
7c 
    ld a, h
#b568#4de828
fe fd 
    cp #fd  ; check if we are out of map bounds
#b56a#4dea213/8
30 5c 
    jr nc, Lb5c8_no_collision
#b56c#4dec18
7e 
    ld a, (hl)
#b56d#4ded15
a3 
    and e
#b56e#4dee111
c9 
    ret
#b56f#4def
#b56f#4def
#b56f#4def
; --------------------------------
#b56f#4def
; Checks if a robot can walk to the left (decrementing x).
#b56f#4def
; Input:
#b56f#4def
; - hl: map pointer
#b56f#4def
; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk 
#b56f#4def
;      over).
#b56f#4def
; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable).
#b56f#4def
;      But it could be #c0 when the player is lower than the height of the robot in consideration,
#b56f#4def
;      to consider the player as an obstacle.
#b56f#4def
Lb56f_check_robot_collision_dec_x:
#b56f#4def15
25 
    dec h  ; y -= 1
#b570#4df015
25 
    dec h
#b571#4df117
2b 
    dec hl  ; x -= 1
#b572#4df2318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b575#4df5112/6
c0 
    ret nz  ; collision
#b576#4df617
2b 
    dec hl  ; x -= 1
#b577#4df718
7e 
    ld a, (hl)
#b578#4df815
a3 
    and e
#b579#4df9112/6
c0 
    ret nz  ; collision
#b57a#4dfa15
24 
    inc h  ; y += 1
#b57b#4dfb15
24 
    inc h
#b57c#4dfc18
7e 
    ld a, (hl)
#b57d#4dfd15
a3 
    and e
#b57e#4dfe112/6
c0 
    ret nz  ; collision
#b57f#4dff17
23 
    inc hl  ; x += 1
#b580#4e00318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b583#4e03112/6
c0 
    ret nz  ; collision
#b584#4e0417
2b 
    dec hl  ; x -= 1
#b585#4e0515
24 
    inc h
#b586#4e0615
24 
    inc h  ; y += 1
#b587#4e0715
7c 
    ld a, h
#b588#4e0828
fe fd 
    cp #fd  ; check if we are out of map bounds
#b58a#4e0a213/8
30 3c 
    jr nc, Lb5c8_no_collision
#b58c#4e0c18
7e 
    ld a, (hl)
#b58d#4e0d15
a3 
    and e
#b58e#4e0e111
c9 
    ret
#b58f#4e0f
#b58f#4e0f
#b58f#4e0f
; --------------------------------
#b58f#4e0f
; Checks if a robot can walk down (incrementing y).
#b58f#4e0f
; Input:
#b58f#4e0f
; - hl: map pointer
#b58f#4e0f
; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk 
#b58f#4e0f
;      over).
#b58f#4e0f
; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable).
#b58f#4e0f
;      But it could be #c0 when the player is lower than the height of the robot in consideration,
#b58f#4e0f
;      to consider the player as an obstacle.
#b58f#4e0f
Lb58f_check_robot_collision_inc_y:
#b58f#4e0f15
24 
    inc h  ; y += 1
#b590#4e1015
24 
    inc h
#b591#4e1115
7c 
    ld a, h
#b592#4e1228
fe fd 
    cp #fd
#b594#4e14213/8
30 34 
    jr nc, Lb5ca_collision  ; check if we are out of map bounds
#b596#4e16318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b599#4e19112/6
c0 
    ret nz
#b59a#4e1a17
23 
    inc hl  ; x += 1
#b59b#4e1b318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b59e#4e1e112/6
c0 
    ret nz
#b59f#4e1f15
24 
    inc h  ; y += 1
#b5a0#4e2015
24 
    inc h
#b5a1#4e2115
7c 
    ld a, h
#b5a2#4e2228
fe fd 
    cp #fd  ; check if we are out of map bounds
#b5a4#4e24213/8
30 22 
    jr nc, Lb5c8_no_collision
#b5a6#4e2618
7e 
    ld a, (hl)
#b5a7#4e2715
a3 
    and e
#b5a8#4e28112/6
c0 
    ret nz
#b5a9#4e2917
2b 
    dec hl  ; x -= 1
#b5aa#4e2a18
7e 
    ld a, (hl)
#b5ab#4e2b15
a3 
    and e
#b5ac#4e2c112/6
c0 
    ret nz
#b5ad#4e2d17
2b 
    dec hl  ; x -= 1
#b5ae#4e2e18
7e 
    ld a, (hl)
#b5af#4e2f15
a3 
    and e
#b5b0#4e30111
c9 
    ret
#b5b1#4e31
#b5b1#4e31
#b5b1#4e31
; --------------------------------
#b5b1#4e31
; Checks if a robot can walk up (decrementing y).
#b5b1#4e31
; Input:
#b5b1#4e31
; - hl: map pointer
#b5b1#4e31
; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk 
#b5b1#4e31
;      over).
#b5b1#4e31
; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable).
#b5b1#4e31
;      But it could be #c0 when the player is lower than the height of the robot in consideration,
#b5b1#4e31
;      to consider the player as an obstacle.
#b5b1#4e31
Lb5b1_check_robot_collision_dec_y:
#b5b1#4e3115
25 
    dec h
#b5b2#4e3215
25 
    dec h  ; y -= 1
#b5b3#4e3315
25 
    dec h
#b5b4#4e3415
25 
    dec h  ; y -= 1
#b5b5#4e3515
7c 
    ld a, h
#b5b6#4e3628
fe dd 
    cp #dd  ; check if we are out of map bounds
#b5b8#4e38213/8
38 10 
    jr c, Lb5ca_collision
#b5ba#4e3a17
2b 
    dec hl  ; x -= 1
#b5bb#4e3b18
7e 
    ld a, (hl)
#b5bc#4e3c15
a3 
    and e
#b5bd#4e3d112/6
c0 
    ret nz
#b5be#4e3e17
23 
    inc hl  ; x += 1
#b5bf#4e3f318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b5c2#4e42112/6
c0 
    ret nz
#b5c3#4e4317
23 
    inc hl  ; x += 1
#b5c4#4e44318
cd cd b5 
    call Lb5cd_robot_map_collision_internal
#b5c7#4e47111
c9 
    ret
#b5c8#4e48
Lb5c8_no_collision:
#b5c8#4e4815
af 
    xor a
#b5c9#4e49111
c9 
    ret
#b5ca#4e4a
Lb5ca_collision:
#b5ca#4e4a28
f6 01 
    or 1
#b5cc#4e4c111
c9 
    ret
#b5cd#4e4d
#b5cd#4e4d
#b5cd#4e4d
; --------------------------------
#b5cd#4e4d
; Check if a given position in the map is walkable by the chassis of a robot.
#b5cd#4e4d
; This is checked by seeing if the element in the map is < "d".
#b5cd#4e4d
; Input:
#b5cd#4e4d
; - hl: map pointer
#b5cd#4e4d
; - d: 8 for bipod, 12 for tracks, and 15 for antigrav (the highest map element a robot can walk 
#b5cd#4e4d
;      over).
#b5cd#4e4d
; - e: mask of non-walkable elements (usually just #40 to indicate other robots are not walkable).
#b5cd#4e4d
;      But it could be #c0 when the player is lower than the height of the robot in consideration,
#b5cd#4e4d
;      to consider the player as an obstacle.
#b5cd#4e4d
Lb5cd_robot_map_collision_internal:
#b5cd#4e4d18
7e 
    ld a, (hl)
#b5ce#4e4e28
e6 1f 
    and #1f
#b5d0#4e5015
ba 
    cp d
#b5d1#4e51213/8
30 f7 
    jr nc, Lb5ca_collision  ; map element is not walkable by the current chassis.
#b5d3#4e5318
7e 
    ld a, (hl)
#b5d4#4e5415
a3 
    and e  ; check for objects (robots and potentially the player)
#b5d5#4e55111
c9 
    ret
#b5d6#4e56
#b5d6#4e56
#b5d6#4e56
; --------------------------------
#b5d6#4e56
; Get highest altitude of 2x2 map area:
#b5d6#4e56
; input:
#b5d6#4e56
; - hl: x
#b5d6#4e56
; - b: y
#b5d6#4e56
; Output:
#b5d6#4e56
; - a: altitude
#b5d6#4e56
Lb5d6_map_altitude_2x2:
#b5d6#4e56112
e5 
    push hl
#b5d7#4e57112
c5 
    push bc
#b5d8#4e5815
78 
        ld a, b
#b5d9#4e59318
cd a6 cc 
        call Lcca6_compute_map_ptr
#b5dc#4e5c15
eb 
        ex de, hl
#b5dd#4e5d28
0e 00 
        ld c, 0
#b5df#4e5f318
cd 8a b0 
        call Lb08a_get_map_altitude
#b5e2#4e6217
13 
        inc de
#b5e3#4e63318
cd 8a b0 
        call Lb08a_get_map_altitude
#b5e6#4e6615
15 
        dec d
#b5e7#4e6715
15 
        dec d
#b5e8#4e68318
cd 8a b0 
        call Lb08a_get_map_altitude
#b5eb#4e6b17
1b 
        dec de
#b5ec#4e6c318
cd 8a b0 
        call Lb08a_get_map_altitude
#b5ef#4e6f15
79 
        ld a, c
#b5f0#4e70111
c1 
    pop bc
#b5f1#4e71111
e1 
    pop hl
#b5f2#4e72111
c9 
    ret
#b5f3#4e73
#b5f3#4e73
#b5f3#4e73
; --------------------------------
#b5f3#4e73
; Determines how many cycles will the robot need to take to move
#b5f3#4e73
; depending on the terrain it is on.
#b5f3#4e73
; Input:
#b5f3#4e73
; - iy: robot pointer
#b5f3#4e73
Lb5f3_determine_speed_based_on_terrain:
#b5f3#4e73112
c5 
    push bc
#b5f4#4e74112
e5 
    push hl
#b5f5#4e75321
fd 7e 0d 
        ld a, (iy + ROBOT_STRUCT_ALTITUDE)
#b5f8#4e7828
0e 00 
        ld c, 0  ; flat terrain
#b5fa#4e7a15
b7 
        or a
#b5fb#4e7b213/8
28 08 
        jr z, Lb605_terrain_type_determined
#b5fd#4e7d28
0e 03 
        ld c, 3  ; rugged
#b5ff#4e7f28
fe 04 
        cp 4
#b601#4e81213/8
38 02 
        jr c, Lb605_terrain_type_determined
#b603#4e8328
0e 06 
        ld c, 6  ; mountains
#b605#4e85
Lb605_terrain_type_determined:
#b605#4e85321
fd 7e 07 
        ld a, (iy + ROBOT_STRUCT_PIECES)
#b608#4e8828
16 ff 
        ld d, 255
#b60a#4e8a
Lb60a_determine_chassis_loop:
#b60a#4e8a15
14 
        inc d
#b60b#4e8b15
0f 
        rrca
#b60c#4e8c213/8
30 fc 
        jr nc, Lb60a_determine_chassis_loop
#b60e#4e8e15
79 
        ld a, c
#b60f#4e8f15
82 
        add a, d
#b610#4e90311
21 1d b6 
        ld hl, Lb61d_robot_movement_speed_table
#b613#4e93318
cd 51 d3 
        call Ld351_add_hl_a
#b616#4e9618
7e 
        ld a, (hl)
#b617#4e97321
fd 77 0f 
        ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), a
#b61a#4e9a111
e1 
    pop hl
#b61b#4e9b111
c1 
    pop bc
#b61c#4e9c111
c9 
    ret
#b61d#4e9d
#b61d#4e9d
; How many cycles does the robot take to move in the different terrains,
#b61d#4e9d
; depending on its chassis:
#b61d#4e9d
Lb61d_robot_movement_speed_table:
#b61d#4e9d
    ;  bipod, tracks, anti-grav
#b61d#4e9d3
    db #06, #04, #03  ; flat terrain
#b620#4ea03
    db #08, #06, #03  ; rugged
#b623#4ea33
    db #09, #07, #04  ; mountains
#b626#4ea6
#b626#4ea6
#b626#4ea6
; --------------------------------
#b626#4ea6
; Looks in the 4 cardinal directions to see if in any of them there are enemy robots
#b626#4ea6
; that we could fire at.
#b626#4ea6
; Input:
#b626#4ea6
; - iy: robot ptr.
#b626#4ea6
; Output:
#b626#4ea6
; - e: one-hot representation of the directions where enemy robots can be found.
#b626#4ea6
Lb626_check_directions_with_enemy_robots:
#b626#4ea628
1e 00 
    ld e, 0  ; will accumulate the directions in which there are enemy robots in line.
#b628#4ea828
16 08 
    ld d, 8  ; initial direction (up in a one-hot encoded representation)
#b62a#4eaa
Lb62a_loop_direction:
#b62a#4eaa210
cb 03 
    rlc e
#b62c#4eac321
fd 6e 00 
    ld l, (iy + ROBOT_STRUCT_MAP_PTR)
#b62f#4eaf321
fd 66 01 
    ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b632#4eb228
06 08 
    ld b, 8  ; distance to check in directions we are not facing
#b634#4eb415
7a 
    ld a, d
#b635#4eb5321
fd be 08 
    cp (iy + ROBOT_STRUCT_DIRECTION)
#b638#4eb8213/8
20 2c 
    jr nz, Lb666_simple_check
#b63a#4eba28
06 0a 
    ld b, 10  ; look a bit further in the direction we are facing
#b63c#4ebc422
fd cb 07 7e 
    bit 7, (iy + ROBOT_STRUCT_PIECES)
#b640#4ec0213/8
28 02 
    jr z, Lb644
#b642#4ec228
06 0c 
    ld b, 12  ; if robot has "electronics", it can see a bit further still.
#b644#4ec4
Lb644:
#b644#4ec415
7a 
    ld a, d
#b645#4ec528
e6 03 
    and #03
#b647#4ec7213/8
20 0e 
    jr nz, Lb657
#b649#4ec9
    ; Look along the y axis (left/right):
#b649#4ec915
48 
    ld c, b  ; store the max distance for later
#b64a#4eca17
2b 
    dec hl  ; check with an offset of 1 tile up
#b64b#4ecb318
cd 6e b6 
    call Lb66e_check_if_enemy_robot_in_line
#b64e#4ece15
41 
    ld b, c  ; restore the max distance
#b64f#4ecf17
23 
    inc hl  ; check with no offset
#b650#4ed0318
cd 6e b6 
    call Lb66e_check_if_enemy_robot_in_line
#b653#4ed315
41 
    ld b, c  ; restore the max distance
#b654#4ed417
23 
    inc hl  ; check with an offset of 1 tile down
#b655#4ed5213
18 0f 
    jr Lb666_simple_check
#b657#4ed7
Lb657:
#b657#4ed7
    ; Look along the x axis (up/down):
#b657#4ed715
48 
    ld c, b  ; store the max distance for later
#b658#4ed815
25 
    dec h
#b659#4ed915
25 
    dec h  ; check with an offset of 1 tile left
#b65a#4eda318
cd 6e b6 
    call Lb66e_check_if_enemy_robot_in_line
#b65d#4edd15
41 
    ld b, c  ; restore the max distance
#b65e#4ede15
24 
    inc h  ; check with no offset
#b65f#4edf15
24 
    inc h  ; check with an offset of 1 tile right
#b660#4ee0318
cd 6e b6 
    call Lb66e_check_if_enemy_robot_in_line
#b663#4ee315
41 
    ld b, c  ; restore the max distance
#b664#4ee415
24 
    inc h
#b665#4ee515
24 
    inc h
#b666#4ee6
Lb666_simple_check:
#b666#4ee6
    ; Just check in a straight line without adjusting the offset:
#b666#4ee6318
cd 6e b6 
    call Lb66e_check_if_enemy_robot_in_line
#b669#4ee9210
cb 0a 
    rrc d  ; next direction
#b66b#4eeb213/8
30 bd 
    jr nc, Lb62a_loop_direction
#b66d#4eed111
c9 
    ret
#b66e#4eee
#b66e#4eee
#b66e#4eee
; --------------------------------
#b66e#4eee
; Checks if there is an enemy robot in line with the current robot in the desired direction.
#b66e#4eee
; Basically, to see if we fired a weapon in that direction, if we could hit an enemy robot.
#b66e#4eee
; Input:
#b66e#4eee
; - hl: map ptr.
#b66e#4eee
; - b: maximum distance to check.
#b66e#4eee
; - d: direction (one-hot representation).
#b66e#4eee
; - e: current directions at which we found enemy robots.
#b66e#4eee
; Output:
#b66e#4eee
; - e: updated with whether we found an enemy robot in the current direction.
#b66e#4eee
Lb66e_check_if_enemy_robot_in_line:
#b66e#4eee112
e5 
    push hl
#b66f#4eef112
d5 
        push de
#b670#4ef0112
e5 
            push hl
#b671#4ef1311
21 ae b6 
                ld hl, Lb6b0_direction_offsets - 2
#b674#4ef415
7a 
                ld a, d
#b675#4ef5
                ; get the position from the Lb6b0_direction_offsets array corresponding to the 
#b675#4ef5
                ; one-hot bit in "d", and store it in "de"
#b675#4ef5
Lb675_get_word_loop:
#b675#4ef517
23 
                inc hl
#b676#4ef617
23 
                inc hl
#b677#4ef715
0f 
                rrca
#b678#4ef8213/8
30 fb 
                jr nc, Lb675_get_word_loop
#b67a#4efa18
5e 
                ld e, (hl)
#b67b#4efb17
23 
                inc hl
#b67c#4efc18
56 
                ld d, (hl)
#b67d#4efd111
e1 
            pop hl
#b67e#4efe
            ; Keeps advancing in the desired direction until we get out of the map,
#b67e#4efe
            ; or we find an object.
#b67e#4efe
Lb67e_raycast_loop:
#b67e#4efe112
19 
            add hl, de  ; add the offset to the map ptr.
#b67f#4eff15
7c 
            ld a, h
#b680#4f0028
d6 dd 
            sub #dd
#b682#4f0228
fe 20 
            cp 16 * 2
#b684#4f04213/8
30 27 
            jr nc, Lb6ad_nothing_found  ; out of bounds of the map
#b686#4f06214
cb 76 
            bit 6, (hl)
#b688#4f08213/8
20 04 
            jr nz, Lb68e_object_found  ; object found
#b68a#4f0a214/9
10 f2 
            djnz Lb67e_raycast_loop
#b68c#4f0c213
18 1f 
            jr Lb6ad_nothing_found
#b68e#4f0e
#b68e#4f0e
Lb68e_object_found:
#b68e#4f0e217
fd e5 
            push iy
#b690#4f10318
cd d8 cd 
                call Lcdd8_get_robot_at_ptr
#b693#4f13321
fd 7e 0a 
                ld a, (iy + ROBOT_STRUCT_CONTROL)
#b696#4f16321
fd 46 0c 
                ld b, (iy + ROBOT_STRUCT_STRENGTH)
#b699#4f19216
fd e1 
            pop iy
#b69b#4f1b213/8
20 10 
            jr nz, Lb6ad_nothing_found
#b69d#4f1d321
fd ae 0a 
            xor (iy + ROBOT_STRUCT_CONTROL)
#b6a0#4f20311
f2 ad b6 
            jp p, Lb6ad_nothing_found  ; the robot has the same owner as the current robot.
#b6a3#4f2315
05 
            dec b
#b6a4#4f24311
fa ad b6 
            jp m, Lb6ad_nothing_found  ; the robot is already destroyed
#b6a7#4f27111
d1 
        pop de
#b6a8#4f2815
7b 
        ld a, e
#b6a9#4f2928
f6 01 
        or 1
#b6ab#4f2b15
5f 
        ld e, a  ; potential optimization: these 3 instructions are just "set 0, e".
#b6ac#4f2c112
d5 
        push de  ; push just to make sure the next pop does not mess up the stack.
#b6ad#4f2d
Lb6ad_nothing_found:
#b6ad#4f2d111
d1 
        pop de
#b6ae#4f2e
Lb6ae:
#b6ae#4f2e111
e1 
    pop hl
#b6af#4f2f111
c9 
    ret
#b6b0#4f30
#b6b0#4f30
Lb6b0_direction_offsets:
#b6b0#4f302
    dw 1  ; right
#b6b2#4f322
    dw -1  ; left
#b6b4#4f342
    dw 512  ; down
#b6b6#4f362
    dw -512  ; up
#b6b8#4f38
#b6b8#4f38
#b6b8#4f38
; --------------------------------
#b6b8#4f38
; Find new bullet pointer. Friendly robots can only use bullets 1, and 2,
#b6b8#4f38
; and enemy robots bullets 3 and 4 (bullet 0 is reserved for player-controlled robots).
#b6b8#4f38
; Input:
#b6b8#4f38
; - ix: pointer to robot that is firing.
#b6b8#4f38
; Output:
#b6b8#4f38
; - iy: new bullet ptr
#b6b8#4f38
; - z: new bullet found
#b6b8#4f38
; - nz: no bullet slots available.
#b6b8#4f38
Lb6b8_find_new_bullet_ptr:
#b6b8#4f38416
fd 21 dc d7 
    ld iy, Ld7d3_bullets + BULLET_STRUCT_SIZE
#b6bc#4f3c422
dd cb 0a 7e 
    bit 7, (ix + ROBOT_STRUCT_CONTROL)
#b6c0#4f40213/8
28 05 
    jr z, Lb6c7_player_robot
#b6c2#4f42311
11 12 00 
    ld de, BULLET_STRUCT_SIZE * 2
#b6c5#4f45217
fd 19 
    add iy, de
#b6c7#4f47
Lb6c7_player_robot:
#b6c7#4f47321
fd 7e 01 
    ld a, (iy + 1)
#b6ca#4f4a15
b7 
    or a
#b6cb#4f4b112/6
c8 
    ret z  ; first bullet is available
#b6cc#4f4c
    ; Try next bullet:
#b6cc#4f4c311
11 09 00 
    ld de, BULLET_STRUCT_SIZE
#b6cf#4f4f217
fd 19 
    add iy, de
#b6d1#4f51321
fd 7e 01 
    ld a, (iy + 1)
#b6d4#4f5415
b7 
    or a
#b6d5#4f55111
c9 
    ret
#b6d6#4f56
#b6d6#4f56
#b6d6#4f56
; --------------------------------
#b6d6#4f56
; Spawns a new bullet on "iy".
#b6d6#4f56
; Input:
#b6d6#4f56
; - a: weapon to fire: 1: cannon, 2: missiles, 3: phasers.
#b6d6#4f56
; - iy: bullet pointer to use.
#b6d6#4f56
; - ix: pointer to robot that fired the weapon.
#b6d6#4f56
Lb6d6_weapon_fire:
#b6d6#4f56321
fd 77 07 
    ld (iy + BULLET_STRUCT_TYPE), a
#b6d9#4f5928
0e 05 
    ld c, WEAPON_RANGE_DEFAULT  ; range
#b6db#4f5b28
fe 02 
    cp 2  ; missiles
#b6dd#4f5d213/8
20 02 
    jr nz, Lb6e1_not_missiles
#b6df#4f5f28
0e 07 
    ld c, WEAPON_RANGE_MISSILES  ; missiles have an extended range
#b6e1#4f61
Lb6e1_not_missiles:
#b6e1#4f61422
dd cb 07 7e 
    bit 7, (ix + ROBOT_STRUCT_PIECES)
#b6e5#4f65213/8
28 01 
    jr z, Lb6e8_not_electronics
#b6e7#4f6715
0c 
    inc c  ; electronics increase by one the weapon range
#b6e8#4f68
Lb6e8_not_electronics:
#b6e8#4f68321
fd 71 06 
    ld (iy + BULLET_STRUCT_RANGE), c
#b6eb#4f6b321
dd 7e 08 
    ld a, (ix + ROBOT_STRUCT_DIRECTION)
#b6ee#4f6e321
fd 77 05 
    ld (iy + BULLET_STRUCT_DIRECTION), a
#b6f1#4f71421
fd 36 08 0a 
    ld (iy + BULLET_STRUCT_ALTITUDE), 10
#b6f5#4f75321
dd 6e 02 
    ld l, (ix + ROBOT_STRUCT_X)
#b6f8#4f78321
dd 66 03 
    ld h, (ix + ROBOT_STRUCT_X + 1)
#b6fb#4f7b321
dd 46 04 
    ld b, (ix + ROBOT_STRUCT_Y)
#b6fe#4f7e318
cd 24 b7 
    call Lb724_bullet_update_internal
#b701#4f81321
fd 7e 01 
    ld a, (iy + 1)
#b704#4f8415
b7 
    or a
#b705#4f85213/8
28 05 
    jr z, Lb70c
#b707#4f8728
3e 01 
    ld a, 1
#b709#4f89314
32 53 fd 
    ld (Lfd53_produce_in_game_sound), a  ; produce sound
#b70c#4f8c
Lb70c:
#b70c#4f8c111
c9 
    ret
#b70d#4f8d
#b70d#4f8d
#b70d#4f8d
; --------------------------------
#b70d#4f8d
; Update cycle for bullets, including dealing damage to robots.
#b70d#4f8d
; Input:
#b70d#4f8d
; - iy: bullet ptr
#b70d#4f8d
Lb70d_bullet_update:
#b70d#4f8d321
fd 6e 00 
    ld l, (iy + BULLET_STRUCT_MAP_PTR)
#b710#4f90321
fd 66 01 
    ld h, (iy + BULLET_STRUCT_MAP_PTR + 1)
#b713#4f93217
cb b6 
    res 6, (hl)  ; remove the bullet from the map
#b715#4f95325
fd 35 06 
    dec (iy + BULLET_STRUCT_RANGE)  ; decrease the lifetime of the bullet
#b718#4f98311
ca ea b7 
    jp z, Lb7ea_bullet_disappear  ; if bullet has reached its maximum range, destroy it
#b71b#4f9b321
fd 6e 02 
    ld l, (iy + BULLET_STRUCT_X)
#b71e#4f9e321
fd 66 03 
    ld h, (iy + BULLET_STRUCT_X + 1)
#b721#4fa1321
fd 46 04 
    ld b, (iy + BULLET_STRUCT_Y)
#b724#4fa4
Lb724_bullet_update_internal:
#b724#4fa4
    ; move the bullet in the direction of movement:
#b724#4fa4321
fd 7e 05 
    ld a, (iy + BULLET_STRUCT_DIRECTION)
#b727#4fa715
0f 
    rrca
#b728#4fa8213/8
30 04 
    jr nc, Lb72e_not_right
#b72a#4faa17
23 
    inc hl  ; x += 2
#b72b#4fab17
23 
    inc hl
#b72c#4fac213
18 19 
    jr Lb747_movement_complete
#b72e#4fae
Lb72e_not_right:
#b72e#4fae15
0f 
    rrca
#b72f#4faf213/8
30 04 
    jr nc, Lb735_not_left
#b731#4fb117
2b 
    dec hl  ; x -= 2
#b732#4fb217
2b 
    dec hl
#b733#4fb3213
18 12 
    jr Lb747_movement_complete
#b735#4fb5
Lb735_not_left:
#b735#4fb515
0f 
    rrca
#b736#4fb6213/8
30 04 
    jr nc, Lb73c_not_down
#b738#4fb815
04 
    inc b  ; y += 2
#b739#4fb915
04 
    inc b
#b73a#4fba213
18 05 
    jr Lb741_check_out_of_map_in_y
#b73c#4fbc
Lb73c_not_down:
#b73c#4fbc15
0f 
    rrca
#b73d#4fbd213/8
30 08 
    jr nc, Lb747_movement_complete
#b73f#4fbf15
05 
    dec b  ; y -= 2
#b740#4fc015
05 
    dec b
#b741#4fc1
Lb741_check_out_of_map_in_y:
#b741#4fc1
    ; Notice that we only need to check out of bounds in the y axis, as, in the x axis, there's
#b741#4fc1
    ; always obstacles at the ends of the map, so, we don't need to check.
#b741#4fc115
78 
    ld a, b
#b742#4fc228
fe 10 
    cp MAP_WIDTH
#b744#4fc4311
d2 ea b7 
    jp nc, Lb7ea_bullet_disappear  ; if y > 16 or < 0, make it disappear.
#b747#4fc7
Lb747_movement_complete:
#b747#4fc7321
fd 75 02 
    ld (iy + BULLET_STRUCT_X), l
#b74a#4fca321
fd 74 03 
    ld (iy + BULLET_STRUCT_X + 1), h
#b74d#4fcd321
fd 70 04 
    ld (iy + BULLET_STRUCT_Y), b
#b750#4fd0
    ; Check if the bullet collided with the map:
#b750#4fd0318
cd d6 b5 
    call Lb5d6_map_altitude_2x2
#b753#4fd3321
fd be 08 
    cp (iy + BULLET_STRUCT_ALTITUDE)
#b756#4fd6311
d2 ea b7 
    jp nc, Lb7ea_bullet_disappear  ; collision
#b759#4fd915
78 
    ld a, b
#b75a#4fda
    ; Calculate the new map pointer given the new position:
#b75a#4fda318
cd a6 cc 
    call Lcca6_compute_map_ptr
#b75d#4fdd321
fd 75 00 
    ld (iy + BULLET_STRUCT_MAP_PTR), l
#b760#4fe0321
fd 74 01 
    ld (iy + BULLET_STRUCT_MAP_PTR + 1), h
#b763#4fe3112
e5 
    push hl
#b764#4fe417
2b 
        dec hl  ; x -= 1
#b765#4fe515
25 
        dec h  ; y -= 1
#b766#4fe615
25 
        dec h
#b767#4fe715
7c 
        ld a, h
#b768#4fe828
fe dd 
        cp #dd  ; check if the pointer is out of the map area
#b76a#4fea213/8
38 10 
        jr c, Lb77c_continue  ; out of bounds in that direction, so, we can skip a few collision 
#b76c#4fec
                              ; checks.
#b76c#4fec214
cb 76 
        bit 6, (hl)
#b76e#4fee213/8
20 37 
        jr nz, Lb7a7_potentially_hit_a_robot
#b770#4ff017
23 
        inc hl  ; x += 1
#b771#4ff1214
cb 76 
        bit 6, (hl)
#b773#4ff3213/8
20 32 
        jr nz, Lb7a7_potentially_hit_a_robot
#b775#4ff517
23 
        inc hl  ; x += 1
#b776#4ff6214
cb 76 
        bit 6, (hl)
#b778#4ff8213/8
20 2d 
        jr nz, Lb7a7_potentially_hit_a_robot
#b77a#4ffa17
2b 
        dec hl  ; restore the x coordinate
#b77b#4ffb17
2b 
        dec hl
#b77c#4ffc
Lb77c_continue:
#b77c#4ffc15
24 
        inc h  ; y += 1
#b77d#4ffd15
24 
        inc h
#b77e#4ffe214
cb 76 
        bit 6, (hl)
#b780#5000213/8
20 25 
        jr nz, Lb7a7_potentially_hit_a_robot
#b782#500217
23 
        inc hl  ; x += 1
#b783#5003214
cb 76 
        bit 6, (hl)
#b785#5005213/8
20 20 
        jr nz, Lb7a7_potentially_hit_a_robot
#b787#500717
23 
        inc hl  ; x += 1
#b788#5008214
cb 76 
        bit 6, (hl)
#b78a#500a213/8
20 1b 
        jr nz, Lb7a7_potentially_hit_a_robot
#b78c#500c17
2b 
        dec hl  ; x -= 2
#b78d#500d17
2b 
        dec hl
#b78e#500e15
24 
        inc h  ; y += 1
#b78f#500f15
24 
        inc h
#b790#501015
7c 
        ld a, h
#b791#501128
fe fd 
        cp #fd  ; check if the pointer is out of the map area
#b793#5013213/8
30 0e 
        jr nc, Lb7a3_no_robot_collision
#b795#5015214
cb 76 
        bit 6, (hl)
#b797#5017213/8
20 0e 
        jr nz, Lb7a7_potentially_hit_a_robot
#b799#501917
23 
        inc hl
#b79a#501a214
cb 76 
        bit 6, (hl)
#b79c#501c213/8
20 09 
        jr nz, Lb7a7_potentially_hit_a_robot
#b79e#501e17
23 
        inc hl
#b79f#501f214
cb 76 
        bit 6, (hl)
#b7a1#5021213/8
20 04 
        jr nz, Lb7a7_potentially_hit_a_robot
#b7a3#5023
Lb7a3_no_robot_collision:
#b7a3#5023111
e1 
    pop hl
#b7a4#5024217
cb f6 
    set 6, (hl)  ; we mark the bullet in the map again
#b7a6#5026111
c9 
    ret
#b7a7#5027
Lb7a7_potentially_hit_a_robot:
#b7a7#5027217
fd e5 
        push iy
#b7a9#5029321
fd 5e 07 
            ld e, (iy + BULLET_STRUCT_TYPE)
#b7ac#502c28
0e fc 
            ld c, 252  ; c determines the SFX that will be played with this event
#b7ae#502e318
cd d8 cd 
            call Lcdd8_get_robot_at_ptr
#b7b1#5031213/8
20 2b 
            jr nz, Lb7de_collision_handled
#b7b3#5033321
fd 7e 0c 
            ld a, (iy + ROBOT_STRUCT_STRENGTH)
#b7b6#503615
3d 
            dec a
#b7b7#5037311
fa de b7 
            jp m, Lb7de_collision_handled  ; robot was already destroyed
#b7ba#503a
            ; Determine the damage dealt:
#b7ba#503a28
3e 3c 
            ld a, 60
#b7bc#503c321
fd 96 09 
            sub (iy + ROBOT_STRUCT_HEIGHT)
#b7bf#503f321
fd 96 0d 
            sub (iy + ROBOT_STRUCT_ALTITUDE)
#b7c2#5042210
cb 3f 
            srl a
#b7c4#5044210
cb 3f 
            srl a
#b7c6#504615
57 
            ld d, a  ; d = "base damage" = (60 - (robot height + altitude)) / 4
#b7c7#504715
43 
            ld b, e  ; bullet type (1: cannon, 2: missiles, 3: phaser)
#b7c8#5048
Lb7c8_damage_calculation_loop:
#b7c8#504815
82 
            add a, d
#b7c9#5049214/9
10 fd 
            djnz Lb7c8_damage_calculation_loop
#b7cb#504b
            ; Here a = 2x base damage for cannon, 3x for missiles, and 4x for phasers.
#b7cb#504b15
47 
            ld b, a
#b7cc#504c28
0e fa 
            ld c, 250  ; sfx
#b7ce#504e321
fd 7e 0c 
            ld a, (iy + ROBOT_STRUCT_STRENGTH)
#b7d1#505115
90 
            sub b  ; deal damage
#b7d2#5052213/8
28 03 
            jr z, Lb7d7_robot_destroyed
#b7d4#5054311
f2 db b7 
            jp p, Lb7db_robot_hit
#b7d7#5057
Lb7d7_robot_destroyed:
#b7d7#505728
3e fc 
            ld a, -4  ; mark negative strength, which will make the robot blink before being 
#b7d9#5059
                      ; destroyed.
#b7d9#505928
0e c8 
            ld c, 200  ; sfx
#b7db#505b
Lb7db_robot_hit:
#b7db#505b321
fd 77 0c 
            ld (iy + ROBOT_STRUCT_STRENGTH), a  ; update robot health
#b7de#505e
Lb7de_collision_handled:
#b7de#505e216
fd e1 
        pop iy
#b7e0#5060111
e1 
    pop hl
#b7e1#5061421
fd 36 01 00 
    ld (iy + BULLET_STRUCT_MAP_PTR + 1), 0  ; make the bullet disappear
#b7e5#506515
79 
    ld a, c
#b7e6#5066314
32 53 fd 
    ld (Lfd53_produce_in_game_sound), a  ; produce sound
#b7e9#5069111
c9 
    ret
#b7ea#506a
#b7ea#506a
#b7ea#506a
; --------------------------------
#b7ea#506a
; Make a bullet disappear.
#b7ea#506a
; Input:
#b7ea#506a
; - iy: bullet pointer.
#b7ea#506a
Lb7ea_bullet_disappear:
#b7ea#506a421
fd 36 01 00 
    ld (iy + 1), 0
#b7ee#506e28
3e fc 
    ld a, -4
#b7f0#5070314
32 53 fd 
    ld (Lfd53_produce_in_game_sound), a  ; produce sound
#b7f3#5073111
c9 
    ret
#b7f4#5074
#b7f4#5074
#b7f4#5074
; --------------------------------
#b7f4#5074
; Enemy AI update cycle. It works as follows:
#b7f4#5074
; - with probability 0.25 it does nothing.
#b7f4#5074
; - it then tries to pick a robot at random (from the set of 24 possible robots).
#b7f4#5074
; - if it's an active robot, it will control it via "Lb920_enemy_ai_single_robot_control"
#b7f4#5074
; - otherwise, it picks a random warbase
#b7f4#5074
; - if it belongs to the enemy, it will try to produce a random robot with come constraints.
#b7f4#5074
; - if any of the constraints is violated, then the enemy AI will just do nothing.
#b7f4#5074
; - otherwise, it will construct the robot with "stop & defend" orders, and wait for it 
#b7f4#5074
;   to be randomly picked up later to be assigned new orders.
#b7f4#5074
Lb7f4_update_enemy_ai:
#b7f4#5074318
cd 58 d3 
    call Ld358_random
#b7f7#507728
e6 1f 
    and #1f
#b7f9#507928
fe 18 
    cp MAX_ROBOTS_PER_PLAYER
#b7fb#507b112/6
d0 
    ret nc  ; with 0.25 probability the enemy AI does nothing.
#b7fc#507c
    ; Use the generated random number to get the pointer of a robot at random:
#b7fc#507c15
87 
    add a, a
#b7fd#507d15
87 
    add a, a
#b7fe#507e15
87 
    add a, a
#b7ff#507f15
6f 
    ld l, a
#b800#508028
26 00 
    ld h, 0
#b802#5082112
29 
    add hl, hl
#b803#5083311
11 80 db 
    ld de, Ldb80_player2_robots
#b806#5086112
19 
    add hl, de
#b807#5087112
e5 
    push hl
#b808#5088216
fd e1 
    pop iy  ; iy now has the pointer to a random robot from the enemy AI.
#b80a#508a28
3e 01 
    ld a, 1
#b80c#508c314
32 51 fd 
    ld (Lfd51_current_robot_player_or_enemy), a
#b80f#508f
    ; Check if the pointer corresponds to an active robot:
#b80f#508f321
fd 7e 01 
    ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#b812#509215
b7 
    or a
#b813#5093311
c2 20 b9 
    jp nz, Lb920_enemy_ai_single_robot_control
#b816#5096
#b816#5096
    ; pick a random warbase otherwise:
#b816#509628
06 04 
    ld b, N_WARBASES
#b818#5098311
21 73 fd 
    ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE
#b81b#509b
Lb81b_pick_random_warbase_loop:
#b81b#509b318
cd 58 d3 
    call Ld358_random
#b81e#509e28
e6 01 
    and 1
#b820#50a0213/8
28 05 
    jr z, Lb827_next_warbase
#b822#50a218
7e 
    ld a, (hl)
#b823#50a328
fe 20 
    cp #20
#b825#50a5213/8
28 08 
    jr z, Lb0ca_enemy_ai_control_warbase  ; also ensures it's a warbase
#b827#50a7
Lb827_next_warbase:
#b827#50a728
3e 05 
    ld a, BUILDING_STRUCT_SIZE
#b829#50a9318
cd 51 d3 
    call Ld351_add_hl_a
#b82c#50ac214/9
10 ed 
    djnz Lb81b_pick_random_warbase_loop
#b82e#50ae
    ; no warbase selected
#b82e#50ae111
c9 
    ret
#b82f#50af
#b82f#50af
Lb0ca_enemy_ai_control_warbase:
#b82f#50af
    ; Notice that if we reached here, "iy" has the pointer to an empty
#b82f#50af
    ; robot position.
#b82f#50af17
2b 
    dec hl
#b830#50b018
46 
    ld b, (hl)
#b831#50b117
2b 
    dec hl
#b832#50b218
7e 
    ld a, (hl)
#b833#50b317
2b 
    dec hl
#b834#50b418
6e 
    ld l, (hl)
#b835#50b515
67 
    ld h, a  ; hl = x coordinate, b = y coordinate
#b836#50b615
78 
    ld a, b
#b837#50b7112
e5 
    push hl
#b838#50b815
d9 
        exx
#b839#50b9111
e1 
    pop hl
#b83a#50ba15
47 
    ld b, a  ; hl = x coordinate, b = y coordinate in both ghost and regular registers
#b83b#50bb
             ; this is to set the robot coordinates below.
#b83b#50bb15
d9 
    exx
#b83c#50bc318
cd a6 cc 
    call Lcca6_compute_map_ptr
#b83f#50bf
    ; Check if the entrance to the warbase is blocked:
#b83f#50bf112
e5 
    push hl
#b840#50c018
7e 
        ld a, (hl)
#b841#50c115
24 
        inc h
#b842#50c215
24 
        inc h
#b843#50c318
b6 
        or (hl)
#b844#50c417
2b 
        dec hl
#b845#50c518
b6 
        or (hl)
#b846#50c617
23 
        inc hl
#b847#50c717
23 
        inc hl
#b848#50c818
b6 
        or (hl)
#b849#50c928
e6 40 
        and #40
#b84b#50cb111
e1 
    pop hl
#b84c#50cc112/6
c0 
    ret nz  ; if there is something blocking the entrance of the warbase, exit.
#b84d#50cd318
cd 58 d3 
    call Ld358_random  ; Note: not sure why calling random twice.
#b850#50d0318
cd 58 d3 
    call Ld358_random
#b853#50d315
4f 
    ld c, a  ; save the random number for later
#b854#50d4321
fd 77 07 
    ld (iy + ROBOT_STRUCT_PIECES), a
#b857#50d728
e6 07 
    and 7
#b859#50d928
fe 01 
    cp 1  ; bipod
#b85b#50db213/8
28 07 
    jr z, Lb864_correct_chasis
#b85d#50dd28
fe 02 
    cp 2  ; tracks
#b85f#50df213/8
28 03 
    jr z, Lb864_correct_chasis
#b861#50e128
fe 04 
    cp 4  ; antigrav
#b863#50e3112/6
c0 
    ret nz  ; if we picked more than one chassis, just return.
#b864#50e4
Lb864_correct_chasis:
#b864#50e415
79 
    ld a, c  ; restore the random number
#b865#50e515
0f 
    rrca
#b866#50e615
0f 
    rrca
#b867#50e715
0f 
    rrca
#b868#50e828
e6 0f 
    and #0f
#b86a#50ea112/6
c8 
    ret z  ; if we picked no weapon, just return.
#b86b#50eb28
fe 0f 
    cp #0f
#b86d#50ed112/6
c8 
    ret z  ; if we picked too many weapons (only 3 allowed), just return.
#b86e#50ee15
4f 
    ld c, a  ; save the weapon selection
#b86f#50ef314
3a 49 fd 
    ld a, (Lfd49_player2_robot_count)
#b872#50f215
0f 
    rrca
#b873#50f315
0f 
    rrca
#b874#50f415
0f 
    rrca
#b875#50f515
3c 
    inc a
#b876#50f628
e6 03 
    and 3
#b878#50f815
47 
    ld b, a  ; enemy # of robots / 8 + 1
#b879#50f9318
cd 05 b5 
    call Lb505_count_number_of_active_bits_in_the_lower_nibble
#b87c#50fc15
b8 
    cp b
#b87d#50fd112/6
d8 
    ret c  ; the first 8 robots, can at most have 1 weapon, the next 8 can have two, etc.
#b87e#50fe
#b87e#50fe
    ; Check if player 2 has enough resources:
#b87e#50fe311
21 4a fd 
    ld hl, Lfd4a_player2_resource_counts
#b881#5101311
11 29 fd 
    ld de, Lfd29_resource_counts_buffer
#b884#5104311
01 07 00 
    ld bc, 7
#b887#5107223/18
ed b0 
    ldir
#b889#5109321
fd 4e 07 
    ld c, (iy + ROBOT_STRUCT_PIECES)
#b88c#510c28
16 00 
    ld d, 0  ; how many "general resources" will we need to use.
#b88e#510e28
06 08 
    ld b, 8
#b890#5110
Lb890_check_resource_availability_loop:
#b890#5110210
cb 09 
    rrc c
#b892#5112213/8
30 24 
    jr nc, Lb8b8_next_piece
#b894#511428
3e 08 
    ld a, 8
#b896#511615
90 
    sub b
#b897#5117112
f5 
    push af
#b898#5118311
21 f0 ca 
        ld hl, Lcaf0_piece_costs
#b89b#511b318
cd 51 d3 
        call Ld351_add_hl_a
#b89e#511e18
5e 
        ld e, (hl)  ; cost of the piece
#b89f#511f111
f1 
    pop af
#b8a0#5120311
21 f8 ca 
    ld hl, Lcaf8_piece_factory_type
#b8a3#5123318
cd 51 d3 
    call Ld351_add_hl_a
#b8a6#512618
7e 
    ld a, (hl)  ; type of factory that can produce this piece
#b8a7#5127311
21 29 fd 
    ld hl, Lfd29_resource_counts_buffer
#b8aa#512a318
cd 51 d3 
    call Ld351_add_hl_a
#b8ad#512d18
7e 
    ld a, (hl)
#b8ae#512e15
93 
    sub e
#b8af#512f311
f2 b7 b8 
    jp p, Lb8b7_no_need_for_general_resources
#b8b2#5132210
ed 44 
    neg
#b8b4#513415
82 
    add a, d  ; add the left over to the general resources cost
#b8b5#513515
57 
    ld d, a
#b8b6#513615
af 
    xor a  ; zero out the resources we have left for this factory type.
#b8b7#5137
Lb8b7_no_need_for_general_resources:
#b8b7#513718
77 
    ld (hl), a
#b8b8#5138
Lb8b8_next_piece:
#b8b8#5138214/9
10 d6 
    djnz Lb890_check_resource_availability_loop
#b8ba#513a
    ; Check that we have enough general resources:
#b8ba#513a311
21 29 fd 
    ld hl, Lfd29_resource_counts_buffer
#b8bd#513d18
7e 
    ld a, (hl)
#b8be#513e210
cb 3f 
    srl a
#b8c0#514028
fe 0b 
    cp 11
#b8c2#5142213/8
30 02 
    jr nc, Lb8c6_more_than_22_resources_left
#b8c4#514428
3e 0b 
    ld a, 11
#b8c6#5146
Lb8c6_more_than_22_resources_left:
#b8c6#514615
ba 
    cp d
#b8c7#5147112/6
d8 
    ret c  ; The maximum general resources we can spend on a robot is half of the amount we have (
#b8c8#5148
           ; except if we need to spend less or equal to 11).
#b8c8#5148
#b8c8#514818
7e 
    ld a, (hl)
#b8c9#514915
92 
    sub d
#b8ca#514a112/6
f8 
    ret m  ; we do not have enough resources to build the robot, return.
#b8cb#514b
#b8cb#514b
    ; subtract the costs from the actual player 2 resources:
#b8cb#514b18
77 
    ld (hl), a
#b8cc#514c311
11 4a fd 
    ld de, Lfd4a_player2_resource_counts
#b8cf#514f311
01 07 00 
    ld bc, 7
#b8d2#5152223/18
ed b0 
    ldir
#b8d4#5154
#b8d4#5154
    ; Start the robot!
#b8d4#5154421
fd 36 0a 80 
    ld (iy + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_ENEMY_AI  ; mark the owner
#b8d8#515815
d9 
    exx
#b8d9#5159318
cd 7c cc 
        call Lcc7c_set_robot_position  ; set position
#b8dc#515c15
d9 
    exx
#b8dd#515d421
fd 36 05 04 
    ld (iy + ROBOT_STRUCT_DESIRED_MOVE_DIRECTION), 4  ; by default move down (to exit the warbase)
#b8e1#5161421
fd 36 08 04 
    ld (iy + ROBOT_STRUCT_DIRECTION), 4
#b8e5#5165421
fd 36 06 03 
    ld (iy + ROBOT_STRUCT_NUMBER_OF_STEPS_TO_KEEP_WALKING), 3
#b8e9#5169421
fd 36 0d 00 
    ld (iy + ROBOT_STRUCT_ALTITUDE), 0
#b8ed#516d421
fd 36 0b 00 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_STOP_AND_DEFEND
#b8f1#5171421
fd 36 0f 01 
    ld (iy + ROBOT_STRICT_CYCLES_TO_NEXT_UPDATE), 1
#b8f5#5175421
fd 36 0c 64 
    ld (iy + ROBOT_STRUCT_STRENGTH), 100
#b8f9#5179421
fd 36 0e ff 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 255
#b8fd#517d
    ; calculate robot height (when a player constructs it, this is calculated in the robot editing 
#b8fd#517d
    ; UI):
#b8fd#517d321
fd 4e 07 
    ld c, (iy + ROBOT_STRUCT_PIECES)
#b900#518028
06 08 
    ld b, 8
#b902#518228
16 00 
    ld d, 0
#b904#5184
Lb904_robot_height_loop:
#b904#5184210
cb 09 
    rrc c
#b906#5186213/8
30 0c 
    jr nc, Lb914_next_piece
#b908#518828
3e 08 
    ld a, 8
#b90a#518a15
90 
    sub b
#b90b#518b311
21 b4 d7 
    ld hl, Ld7b4_piece_heights
#b90e#518e318
cd 51 d3 
    call Ld351_add_hl_a
#b911#519118
7e 
    ld a, (hl)
#b912#519215
82 
    add a, d
#b913#519315
57 
    ld d, a
#b914#5194
Lb914_next_piece:
#b914#5194214/9
10 ee 
    djnz Lb904_robot_height_loop
#b916#5196321
fd 72 09 
    ld (iy + ROBOT_STRUCT_HEIGHT), d
#b919#5199318
cd 40 bb 
    call Lbb40_count_robots
#b91c#519c318
cd 93 d2 
    call Ld293_update_stats_in_right_hud
#b91f#519f111
c9 
    ret
#b920#51a0
#b920#51a0
#b920#51a0
; --------------------------------
#b920#51a0
; If the robot already has orders (!= from "stop & defend"):
#b920#51a0
; - with a 1 / 32 chance they will be kept.
#b920#51a0
; - if the robot target is of the type it was looking for, a new order will be given (note: I think 
#b920#51a0
;   this is a bug, look my other note below).
#b920#51a0
; - if the robot has not reached the target, a new order will be given.
#b920#51a0
; If new orders are to be given:
#b920#51a0
; - if robot has nuclear, it will try to randomly go and destroy player factories/warbases.
#b920#51a0
; - otherwise, capture neutral/player factories or player warbases.
#b920#51a0
; - if it cannot find a target, then destroy player robots.
#b920#51a0
; Input:
#b920#51a0
; - iy: robot ptr.
#b920#51a0
Lb920_enemy_ai_single_robot_control:
#b920#51a0321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b923#51a315
b7 
    or a
#b924#51a4213/8
28 37 
    jr z, Lb95d_assign_new_orders  ; if current orders are stop & defend
#b926#51a6
#b926#51a6
    ; The robot already had orders different from stop & defend.
#b926#51a615
47 
    ld b, a
#b927#51a7318
cd 58 d3 
    call Ld358_random
#b92a#51aa28
e6 1f 
    and #1f
#b92c#51ac112/6
c0 
    ret nz  ; 1 / 32 chance to keep the same orders the robot still has.
#b92d#51ad15
78 
    ld a, b
#b92e#51ae28
fe 04 
    cp ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES
#b930#51b0213/8
38 2b 
    jr c, Lb95d_assign_new_orders  ; if orders where stop & defend, advance, retreat or destroy 
#b932#51b2
                                   ; robots, assign new orders.
#b932#51b2
#b932#51b2
    ; Otherwise, look for a target:
#b932#51b2321
fd 7e 0b 
    ld a, (iy + ROBOT_STRUCT_ORDERS)
#b935#51b5318
cd d5 b3 
    call Lb3d5_prepare_robot_order_building_target_search
#b938#51b8321
fd 7e 0e 
    ld a, (iy + ROBOT_STRUCT_ORDERS_ARGUMENT)
#b93b#51bb15
47 
    ld b, a
#b93c#51bc15
87 
    add a, a
#b93d#51bd15
87 
    add a, a
#b93e#51be15
80 
    add a, b
#b93f#51bf318
cd 51 d3 
    call Ld351_add_hl_a  ; hl now contains a pointer to the target building type flag
#b942#51c218
7e 
    ld a, (hl)
#b943#51c328
e6 e0 
    and #e0
#b945#51c515
bb 
    cp e  ; compare if the target flags are the same as we are looking for.
#b946#51c6213/8
28 15 
    jr z, Lb95d_assign_new_orders  ; if the robot's target was a correct one, assign new orders (
#b948#51c8
                                   ; note: this is strange, I think this is a bug, and it was meant 
#b948#51c8
                                   ; to be "nz").
#b948#51c8
    ; Now check, if the robot has arrived to the target, keep orders, otherwise, change.
#b948#51c817
2b 
    dec hl
#b949#51c9321
fd 7e 04 
    ld a, (iy + ROBOT_STRUCT_Y)
#b94c#51cc18
96 
    sub (hl)
#b94d#51cd213/8
20 0e 
    jr nz, Lb95d_assign_new_orders  ; if the target is not in the same "y" coordinate, assign new 
#b94f#51cf
                                    ; orders.
#b94f#51cf17
2b 
    dec hl
#b950#51d018
56 
    ld d, (hl)
#b951#51d117
2b 
    dec hl
#b952#51d218
5e 
    ld e, (hl)
#b953#51d3321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b956#51d6321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b959#51d915
af 
    xor a
#b95a#51da217
ed 52 
    sbc hl, de
#b95c#51dc112/6
c8 
    ret z  ; if the robot is in the same "x" coordinate as the target, keep the orders!
#b95d#51dd
#b95d#51dd
Lb95d_assign_new_orders:
#b95d#51dd
    ; Randomly assigns a robot to destroy/capture factories or warbases. 
#b95d#51dd
    ; - destroy if the robot has nuclear, and capture if it does not.
#b95d#51dd
    ; - in case it cannot find a target for the random orders it was assigned, it will just 
#b95d#51dd
    ;   be tasked to destroy player robots.
#b95d#51dd421
fd 36 0b 03 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS  ; Potential optimization: 
#b961#51e1
                                                                      ; this assignment will always 
#b961#51e1
                                                                      ; be overwritten. So, it can 
#b961#51e1
                                                                      ; be eliminated.
#b961#51e1422
fd cb 07 76 
    bit 6, (iy + ROBOT_STRUCT_PIECES)
#b965#51e5213/8
28 0f 
    jr z, Lb976_robot_does_not_have_nuclear
#b967#51e7
    ; robot has nuclear:
#b967#51e7
    ; randomly assign it to destroy either player factories or player warbases:
#b967#51e7318
cd 58 d3 
    call Ld358_random
#b96a#51ea15
47 
    ld b, a
#b96b#51eb15
07 
    rlca
#b96c#51ec15
b0 
    or b
#b96d#51ed28
e6 01 
    and 1
#b96f#51ef28
c6 04 
    add a, ROBOT_ORDERS_DESTROY_ENEMY_FACTORIES
#b971#51f1321
fd 77 0b 
    ld (iy + ROBOT_STRUCT_ORDERS), a
#b974#51f4213
18 13 
    jr Lb989_new_orders_assigned
#b976#51f6
#b976#51f6
Lb976_robot_does_not_have_nuclear:
#b976#51f6
    ; Randomly assign it to capture: neutral factories, enemy factories or enemy warbases:
#b976#51f628
0e 00 
    ld c, ROBOT_ORDERS_STOP_AND_DEFEND
#b978#51f8318
cd 58 d3 
    call Ld358_random
#b97b#51fb15
0f 
    rrca
#b97c#51fc213/8
38 05 
    jr c, Lb983
#b97e#51fe15
0c 
    inc c
#b97f#51ff15
0f 
    rrca
#b980#5200213/8
38 01 
    jr c, Lb983
#b982#520215
0c 
    inc c
#b983#5203
Lb983:
#b983#520315
79 
    ld a, c
#b984#520428
c6 06 
    add a, ROBOT_ORDERS_CAPTURE_NEUTRAL_FACTORIES
#b986#5206321
fd 77 0b 
    ld (iy + ROBOT_STRUCT_ORDERS), a
#b989#5209
#b989#5209
Lb989_new_orders_assigned:
#b989#5209321
fd 6e 02 
    ld l, (iy + ROBOT_STRUCT_X)
#b98c#520c321
fd 66 03 
    ld h, (iy + ROBOT_STRUCT_X + 1)
#b98f#520f421
fd 36 0e ff 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), 255
#b993#5213318
cd 4d b3 
    call Lb34d_find_capture_or_destroy_target
#b996#5216321
fd 72 0e 
    ld (iy + ROBOT_STRUCT_ORDERS_ARGUMENT), d
#b999#5219112/6
c0 
    ret nz  ; if target found, we are done.
#b99a#521a
    ; Otherwise, just try to destroy enemy robots
#b99a#521a421
fd 36 0b 03 
    ld (iy + ROBOT_STRUCT_ORDERS), ROBOT_ORDERS_DESTROY_ENEMY_ROBOTS
#b99e#521e111
c9 
    ret
#b99f#521f
#b99f#521f
#b99f#521f
; --------------------------------
#b99f#521f
; Nuclear bomb effect: destroys buildings and robots nearby and replace with debris.
#b99f#521f
; Input:
#b99f#521f
; - iy: robot pointer.
#b99f#521f
Lb99f_fire_nuclear_bomb:
#b99f#521f311
21 73 fd 
    ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE
#b9a2#522228
0e 00 
    ld c, 0  ; building index
#b9a4#5224311
11 0a 07 
    ld de, #070a  ; nuclear bomb effect radius for warbases (something in between a circle and a 
#b9a7#5227
                  ; square):
#b9a7#5227
                  ; - maximum distance in each axis of 7
#b9a7#5227
                  ; - maximum sum of distances in each axis of 10
#b9a7#5227
Lb9a7_building_loop:
#b9a7#5227112
e5 
    push hl
#b9a8#5228214
cb 7e 
        bit 7, (hl)  ; check if the building is already destroyed.
#b9aa#522a213/8
20 31 
        jr nz, Lb9dd_skip_building
#b9ac#522c17
2b 
        dec hl
#b9ad#522d15
79 
        ld a, c
#b9ae#522e28
fe 04 
        cp N_WARBASES
#b9b0#5230
        ; Calculate the distance in the y axis between robot and building.
#b9b0#5230321
fd 7e 04 
        ld a, (iy + ROBOT_STRUCT_Y)
#b9b3#5233213/8
30 02 
        jr nc, Lb9b7_not_a_warbase
#b9b5#523528
c6 04 
        add a, 4
#b9b7#5237
Lb9b7_not_a_warbase:
#b9b7#523715
3c 
        inc a
#b9b8#523818
96 
        sub (hl)
#b9b9#5239
        ; "a" now has the difference in the y axis, now calculate the absolute value:
#b9b9#5239311
f2 be b9 
        jp p, Lb9be_positive_difference
#b9bc#523c210
ed 44 
        neg
#b9be#523e
Lb9be_positive_difference:
#b9be#523e15
47 
        ld b, a  ; store the difference in y.
#b9bf#523f15
ba 
        cp d
#b9c0#5240213/8
30 1b 
        jr nc, Lb9dd_skip_building  ; building is too far
#b9c2#5242
        ; calculate the distance in the x axis:
#b9c2#5242112
d5 
        push de
#b9c3#524317
2b 
            dec hl
#b9c4#524418
56 
            ld d, (hl)
#b9c5#524517
2b 
            dec hl
#b9c6#524618
5e 
            ld e, (hl)  ; building x
#b9c7#5247321
fd 6e 02 
            ld l, (iy + ROBOT_STRUCT_X)
#b9ca#524a321
fd 66 03 
            ld h, (iy + ROBOT_STRUCT_X + 1)  ; robot x
#b9cd#524d318
cd ca b3 
            call Lb3ca_distance_from_hl_to_de
#b9d0#5250111
d1 
        pop de
#b9d1#525115
7c 
        ld a, h
#b9d2#525215
b7 
        or a
#b9d3#5253213/8
20 08 
        jr nz, Lb9dd_skip_building  ; too far
#b9d5#525515
7d 
        ld a, l
#b9d6#525615
ba 
        cp d
#b9d7#5257213/8
30 04 
        jr nc, Lb9dd_skip_building  ; too far
#b9d9#525915
80 
        add a, b
#b9da#525a15
bb 
        cp e  ; check if the sum of distances is larger than 10
#b9db#525b213/8
38 15 
        jr c, Lb9f2_building_in_range_of_nuclear_bomb
#b9dd#525d
Lb9dd_skip_building:
#b9dd#525d111
e1 
    pop hl
#b9de#525e
    ; next building
#b9de#525e28
3e 05 
    ld a, BUILDING_STRUCT_SIZE
#b9e0#5260318
cd 51 d3 
    call Ld351_add_hl_a
#b9e3#526315
0c 
    inc c
#b9e4#526415
79 
    ld a, c
#b9e5#526528
fe 04 
    cp 4
#b9e7#5267213/8
38 be 
    jr c, Lb9a7_building_loop
#b9e9#5269311
11 07 05 
    ld de, #0507  ; nuclear bomb effect radius for factories (something in between a circle and a 
#b9ec#526c
                  ; square):
#b9ec#526c
                  ; - maximum distance in each axis of 5
#b9ec#526c
                  ; - maximum sum of distances in each axis of 7
#b9ec#526c28
fe 1c 
    cp N_WARBASES + N_FACTORIES
#b9ee#526e213/8
38 b7 
    jr c, Lb9a7_building_loop
#b9f0#5270213
18 10 
    jr Lba02_look_for_robots_in_range_of_nuclear_bomb
#b9f2#5272
#b9f2#5272
Lb9f2_building_in_range_of_nuclear_bomb:
#b9f2#5272
    ; A nuclear bomb will only destroy at most one building. As soon as
#b9f2#5272
    ; a building to destroy is found, we are done with the above loop:
#b9f2#5272111
e1 
    pop hl
#b9f3#527315
79 
    ld a, c
#b9f4#527428
fe 04 
    cp N_WARBASES
#b9f6#5276213/8
30 05 
    jr nc, Lb9fd_factory
#b9f8#5278318
cd f9 bb 
    call Lbbf9_destroy_warbase
#b9fb#527b213
18 05 
    jr Lba02_look_for_robots_in_range_of_nuclear_bomb
#b9fd#527d
Lb9fd_factory:
#b9fd#527d28
d6 04 
    sub N_WARBASES
#b9ff#527f318
cd d8 bb 
    call Lbbd8_destroy_factory
#ba02#5282
#ba02#5282
Lba02_look_for_robots_in_range_of_nuclear_bomb:
#ba02#5282
    ; Look for robots nearby to destroy
#ba02#5282321
fd 6e 00 
    ld l, (iy + ROBOT_STRUCT_MAP_PTR)
#ba05#5285321
fd 66 01 
    ld h, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#ba08#5288217
fd e5 
    push iy
#ba0a#528a311
11 fc f7 
        ld de, -(4 * MAP_LENGTH + 4)
#ba0d#528d112
19 
        add hl, de  ; subtract (4, 4) to the robot map pointer.
#ba0e#528e
        ; look for robots in a 9x9 window around the robot
#ba0e#528e311
01 09 09 
        ld bc, #0909
#ba11#5291
Lba11_loop_y:
#ba11#5291112
c5 
        push bc
#ba12#5292112
e5 
            push hl
#ba13#529315
7c 
                ld a, h
#ba14#529428
fe df 
                cp #df
#ba16#5296213/8
38 49 
                jr c, Lba61_next_y  ; out of map bounds
#ba18#529828
fe fd 
                cp #fd
#ba1a#529a213/8
30 45 
                jr nc, Lba61_next_y  ; out of map bounds
#ba1c#529c15
79 
                ld a, c
#ba1d#529d28
fe 01 
                cp 1
#ba1f#529f213/8
28 0c 
                jr z, Lba2d_double_x_increment
#ba21#52a128
fe 02 
                cp 2
#ba23#52a3213/8
28 0b 
                jr z, Lba30_x_increment
#ba25#52a528
fe 08 
                cp 8
#ba27#52a7213/8
28 07 
                jr z, Lba30_x_increment
#ba29#52a928
fe 09 
                cp 9
#ba2b#52ab213/8
20 06 
                jr nz, Lba33_loop_x
#ba2d#52ad
Lba2d_double_x_increment:
#ba2d#52ad17
23 
                inc hl
#ba2e#52ae15
05 
                dec b
#ba2f#52af15
05 
                dec b
#ba30#52b0
Lba30_x_increment:
#ba30#52b017
23 
                inc hl
#ba31#52b115
05 
                dec b
#ba32#52b215
05 
                dec b
#ba33#52b3
Lba33_loop_x:
#ba33#52b3112
c5 
                push bc
#ba34#52b418
7e 
                    ld a, (hl)
#ba35#52b5210
cb 77 
                    bit 6, a
#ba37#52b7213/8
28 0b 
                    jr z, Lba44_robots_handled
#ba39#52b9318
cd d8 cd 
                    call Lcdd8_get_robot_at_ptr
#ba3c#52bc213/8
20 06 
                    jr nz, Lba44_robots_handled
#ba3e#52be421
fd 36 01 00 
                    ld (iy + ROBOT_STRUCT_MAP_PTR + 1), 0  ; mark robot as destroyed
#ba42#52c2217
cb b6 
                    res 6, (hl)  ; remove from map
#ba44#52c4
Lba44_robots_handled:
#ba44#52c4
                    ; Destroy map elements
#ba44#52c418
7e 
                    ld a, (hl)
#ba45#52c5210
cb 6f 
                    bit 5, a
#ba47#52c7213/8
20 14 
                    jr nz, Lba5d_next_x
#ba49#52c928
e6 1f 
                    and #1f
#ba4b#52cb28
fe 11 
                    cp 17  ; do not destroy terrain
#ba4d#52cd213/8
38 0e 
                    jr c, Lba5d_next_x
#ba4f#52cf28
fe 15 
                    cp 21
#ba51#52d1213/8
30 0a 
                    jr nc, Lba5d_next_x  ; do not destroy the fences that mark the end of the map 
#ba53#52d3
                                         ; in each end.
#ba53#52d3318
cd 58 d3 
                    call Ld358_random
#ba56#52d628
e6 01 
                    and 1
#ba58#52d828
c6 06 
                    add a, 6  ; pick a random piece of debris
#ba5a#52da318
cd 91 bd 
                    call Lbd91_add_element_to_map
#ba5d#52dd
Lba5d_next_x:
#ba5d#52dd111
c1 
                pop bc
#ba5e#52de17
23 
                inc hl
#ba5f#52df214/9
10 d2 
                djnz Lba33_loop_x
#ba61#52e1
Lba61_next_y:
#ba61#52e1111
e1 
            pop hl
#ba62#52e215
24 
            inc h  ; y+= 1
#ba63#52e315
24 
            inc h
#ba64#52e4111
c1 
        pop bc
#ba65#52e515
0d 
        dec c
#ba66#52e6213/8
20 a9 
        jr nz, Lba11_loop_y
#ba68#52e8
          ; mark the player in the map and redraw
#ba68#52e8318
cd a0 cc 
        call Lcca0_compute_player_map_ptr
#ba6b#52eb217
cb fe 
        set 7, (hl)
#ba6d#52ed318
cd bd cc 
        call Lccbd_redraw_game_area
#ba70#52f0216
fd e1 
    pop iy
#ba72#52f2421
fd 36 01 00 
    ld (iy + ROBOT_STRUCT_MAP_PTR + 1), 0  ; destroy the robot that triggered the nuclear bomb
#ba76#52f6318
cd 87 ba 
    call Lba87_nuclear_bomb_visual_effect
#ba79#52f928
3e 01 
    ld a, 1
#ba7b#52fb314
32 52 fd 
    ld (Lfd52_update_radar_buffer_signal), a
#ba7e#52fe318
cd 40 bb 
    call Lbb40_count_robots
#ba81#5301318
cd 09 bb 
    call Lbb09_update_players_warbase_and_factory_counts
#ba84#5304311
c3 93 d2 
    jp Ld293_update_stats_in_right_hud
#ba87#5307
#ba87#5307
#ba87#5307
; --------------------------------
#ba87#5307
; Nuclear bomb visual and sound effect. 
#ba87#5307
; Basically pick random "paper" colors for the game area and keep
#ba87#5307
; changing them, while producing noise in the background.
#ba87#5307
Lba87_nuclear_bomb_visual_effect:
#ba87#5307
    ; Store the original screen attributes to the L5b00 buffer.
#ba87#5307311
11 00 5b 
    ld de, L5b00
#ba8a#530a311
21 21 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021  ; beginning of the game-play area.
#ba8d#530d311
01 14 14 
    ld bc, #1414  ; 20, 20
#ba90#5310
Lba90_loop_y:
#ba90#5310112
c5 
    push bc
#ba91#5311
Lba91_loop_x:
#ba91#5311218
ed a0 
        ldi
#ba93#531315
0c 
        inc c
#ba94#5314214/9
10 fb 
        djnz Lba91_loop_x
#ba96#531628
3e 0c 
        ld a, 12
#ba98#5318318
cd 51 d3 
        call Ld351_add_hl_a
#ba9b#531b111
c1 
    pop bc
#ba9c#531c15
0d 
    dec c
#ba9d#531d213/8
20 f1 
    jr nz, Lba90_loop_y
#ba9f#531f
#ba9f#531f
    ; Visual and sound effect
#ba9f#531f311
01 01 f4 
    ld bc, #f401
#baa2#5322
Lbaa2_nuclear_bomb_visual_effect_loop:
#baa2#5322318
cd ee ba 
    call Lbaee_nuclear_explosion_sfx
#baa5#5325112
c5 
    push bc
#baa6#5326311
21 21 58 
        ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021  ; beginning of the game-play area.
#baa9#5329311
01 14 14 
        ld bc, #1414  ; 20, 20
#baac#532c
Lbaac_random_color_loop:
#baac#532c318
cd 58 d3 
        call Ld358_random
#baaf#532f28
e6 38 
        and #38  ; random number of the form 8 * [0 - 7]  ; random attribute with black ink,
#bab1#5331
                 ; basically.
#bab1#533128
fe 10 
        cp #10
#bab3#5333213/8
38 f7 
        jr c, Lbaac_random_color_loop  ; do not allow black on black or black on blue.
#bab5#533515
bb 
        cp e
#bab6#5336213/8
28 f4 
        jr z, Lbaac_random_color_loop  ; do not allow the same color as before.
#bab8#533815
5f 
        ld e, a
#bab9#5339
        ; add the new random paper color to all the game area:
#bab9#5339
Lbab9_loop_y:
#bab9#5339112
c5 
        push bc
#baba#533a
Lbaba_loop_x:
#baba#533a18
7e 
            ld a, (hl)
#babb#533b28
e6 38 
            and #38
#babd#533d213/8
28 05 
            jr z, Lbac4_skip  ; do not change the black on black areas (sky).
#babf#533f18
7e 
            ld a, (hl)
#bac0#534028
e6 c7 
            and #c7  ; leave ink / brightness the same.
#bac2#534215
b3 
            or e  ; add the new paper color.
#bac3#534318
77 
            ld (hl), a
#bac4#5344
Lbac4_skip:
#bac4#534417
23 
            inc hl
#bac5#5345214/9
10 f3 
            djnz Lbaba_loop_x
#bac7#534728
3e 0c 
            ld a, 12
#bac9#5349318
cd 51 d3 
            call Ld351_add_hl_a
#bacc#534c111
c1 
        pop bc
#bacd#534d15
0d 
        dec c
#bace#534e213/8
20 e9 
        jr nz, Lbab9_loop_y
#bad0#5350111
c1 
    pop bc
#bad1#5351214/9
10 cf 
    djnz Lbaa2_nuclear_bomb_visual_effect_loop
#bad3#5353
#bad3#5353
    ; Restore the original screen attributes from the L5b00 buffer.
#bad3#5353311
21 00 5b 
    ld hl, L5b00
#bad6#5356311
11 21 58 
    ld de, L5800_VIDEOMEM_ATTRIBUTES + #0021
#bad9#5359311
01 14 14 
    ld bc, #1414  ; 20, 20
#badc#535c
Lbadc_loop_y:
#badc#535c112
c5 
    push bc
#badd#535d
Lbadd_loop_x:
#badd#535d218
ed a0 
        ldi
#badf#535f15
0c 
        inc c
#bae0#5360214/9
10 fb 
        djnz Lbadd_loop_x
#bae2#536228
3e 0c 
        ld a, 12
#bae4#536415
83 
        add a, e
#bae5#536515
5f 
        ld e, a
#bae6#5366213/8
30 01 
        jr nc, Lbae9_continue
#bae8#536815
14 
        inc d
#bae9#5369
Lbae9_continue:
#bae9#5369111
c1 
    pop bc
#baea#536a15
0d 
    dec c
#baeb#536b213/8
20 ef 
    jr nz, Lbadc_loop_y
#baed#536d111
c9 
    ret
#baee#536e
#baee#536e
#baee#536e
; --------------------------------
#baee#536e
; Produces part of the sfx of the nuclear explosion.
#baee#536e
; This function is called many times in a loop (above), and the
#baee#536e
; combination of all calls, produces the nuclear explosion sound
#baee#536e
; effect.
#baee#536e
; Input:
#baee#536e
; - c: wave period.
#baee#536e
; - b: number of bytes to read to generate noise.
#baee#536e
Lbaee_nuclear_explosion_sfx:
#baee#536e112
c5 
    push bc
#baef#536f311
21 90 00 
        ld hl, 144
#baf2#5372
Lbaf2_outer_loop:
#baf2#5372112
c5 
        push bc
#baf3#5373
            ; read a value from some position in the ZX Spectrum BIOS (used to
#baf3#5373
            ; get some semi-random values to produce noise):
#baf3#537318
7e 
            ld a, (hl)
#baf4#537428
e6 10 
            and 16
#baf6#5376212
d3 fe 
            out (ULA_PORT), a  ; change MIC/EAR state (to produce sound).
#baf8#537817
23 
            inc hl
#baf9#5379
            ; insert some delay before we change the wave again:
#baf9#5379
Lbaf9_inner_loop:
#baf9#537915
0d 
            dec c
#bafa#537a15
00 
            nop
#bafb#537b15
00 
            nop
#bafc#537c213/8
20 fb 
            jr nz, Lbaf9_inner_loop
#bafe#537e111
c1 
        pop bc
#baff#537f214/9
10 f1 
        djnz Lbaf2_outer_loop
#bb01#5381111
c1 
    pop bc
#bb02#538215
05 
    dec b
#bb03#538315
05 
    dec b
#bb04#538415
05 
    dec b
#bb05#538515
0c 
    inc c
#bb06#538615
0c 
    inc c
#bb07#538715
0c 
    inc c
#bb08#5388111
c9 
    ret
#bb09#5389
#bb09#5389
#bb09#5389
; --------------------------------
#bb09#5389
; Clears the factory/warbase counters, and recomputes it from scratch.
#bb09#5389
Lbb09_update_players_warbase_and_factory_counts:
#bb09#5389
    ; clear warbase/factory counts:
#bb09#5389311
21 3a fd 
    ld hl, Lfd3a_player1_base_factory_counts
#bb0c#538c28
06 07 
    ld b, 7
#bb0e#538e
Lbb0e_clear_player1_loop:
#bb0e#538e211
36 00 
    ld (hl), 0
#bb10#539017
23 
    inc hl
#bb11#5391214/9
10 fb 
    djnz Lbb0e_clear_player1_loop
#bb13#539317
23 
    inc hl  ; skip robot count
#bb14#539428
06 07 
    ld b, 7
#bb16#5396
Lbb16_clear_player2_loop:
#bb16#5396211
36 00 
    ld (hl), 0
#bb18#539817
23 
    inc hl
#bb19#5399214/9
10 fb 
    djnz Lbb16_clear_player2_loop
#bb1b#539b311
11 73 fd 
    ld de, Lfd70_warbases + BUILDING_STRUCT_TYPE
#bb1e#539e28
06 1c 
    ld b, N_WARBASES + N_FACTORIES
#bb20#53a0
Lbb20:
#bb20#53a018
1a 
    ld a, (de)
#bb21#53a115
b7 
    or a
#bb22#53a2311
fa 39 bb 
    jp m, Lbb39_skip
#bb25#53a5311
21 3a fd 
    ld hl, Lfd3a_player1_base_factory_counts
#bb28#53a8210
cb 77 
    bit 6, a  ; bit 6 indicates it belongs to player 1
#bb2a#53aa213/8
20 07 
    jr nz, Lbb33_increment_counter
#bb2c#53ac311
21 42 fd 
    ld hl, Lfd42_player2_base_factory_counts
#bb2f#53af210
cb 6f 
    bit 5, a  ; bit 5 indicates it belongs to player 2 (AI)
#bb31#53b1213/8
28 06 
    jr z, Lbb39_skip
#bb33#53b3
Lbb33_increment_counter:
#bb33#53b328
e6 07 
    and 7  ; ignore the owners, and just keep the type
#bb35#53b5318
cd 51 d3 
    call Ld351_add_hl_a
#bb38#53b8112
34 
    inc (hl)  ; increment the count
#bb39#53b9
Lbb39_skip:
#bb39#53b915
7b 
    ld a, e
#bb3a#53ba28
c6 05 
    add a, 5
#bb3c#53bc15
5f 
    ld e, a
#bb3d#53bd214/9
10 e1 
    djnz Lbb20
#bb3f#53bf111
c9 
    ret
#bb40#53c0
#bb40#53c0
#bb40#53c0
; --------------------------------
#bb40#53c0
; Counts the number of robots of each player and stores it in "Lfd41_player1_robot_count" and 
#bb40#53c0
; "Lfd49_player2_robot_count"
#bb40#53c0
Lbb40_count_robots:
#bb40#53c0311
21 01 da 
    ld hl, Lda00_player1_robots + 1
#bb43#53c3318
cd 50 bb 
    call Lbb50_count_player_robots
#bb46#53c6314
32 41 fd 
    ld (Lfd41_player1_robot_count), a
#bb49#53c9318
cd 50 bb 
    call Lbb50_count_player_robots
#bb4c#53cc314
32 49 fd 
    ld (Lfd49_player2_robot_count), a
#bb4f#53cf111
c9 
    ret
#bb50#53d0
#bb50#53d0
#bb50#53d0
; --------------------------------
#bb50#53d0
; Counts the number of robots a player has
#bb50#53d0
; Input:
#bb50#53d0
; - hl: pointer to the table of robots of a given player (offset by one byte)
#bb50#53d0
; Returns:
#bb50#53d0
; - a: # robots
#bb50#53d0
Lbb50_count_player_robots:
#bb50#53d028
06 18 
    ld b, MAX_ROBOTS_PER_PLAYER
#bb52#53d228
0e 00 
    ld c, 0
#bb54#53d4311
11 10 00 
    ld de, 16
#bb57#53d7
Lbb57_count_player_robots_loop:
#bb57#53d718
7e 
    ld a, (hl)
#bb58#53d815
b7 
    or a
#bb59#53d9213/8
28 01 
    jr z, Lbb5c_no_robot
#bb5b#53db15
0c 
    inc c
#bb5c#53dc
Lbb5c_no_robot:
#bb5c#53dc112
19 
    add hl, de
#bb5d#53dd214/9
10 f8 
    djnz Lbb57_count_player_robots_loop
#bb5f#53df15
79 
    ld a, c
#bb60#53e0111
c9 
    ret
#bb61#53e1
#bb61#53e1
#bb61#53e1
; --------------------------------
#bb61#53e1
; Gets factory # "a", removes any records of being owned by a previous player, and assigns it to 
#bb61#53e1
; player "b".
#bb61#53e1
; Input:
#bb61#53e1
; - a: factory index
#bb61#53e1
; - b: owner
#bb61#53e1
Lbb61_assign_factory_to_player:
#bb61#53e1311
21 87 fd 
    ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE
#bb64#53e4318
cd b9 bb 
    call Lbbb9_mark_ath_building_and_get_ptr
#bb67#53e715
25 
    dec h
#bb68#53e815
25 
    dec h
#bb69#53e915
25 
    dec h
#bb6a#53ea15
25 
    dec h
#bb6b#53eb17
23 
    inc hl
#bb6c#53ec17
23 
    inc hl
#bb6d#53ed318
cd 5d bc 
    call Lbc5d_remove_decoration  ; remove a potential enemy flag
#bb70#53f017
2b 
    dec hl
#bb71#53f117
2b 
    dec hl
#bb72#53f217
2b 
    dec hl
#bb73#53f317
2b 
    dec hl
#bb74#53f4318
cd 5d bc 
    call Lbc5d_remove_decoration  ; remove a potential player flag
#bb77#53f715
78 
    ld a, b  ; owner
#bb78#53f815
b7 
    or a
#bb79#53f9213/8
28 04 
    jr z, Lbb7f_assign_to_player
#bb7b#53fb
    ; the enemy sets the flag in a different position than the player
#bb7b#53fb17
23 
    inc hl
#bb7c#53fc17
23 
    inc hl
#bb7d#53fd17
23 
    inc hl
#bb7e#53fe17
23 
    inc hl
#bb7f#53ff
Lbb7f_assign_to_player:
#bb7f#53ff28
c6 07 
    add a, 7  ; add a flag
#bb81#540115
4f 
    ld c, a
#bb82#5402318
cd 43 bc 
    call Lbc43_add_decoration_to_map  ; Potential optimization: tail recursion.
#bb85#5405111
c9 
    ret
#bb86#5406
#bb86#5406
#bb86#5406
; --------------------------------
#bb86#5406
; Input:
#bb86#5406
; - a: warbase index
#bb86#5406
; - b: player to assign it to
#bb86#5406
Lbb86_assign_warbase_to_player:
#bb86#5406311
21 73 fd 
    ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE
#bb89#5409318
cd b9 bb 
    call Lbbb9_mark_ath_building_and_get_ptr
#bb8c#540c15
7c 
    ld a, h
#bb8d#540d28
d6 08 
    sub 8
#bb8f#540f15
67 
    ld h, a
#bb90#5410318
cd 5d bc 
    call Lbc5d_remove_decoration
#bb93#541315
2d 
    dec l
#bb94#541415
2d 
    dec l
#bb95#541515
2d 
    dec l
#bb96#541615
2d 
    dec l
#bb97#5417318
cd 5d bc 
    call Lbc5d_remove_decoration
#bb9a#541a15
7d 
    ld a, l
#bb9b#541b28
c6 08 
    add a, 8
#bb9d#541d15
6f 
    ld l, a
#bb9e#541e318
cd 5d bc 
    call Lbc5d_remove_decoration
#bba1#542128
0e 08 
    ld c, 8
#bba3#542315
78 
    ld a, b
#bba4#542415
b7 
    or a
#bba5#5425311
c2 43 bc 
    jp nz, Lbc43_add_decoration_to_map
#bba8#542815
2d 
    dec l
#bba9#542915
2d 
    dec l
#bbaa#542a15
2d 
    dec l
#bbab#542b15
2d 
    dec l
#bbac#542c15
4f 
    ld c, a
#bbad#542d318
cd 43 bc 
    call Lbc43_add_decoration_to_map
#bbb0#543015
2d 
    dec l
#bbb1#543115
2d 
    dec l
#bbb2#543215
2d 
    dec l
#bbb3#543315
2d 
    dec l
#bbb4#543428
0e 07 
    ld c, 7
#bbb6#5436311
c3 43 bc 
    jp Lbc43_add_decoration_to_map
#bbb9#5439
#bbb9#5439
#bbb9#5439
; --------------------------------
#bbb9#5439
; Marks whether the a-th warbase/factory belongs to player 1 or 2, and returns
#bbb9#5439
; its pointer in the map.
#bbb9#5439
; Input:
#bbb9#5439
; - a: index of warbase/factory
#bbb9#5439
; - hl: ptr to the beginning of the warbase/factory + 3
#bbb9#5439
; - b: owner
#bbb9#5439
Lbbb9_mark_ath_building_and_get_ptr:
#bbb9#543915
4f 
    ld c, a
#bbba#543a15
87 
    add a, a
#bbbb#543b15
87 
    add a, a
#bbbc#543c15
81 
    add a, c
#bbbd#543d318
cd 51 d3 
    call Ld351_add_hl_a  ; hl = hl + a * 5
#bbc0#544015
78 
    ld a, b
#bbc1#544115
b7 
    or a
#bbc2#544228
3e 40 
    ld a, #40  ; if player == 0, mark bit 6
#bbc4#5444213/8
28 01 
    jr z, Lbbc7_neutral
#bbc6#544615
0f 
    rrca  ; if player != 0, mark bit 5 instead
#bbc7#5447
Lbbc7_neutral:
#bbc7#544715
4f 
    ld c, a
#bbc8#544818
7e 
    ld a, (hl)
#bbc9#544928
e6 1f 
    and 31
#bbcb#544b15
b1 
    or c
#bbcc#544c18
77 
    ld (hl), a  ; update the location in the map with the neutral/occupied mark
#bbcd#544d
Lbbcd_get_map_ptr_of_warbase:
#bbcd#544d17
2b 
    dec hl
#bbce#544e18
4e 
    ld c, (hl)
#bbcf#544f17
2b 
    dec hl
#bbd0#545018
7e 
    ld a, (hl)
#bbd1#545117
2b 
    dec hl
#bbd2#545218
6e 
    ld l, (hl)
#bbd3#545315
67 
    ld h, a
#bbd4#545415
79 
    ld a, c
#bbd5#5455311
c3 a6 cc 
    jp Lcca6_compute_map_ptr
#bbd8#5458
#bbd8#5458
#bbd8#5458
; --------------------------------
#bbd8#5458
; Destroy a factory and replace it with debris.
#bbd8#5458
; Input:
#bbd8#5458
; - a: factory index.
#bbd8#5458
Lbbd8_destroy_factory:
#bbd8#5458311
21 87 fd 
    ld hl, Lfd84_factories + BUILDING_STRUCT_TYPE
#bbdb#545b318
cd 1c bc 
    call Lbc1c_mark_building_as_destroyed_and_get_map_ptr
#bbde#545e112
e5 
    push hl
#bbdf#545f
        ; Remove the potential flags (player/enemy) and the factory type decoration:
#bbdf#545f15
25 
        dec h
#bbe0#546015
25 
        dec h
#bbe1#546115
25 
        dec h
#bbe2#546215
25 
        dec h
#bbe3#546317
23 
        inc hl
#bbe4#546417
23 
        inc hl
#bbe5#5465318
cd 5d bc 
        call Lbc5d_remove_decoration
#bbe8#546817
2b 
        dec hl
#bbe9#546917
2b 
        dec hl
#bbea#546a318
cd 5d bc 
        call Lbc5d_remove_decoration
#bbed#546d17
2b 
        dec hl
#bbee#546e17
2b 
        dec hl
#bbef#546f318
cd 5d bc 
        call Lbc5d_remove_decoration
#bbf2#5472111
e1 
    pop hl
#bbf3#5473311
11 e2 bf 
    ld de, Lbfe2_factory
#bbf6#5476311
c3 27 bc 
    jp Lbc27_replace_building_by_debris
#bbf9#5479
#bbf9#5479
#bbf9#5479
; --------------------------------
#bbf9#5479
; Destroy a warbase and replace it with debris.
#bbf9#5479
; Input:
#bbf9#5479
; - a: warbase index.
#bbf9#5479
Lbbf9_destroy_warbase:
#bbf9#5479311
21 73 fd 
    ld hl, Lfd70_warbases + BUILDING_STRUCT_TYPE
#bbfc#547c318
cd 1c bc 
    call Lbc1c_mark_building_as_destroyed_and_get_map_ptr
#bbff#547f112
e5 
    push hl
#bc00#5480
        ; Remove the potential flags (player/enemy) and the warbase "H" decoration:
#bc00#548015
7c 
        ld a, h
#bc01#548128
d6 08 
        sub 8
#bc03#548315
67 
        ld h, a
#bc04#5484318
cd 5d bc 
        call Lbc5d_remove_decoration
#bc07#548715
2d 
        dec l
#bc08#548815
2d 
        dec l
#bc09#548915
2d 
        dec l
#bc0a#548a15
2d 
        dec l
#bc0b#548b318
cd 5d bc 
        call Lbc5d_remove_decoration
#bc0e#548e15
7d 
        ld a, l
#bc0f#548f28
c6 08 
        add a, 8
#bc11#549115
6f 
        ld l, a
#bc12#5492318
cd 5d bc 
        call Lbc5d_remove_decoration
#bc15#5495111
e1 
    pop hl
#bc16#5496311
11 b2 bf 
    ld de, Lbfb2_warbase
#bc19#5499311
c3 27 bc 
    jp Lbc27_replace_building_by_debris
#bc1c#549c
#bc1c#549c
#bc1c#549c
; --------------------------------
#bc1c#549c
; Marks a given warbase as destroyed, and returns the map pointer where it is located.
#bc1c#549c
; Input:
#bc1c#549c
; - hl: warbases array ptr + 3
#bc1c#549c
; - a: warbase index
#bc1c#549c
Lbc1c_mark_building_as_destroyed_and_get_map_ptr:
#bc1c#549c15
4f 
    ld c, a
#bc1d#549d15
87 
    add a, a
#bc1e#549e15
87 
    add a, a
#bc1f#549f15
81 
    add a, c  ; a *= BUILDING_STRING_SIZE
#bc20#54a0318
cd 51 d3 
    call Ld351_add_hl_a
#bc23#54a3211
36 80 
    ld (hl), #80  ; mark warbase as destroyed
#bc25#54a5213
18 a6 
    jr Lbbcd_get_map_ptr_of_warbase
#bc27#54a7
#bc27#54a7
#bc27#54a7
; --------------------------------
#bc27#54a7
; Replace a building by debris. This is used when factories/warbases are destroyed.
#bc27#54a7
; Input:
#bc27#54a7
; - hl: map pointer of the building.
#bc27#54a7
; - de: pointer to a building definition.
#bc27#54a7
Lbc27_replace_building_by_debris:
#bc27#54a718
1a 
    ld a, (de)
#bc28#54a815
b7 
    or a
#bc29#54a9213/8
28 0a 
    jr z, Lbc35
#bc2b#54ab318
cd 58 d3 
    call Ld358_random  ; select a random debris graphic
#bc2e#54ae28
e6 01 
    and 1
#bc30#54b028
c6 06 
    add a, 6
#bc32#54b2318
cd 91 bd 
    call Lbd91_add_element_to_map
#bc35#54b5
Lbc35:
#bc35#54b5
    ; See if the building has more parts. Each part is a 3 byte block: type, x offset, y offset. If 
#bc35#54b5
    ; the offsets are both 0, it means there are no more parts.
#bc35#54b517
13 
    inc de
#bc36#54b618
1a 
    ld a, (de)
#bc37#54b715
4f 
    ld c, a
#bc38#54b817
13 
    inc de
#bc39#54b918
1a 
    ld a, (de)
#bc3a#54ba15
47 
    ld b, a
#bc3b#54bb17
13 
    inc de
#bc3c#54bc15
b1 
    or c
#bc3d#54bd112/6
c8 
    ret z  ; The offsets are zero, there are no more parts.
#bc3e#54be318
cd 7f bd 
    call Lbd7f_add_map_ptr_offset
#bc41#54c1213
18 e4 
    jr Lbc27_replace_building_by_debris
#bc43#54c3
#bc43#54c3
#bc43#54c3
; --------------------------------
#bc43#54c3
; Finds an empty spot in the building decoration list, and adds a decoration
#bc43#54c3
; record pointing at position "hl" in the map.
#bc43#54c3
; Input:
#bc43#54c3
; - hl: map ptr
#bc43#54c3
; - c: type
#bc43#54c3
Lbc43_add_decoration_to_map:
#bc43#54c3311
11 02 ff 
    ld de, Lff01_building_decorations + 1
#bc46#54c628
06 38 
    ld b, (N_WARBASES + N_FACTORIES) * 2
#bc48#54c8
Lbc48_loop:
#bc48#54c818
1a 
    ld a, (de)
#bc49#54c915
b7 
    or a
#bc4a#54ca213/8
28 06 
    jr z, Lbc52_empty_spot_found
#bc4c#54cc17
13 
    inc de
#bc4d#54cd17
13 
    inc de
#bc4e#54ce17
13 
    inc de
#bc4f#54cf214/9
10 f7 
    djnz Lbc48_loop
#bc51#54d1111
c9 
    ret
#bc52#54d2
Lbc52_empty_spot_found:
#bc52#54d217
1b 
    dec de
#bc53#54d3217
cb f6 
    set 6, (hl)  ; mark bit 6 of the map position
#bc55#54d515
eb 
    ex de, hl
#bc56#54d618
73 
        ld (hl), e  ; map pointer
#bc57#54d717
23 
        inc hl
#bc58#54d818
72 
        ld (hl), d  ; map pointer
#bc59#54d917
23 
        inc hl
#bc5a#54da18
71 
        ld (hl), c  ; type
#bc5b#54db15
eb 
    ex de, hl
#bc5c#54dc111
c9 
    ret
#bc5d#54dd
#bc5d#54dd
#bc5d#54dd
; --------------------------------
#bc5d#54dd
; Searches for a building owner record with ptr == hl, and removes it.
#bc5d#54dd
; Input:
#bc5d#54dd
; - hl: map ptr
#bc5d#54dd
Lbc5d_remove_decoration:
#bc5d#54dd217
fd e5 
    push iy
#bc5f#54df112
c5 
    push bc
#bc60#54e0318
cd f5 cd 
        call Lcdf5_find_building_decoration_with_ptr
#bc63#54e3213/8
20 06 
        jr nz, Lbc6b_not_found
#bc65#54e5421
fd 36 01 00 
        ld (iy + 1), 0  ; removes the record
#bc69#54e9217
cb b6 
        res 6, (hl)  ; removes the mark from the map
#bc6b#54eb
Lbc6b_not_found:
#bc6b#54eb111
c1 
    pop bc
#bc6c#54ec216
fd e1 
    pop iy
#bc6e#54ee111
c9 
    ret
#bc6f#54ef
#bc6f#54ef
#bc6f#54ef
; --------------------------------
#bc6f#54ef
; Initializes the map buffer in Ldd00_map and all the warbase/factory/flag records.
#bc6f#54ef
Lbc6f_initialize_map:
#bc6f#54ef
    ; Clear the map:
#bc6f#54ef311
21 00 dd 
    ld hl, Ldd00_map
#bc72#54f215
54 
    ld d, h
#bc73#54f315
5d 
    ld e, l
#bc74#54f417
13 
    inc de
#bc75#54f5311
01 ff 1f 
    ld bc, MAP_LENGTH * MAP_WIDTH - 1
#bc78#54f8211
36 00 
    ld (hl), 0
#bc7a#54fa223/18
ed b0 
    ldir
#bc7c#54fc
#bc7c#54fc
    ; Clear the minimap:
#bc7c#54fc311
21 00 d8 
    ld hl, Ld800_radar_view1
#bc7f#54ff15
54 
    ld d, h
#bc80#550015
5d 
    ld e, l
#bc81#550117
13 
    inc de
#bc82#5502311
01 ff 00 
    ld bc, 255
#bc85#5505211
36 00 
    ld (hl), 0
#bc87#5507223/18
ed b0 
    ldir
#bc89#5509
#bc89#5509311
21 a9 bd 
    ld hl, Lbda9_map_elements_part1
#bc8c#550c28
16 00 
    ld d, 0  ; indicates x < 256
#bc8e#550e318
cd d6 bc 
    call Lbcd6_add_elements_to_map  ; Write map elements to the map buffer (those with x < 256)
#bc91#5511
#bc91#5511311
21 79 be 
    ld hl, Lbe79_map_elements_part2
#bc94#551428
16 01 
    ld d, 1  ; indicates x >= 256
#bc96#5516318
cd d6 bc 
    call Lbcd6_add_elements_to_map  ; Write map elements to the map buffer (those with x >= 256)
#bc99#5519
#bc99#5519416
fd 21 84 fd 
    ld iy, Lfd84_factories
#bc9d#551d416
dd 21 70 fd 
    ld ix, Lfd70_warbases
#bca1#5521
#bca1#5521311
21 46 bf 
    ld hl, Lbf46_warbases_factories_part1
#bca4#552428
16 00 
    ld d, 0
#bca6#5526318
cd f9 bc 
    call Lbcf9_add_warbases_and_factories_to_map
#bca9#5529
#bca9#5529311
21 6e bf 
    ld hl, Lbf6e_warbases_factories_part2
#bcac#552c28
16 01 
    ld d, 1
#bcae#552e318
cd f9 bc 
    call Lbcf9_add_warbases_and_factories_to_map
#bcb1#5531
#bcb1#553115
af 
    xor a
#bcb2#553215
47 
    ld b, a
#bcb3#5533318
cd 86 bb 
    call Lbb86_assign_warbase_to_player  ; warbase 0 to player 1
#bcb6#553628
3e 01 
    ld a, 1
#bcb8#553815
47 
    ld b, a
#bcb9#5539318
cd 86 bb 
    call Lbb86_assign_warbase_to_player  ; warbase 1 to player 2
#bcbc#553c28
3e 02 
    ld a, 2
#bcbe#553e28
06 01 
    ld b, 1
#bcc0#5540318
cd 86 bb 
    call Lbb86_assign_warbase_to_player  ; warbase 2 to player 2
#bcc3#554328
3e 03 
    ld a, 3
#bcc5#554528
06 01 
    ld b, 1
#bcc7#5547318
cd 86 bb 
    call Lbb86_assign_warbase_to_player  ; warbase 3 to player 2
#bcca#554a318
cd 09 bb 
    call Lbb09_update_players_warbase_and_factory_counts  ; compute the warbase/factory counts
#bccd#554d28
3e 01 
    ld a, 1
#bccf#554f314
32 52 fd 
    ld (Lfd52_update_radar_buffer_signal), a
#bcd2#5552318
cd 24 b0 
    call Lb024_add_player_to_map_and_update_radar  ; Potential optimization: tail recursion.
#bcd5#5555111
c9 
    ret
#bcd6#5556
#bcd6#5556
#bcd6#5556
; --------------------------------
#bcd6#5556
; Adds a list of map elements to the map buffer.
#bcd6#5556
; Input:
#bcd6#5556
; - d: A 0 or a 1. Indicates whether x coordinates start at 0 or at 256.
#bcd6#5556
Lbcd6_add_elements_to_map:
#bcd6#5556
Lbcd6_loop:
#bcd6#555618
7e 
    ld a, (hl)
#bcd7#555715
b7 
    or a
#bcd8#5558112/6
c8 
    ret z  ; a 0 at the end indicates end of data.
#bcd9#555915
4f 
    ld c, a  ; element type
#bcda#555a17
23 
    inc hl
#bcdb#555b18
5e 
    ld e, (hl)  ; x
#bcdc#555c17
23 
    inc hl
#bcdd#555d18
7e 
    ld a, (hl)  ; y % 256
#bcde#555e17
23 
    inc hl  ; we have read 3 bytes from the data in: c, e, a.
#bcdf#555f112
e5 
    push hl
#bce0#5560112
d5 
    push de
#bce1#5561311
21 00 dd 
        ld hl, Ldd00_map
#bce4#556415
87 
        add a, a
#bce5#556515
84 
        add a, h
#bce6#556615
67 
        ld h, a
#bce7#5567112
19 
        add hl, de  ; hl now has the pointer in the map to (e, a + d*256).
#bce8#556815
79 
        ld a, c
#bce9#556915
b7 
        or a
#bcea#556a311
fa f2 bc 
        jp m, Lbcf2  ; Those elements with msb set to 1 are complex structures, and are handled 
#bced#556d
                     ; separately.
#bced#556d318
cd 91 bd 
        call Lbd91_add_element_to_map
#bcf0#5570213
18 03 
        jr Lbcf5_continue
#bcf2#5572
Lbcf2:
#bcf2#5572318
cd 61 bd 
        call Lbd61_add_complex_structure_to_map
#bcf5#5575
Lbcf5_continue:
#bcf5#5575111
d1 
    pop de
#bcf6#5576111
e1 
    pop hl
#bcf7#5577213
18 dd 
    jr Lbcd6_loop
#bcf9#5579
#bcf9#5579
#bcf9#5579
; --------------------------------
#bcf9#5579
; Adds warbases and factories to the map.
#bcf9#5579
; - It also adds all the factories to the buildings list (but not the warbases)
#bcf9#5579
; Input:
#bcf9#5579
; - d: 0 if element x < 256, 1 if element x >= 256
#bcf9#5579
; - hl: ptr to the elements to add.
#bcf9#5579
; - ix: ptr to the factory list
#bcf9#5579
; - iy: ptr to the warbase list
#bcf9#5579
Lbcf9_add_warbases_and_factories_to_map:
#bcf9#557918
7e 
    ld a, (hl)
#bcfa#557a15
b7 
    or a
#bcfb#557b112/6
f8 
    ret m  ; a 1 in the most significant bit indicates termination
#bcfc#557c15
4f 
    ld c, a  ; type
#bcfd#557d17
23 
    inc hl
#bcfe#557e18
5e 
    ld e, (hl)  ; x (the most significant byte of x is passed as argument in d)
#bcff#557f17
23 
    inc hl
#bd00#558018
7e 
    ld a, (hl)
#bd01#558115
47 
    ld b, a  ; y
#bd02#558217
23 
    inc hl
#bd03#5583112
e5 
    push hl
#bd04#5584112
d5 
    push de
#bd05#5585311
21 00 dd 
        ld hl, Ldd00_map
#bd08#558815
87 
        add a, a
#bd09#558915
84 
        add a, h
#bd0a#558a15
67 
        ld h, a
#bd0b#558b112
19 
        add hl, de  ; hl now points to the position in the map corresponding to the x, y, 
#bd0c#558c
                    ; coordinates of the element
#bd0c#558c15
79 
        ld a, c
#bd0d#558d15
b7 
        or a
#bd0e#558e213/8
28 2e 
        jr z, Lbd3e_warbase
#bd10#5590321
fd 73 00 
        ld (iy + 0), e  ; x
#bd13#5593321
fd 72 01 
        ld (iy + 1), d  ; x
#bd16#5596321
fd 70 02 
        ld (iy + 2), b  ; y
#bd19#5599321
fd 71 03 
        ld (iy + 3), c  ; type
#bd1c#559c421
fd 36 04 00 
        ld (iy + 4), 0
#bd20#55a0212
fd 23 
        inc iy
#bd22#55a2212
fd 23 
        inc iy
#bd24#55a4212
fd 23 
        inc iy
#bd26#55a6212
fd 23 
        inc iy
#bd28#55a8212
fd 23 
        inc iy
#bd2a#55aa112
c5 
        push bc
#bd2b#55ab112
e5 
        push hl
#bd2c#55ac28
3e 81 
            ld a, #81  ; add a factory
#bd2e#55ae318
cd 61 bd 
            call Lbd61_add_complex_structure_to_map
#bd31#55b1111
e1 
        pop hl
#bd32#55b2111
c1 
        pop bc
#bd33#55b315
25 
        dec h
#bd34#55b415
25 
        dec h
#bd35#55b515
25 
        dec h
#bd36#55b615
25 
        dec h
#bd37#55b7
        ; notice c still holds the type here
#bd37#55b7318
cd 43 bc 
        call Lbc43_add_decoration_to_map
#bd3a#55ba111
d1 
    pop de
#bd3b#55bb111
e1 
    pop hl
#bd3c#55bc213
18 bb 
    jr Lbcf9_add_warbases_and_factories_to_map
#bd3e#55be
Lbd3e_warbase:
#bd3e#55be321
dd 73 00 
        ld (ix + 0), e  ; x
#bd41#55c1321
dd 72 01 
        ld (ix + 1), d  ; x
#bd44#55c4321
dd 70 02 
        ld (ix + 2), b  ; y
#bd47#55c7321
dd 71 03 
        ld (ix + 3), c  ; type
#bd4a#55ca421
dd 36 04 00 
        ld (ix + 4), 0
#bd4e#55ce212
dd 23 
        inc ix
#bd50#55d0212
dd 23 
        inc ix
#bd52#55d2212
dd 23 
        inc ix
#bd54#55d4212
dd 23 
        inc ix
#bd56#55d6212
dd 23 
        inc ix
#bd58#55d828
3e 80 
        ld a, #80  ; add a warbase
#bd5a#55da318
cd 61 bd 
        call Lbd61_add_complex_structure_to_map
#bd5d#55dd111
d1 
    pop de
#bd5e#55de111
e1 
    pop hl
#bd5f#55df213
18 98 
    jr Lbcf9_add_warbases_and_factories_to_map
#bd61#55e1
#bd61#55e1
#bd61#55e1
; --------------------------------
#bd61#55e1
; Adds a complex structure to the map buffer.
#bd61#55e1
Lbd61_add_complex_structure_to_map:
#bd61#55e1112
e5 
    push hl
#bd62#55e2311
21 9c bf 
        ld hl, Lbf9c_map_complex_structure_ptrs
#bd65#55e528
e6 7f 
        and #7f  ; remove the msb
#bd67#55e7318
cd 48 d3 
        call Ld348_get_ptr_from_table
#bd6a#55ea15
eb 
        ex de, hl
#bd6b#55eb111
e1 
    pop hl
#bd6c#55ec
Lbd6c_loop:
#bd6c#55ec18
1a 
    ld a, (de)
#bd6d#55ed15
b7 
    or a  ; element type
#bd6e#55ee318/11
c4 91 bd 
    call nz, Lbd91_add_element_to_map  ; if the structure is != 0, end.
#bd71#55f117
13 
    inc de
#bd72#55f218
1a 
    ld a, (de)
#bd73#55f315
4f 
    ld c, a  ; x
#bd74#55f417
13 
    inc de
#bd75#55f518
1a 
    ld a, (de)
#bd76#55f615
47 
    ld b, a  ; y
#bd77#55f717
13 
    inc de
#bd78#55f815
b1 
    or c
#bd79#55f9112/6
c8 
    ret z  ; if x == y == 0, we are done
#bd7a#55fa318
cd 7f bd 
    call Lbd7f_add_map_ptr_offset
#bd7d#55fd213
18 ed 
    jr Lbd6c_loop
#bd7f#55ff
#bd7f#55ff
#bd7f#55ff
; --------------------------------
#bd7f#55ff
; Adds an (x, y) offset to a map pointer.
#bd7f#55ff
; Input:
#bd7f#55ff
; - hl: map pointer
#bd7f#55ff
; - c: offset in x
#bd7f#55ff
; - b: offset in y
#bd7f#55ff
Lbd7f_add_map_ptr_offset:
#bd7f#55ff112
d5 
    push de
#bd80#5600
        ; hl += c
#bd80#5600
        ; extend c to 16 bits in de:
#bd80#560015
59 
        ld e, c
#bd81#560128
16 00 
        ld d, 0
#bd83#560315
79 
        ld a, c
#bd84#560415
b7 
        or a
#bd85#5605311
f2 8a bd 
        jp p, Lbd8a_c_positive
#bd88#560828
16 ff 
        ld d, 255
#bd8a#560a
Lbd8a_c_positive:
#bd8a#560a112
19 
        add hl, de
#bd8b#560b15
7c 
        ld a, h
#bd8c#560c15
80 
        add a, b
#bd8d#560d15
80 
        add a, b
#bd8e#560e15
67 
        ld h, a  ; h += b*2
#bd8f#560f111
d1 
    pop de
#bd90#5610111
c9 
    ret
#bd91#5611
#bd91#5611
#bd91#5611
; --------------------------------
#bd91#5611
; Adds an element (building, terrain) to the map.
#bd91#5611
; This methods adds the desired element to a 2x2 grid, and marks the bottom-left with bit 5 to 0, 
#bd91#5611
; and the rest with bit 5 to 1.
#bd91#5611
; Input:
#bd91#5611
; - hl: map ptr
#bd91#5611
; - a: map element.
#bd91#5611
Lbd91_add_element_to_map:
#bd91#5611112
d5 
    push de
#bd92#561215
5f 
        ld e, a
#bd93#5613311
01 02 02 
        ld bc, #0202
#bd96#5616112
e5 
        push hl
#bd97#5617
Lbd97_loop_y:
#bd97#5617112
c5 
            push bc
#bd98#5618112
e5 
            push hl
#bd99#5619
Lbd99_loop_x:
#bd99#561918
73 
                ld (hl), e  ; write the type of map element we have in this position.
#bd9a#561a210
cb eb 
                set 5, e  ; only the bottom-left corner has bit 5 set to 0, the rest have it to 1.
#bd9c#561c17
23 
                inc hl
#bd9d#561d214/9
10 fa 
                djnz Lbd99_loop_x
#bd9f#561f111
e1 
            pop hl
#bda0#5620111
c1 
            pop bc
#bda1#562115
25 
            dec h  ; y -= 1
#bda2#562215
25 
            dec h
#bda3#562315
0d 
            dec c
#bda4#5624213/8
20 f1 
            jr nz, Lbd97_loop_y
#bda6#5626111
e1 
        pop hl
#bda7#5627111
d1 
    pop de
#bda8#5628111
c9 
    ret
#bda9#5629
#bda9#5629
#bda9#5629
    ; --------------------------------
#bda9#5629
    ; Game map data:
#bda9#5629
    ; Each block of 3 bytes represents a map element: type, x, y.
#bda9#5629
    ; - Element types with the most significant bit set to 1 represent complex structures, which 
#bda9#5629
    ;   are specified
#bda9#5629
    ;   in "Lbf9c_map_complex_structure_ptrs".
#bda9#5629
    ; - A 0 indicates termination.
#bda9#5629
Lbda9_map_elements_part1:  ; elements with x < 256
#bda9#56293
    db #86, #0c, #01
#bdac#562c3
    db #86, #0c, #09
#bdaf#562f3
    db #11, #10, #0e
#bdb2#56323
    db #11, #20, #03
#bdb5#56353
    db #82, #22, #0a
#bdb8#56383
    db #05, #20, #0c
#bdbb#563b3
    db #04, #2a, #0a
#bdbe#563e3
    db #07, #2a, #0c
#bdc1#56413
    db #06, #2a, #0e
#bdc4#56443
    db #03, #2c, #0a
#bdc7#56473
    db #09, #2c, #0c
#bdca#564a3
    db #07, #2c, #0e
#bdcd#564d3
    db #83, #2e, #0a
#bdd0#56503
    db #03, #30, #08
#bdd3#56533
    db #04, #32, #08
#bdd6#56563
    db #02, #36, #0c
#bdd9#56593
    db #06, #36, #0e
#bddc#565c3
    db #03, #38, #0e
#bddf#565f3
    db #12, #3f, #02
#bde2#56623
    db #12, #41, #02
#bde5#56653
    db #12, #46, #01
#bde8#56683
    db #11, #46, #0f
#bdeb#566b3
    db #11, #48, #0f
#bdee#566e3
    db #87, #48, #02
#bdf1#56713
    db #87, #53, #08
#bdf4#56743
    db #06, #53, #02
#bdf7#56773
    db #05, #53, #04
#bdfa#567a3
    db #83, #55, #02
#bdfd#567d3
    db #02, #55, #06
#be00#56803
    db #04, #5b, #06
#be03#56833
    db #07, #5d, #02
#be06#56863
    db #03, #5d, #04
#be09#56893
    db #85, #5e, #0f
#be0c#568c3
    db #88, #68, #09
#be0f#568f3
    db #88, #6e, #09
#be12#56923
    db #0d, #6e, #09
#be15#56953
    db #85, #6a, #04
#be18#56983
    db #85, #6c, #0d
#be1b#569b3
    db #84, #79, #09
#be1e#569e3
    db #11, #7f, #0c
#be21#56a13
    db #11, #81, #07
#be24#56a43
    db #85, #86, #04
#be27#56a73
    db #12, #85, #0b
#be2a#56aa3
    db #12, #85, #0d
#be2d#56ad3
    db #87, #97, #06
#be30#56b03
    db #82, #a5, #02
#be33#56b33
    db #83, #a7, #06
#be36#56b63
    db #83, #ad, #08
#be39#56b93
    db #83, #b3, #0a
#be3c#56bc3
    db #12, #bf, #08
#be3f#56bf3
    db #89, #bf, #03
#be42#56c23
    db #89, #c1, #08
#be45#56c53
    db #89, #bf, #0d
#be48#56c83
    db #89, #c7, #03
#be4b#56cb3
    db #89, #c7, #0d
#be4e#56ce3
    db #89, #cf, #03
#be51#56d13
    db #89, #c9, #08
#be54#56d43
    db #89, #cf, #0d
#be57#56d73
    db #12, #d1, #08
#be5a#56da3
    db #89, #d7, #0d
#be5d#56dd3
    db #89, #df, #0d
#be60#56e03
    db #11, #e5, #0b
#be63#56e33
    db #84, #e9, #09
#be66#56e63
    db #12, #e9, #07
#be69#56e93
    db #82, #eb, #0a
#be6c#56ec3
    db #82, #f3, #0a
#be6f#56ef3
    db #02, #fb, #0c
#be72#56f23
    db #04, #fb, #0e
#be75#56f53
    db #03, #fd, #0e
#be78#56f81
    db #00
#be79#56f9
#be79#56f9
Lbe79_map_elements_part2:  ; elements with x >= 256
#be79#56f93
    db #83, #0e, #02
#be7c#56fc3
    db #83, #0c, #0a
#be7f#56ff3
    db #83, #10, #0a
#be82#57023
    db #08, #08, #0e
#be85#57053
    db #09, #0a, #0c
#be88#57083
    db #0a, #0a, #0e
#be8b#570b3
    db #08, #18, #0c
#be8e#570e3
    db #0b, #18, #0e
#be91#57113
    db #12, #21, #03
#be94#57143
    db #11, #2b, #09
#be97#57173
    db #12, #33, #0d
#be9a#571a3
    db #11, #40, #0a
#be9d#571d3
    db #11, #42, #0c
#bea0#57203
    db #11, #44, #0e
#bea3#57233
    db #12, #49, #0c
#bea6#57263
    db #85, #50, #05
#bea9#57293
    db #85, #50, #09
#beac#572c3
    db #85, #58, #05
#beaf#572f3
    db #85, #58, #09
#beb2#57323
    db #84, #60, #09
#beb5#57353
    db #12, #5e, #01
#beb8#57383
    db #12, #5e, #03
#bebb#573b3
    db #11, #58, #01
#bebe#573e3
    db #11, #52, #03
#bec1#57413
    db #11, #52, #0d
#bec4#57443
    db #11, #56, #0d
#bec7#57473
    db #11, #56, #0f
#beca#574a3
    db #11, #58, #0f
#becd#574d3
    db #11, #5a, #0f
#bed0#57503
    db #11, #5a, #0b
#bed3#57533
    db #8a, #64, #05
#bed6#57563
    db #11, #7b, #04
#bed9#57593
    db #03, #7b, #0e
#bedc#575c3
    db #04, #7d, #0c
#bedf#575f3
    db #02, #7d, #0e
#bee2#57623
    db #82, #7f, #0a
#bee5#57653
    db #05, #87, #0c
#bee8#57683
    db #02, #87, #0e
#beeb#576b3
    db #04, #89, #0e
#beee#576e3
    db #12, #8a, #01
#bef1#57713
    db #11, #91, #0f
#bef4#57743
    db #12, #99, #01
#bef7#57773
    db #88, #96, #05
#befa#577a3
    db #88, #99, #09
#befd#577d3
    db #88, #99, #0d
#bf00#57803
    db #87, #a4, #08
#bf03#57833
    db #87, #a8, #02
#bf06#57863
    db #87, #ac, #08
#bf09#57893
    db #87, #b0, #02
#bf0c#578c3
    db #09, #b4, #0e
#bf0f#578f3
    db #83, #b6, #0a
#bf12#57923
    db #83, #bc, #0a
#bf15#57953
    db #04, #c0, #0a
#bf18#57983
    db #03, #c2, #0a
#bf1b#579b3
    db #02, #c2, #0c
#bf1e#579e3
    db #88, #c5, #03
#bf21#57a13
    db #11, #d0, #0a
#bf24#57a43
    db #11, #d3, #0d
#bf27#57a73
    db #8a, #de, #01
#bf2a#57aa3
    db #8a, #dc, #03
#bf2d#57ad3
    db #8a, #da, #05
#bf30#57b03
    db #8a, #da, #09
#bf33#57b33
    db #8a, #dc, #0b
#bf36#57b63
    db #8a, #de, #0d
#bf39#57b93
    db #8a, #e0, #0f
#bf3c#57bc3
    db #8a, #e0, #05
#bf3f#57bf3
    db #86, #f7, #01
#bf42#57c23
    db #86, #f7, #09
#bf45#57c51
    db #00
#bf46#57c6
#bf46#57c6
    ; Warbases and factories:
#bf46#57c6
    ; 0 are warbases, and 1 - 6 are factories
#bf46#57c6
Lbf46_warbases_factories_part1:
#bf46#57c63
    db #00, #16, #09
#bf49#57c93
    db #04, #27, #06
#bf4c#57cc3
    db #06, #35, #03
#bf4f#57cf3
    db #01, #3e, #0a
#bf52#57d23
    db #05, #4f, #03
#bf55#57d53
    db #03, #61, #03
#bf58#57d83
    db #02, #7d, #03
#bf5b#57db3
    db #06, #8c, #0b
#bf5e#57de3
    db #01, #a0, #05
#bf61#57e13
    db #03, #b4, #03
#bf64#57e43
    db #04, #d9, #03
#bf67#57e73
    db #05, #e3, #09
#bf6a#57ea3
    db #06, #f1, #03
#bf6d#57ed1
    db #ff
#bf6e#57ee
#bf6e#57ee
Lbf6e_warbases_factories_part2:
#bf6e#57ee3
    db #00, #05, #08
#bf71#57f13
    db #03, #1a, #03
#bf74#57f43
    db #01, #20, #0d
#bf77#57f73
    db #02, #28, #03
#bf7a#57fa3
    db #04, #37, #07
#bf7d#57fd3
    db #06, #42, #03
#bf80#58003
    db #00, #71, #08
#bf83#58033
    db #03, #82, #03
#bf86#58063
    db #05, #91, #07
#bf89#58093
    db #01, #a0, #03
#bf8c#580c3
    db #02, #b4, #05
#bf8f#580f3
    db #04, #be, #03
#bf92#58123
    db #05, #c8, #0a
#bf95#58153
    db #06, #d2, #03
#bf98#58183
    db #00, #ee, #08
#bf9b#581b1
    db #ff
#bf9c#581c
#bf9c#581c
Lbf9c_map_complex_structure_ptrs:
#bf9c#581c2
    dw Lbfb2_warbase
#bf9e#581e2
    dw Lbfe2_factory
#bfa0#58202
    dw Lbff4
#bfa2#58222
    dw Lc018
#bfa4#58242
    dw Lc03c
#bfa6#58262
    dw Lc048
#bfa8#58282
    dw Lc054
#bfaa#582a2
    dw Lc060
#bfac#582c2
    dw Lc06c
#bfae#582e2
    dw Lc078
#bfb0#58302
    dw Lc084
#bfb2#5832
#bfb2#5832
    ; Each complex structure is a list of map elements. Termination is marked by an
#bfb2#5832
    ; element with x == y == 0.
#bfb2#5832
Lbfb2_warbase:
#bfb2#58323
    db #00, #fc, #fc
#bfb5#58353
    db #10, #00, #fe
#bfb8#58383
    db #10, #02, #05
#bfbb#583b3
    db #0f, #00, #fe
#bfbe#583e3
    db #0f, #00, #fe
#bfc1#58413
    db #0f, #00, #fe
#bfc4#58443
    db #10, #02, #05
#bfc7#58473
    db #0f, #00, #fe
#bfca#584a3
    db #10, #00, #fe
#bfcd#584d3
    db #10, #02, #05
#bfd0#58503
    db #0f, #00, #fe
#bfd3#58533
    db #0f, #00, #fe
#bfd6#58563
    db #0f, #00, #fe
#bfd9#58593
    db #10, #02, #03
#bfdc#585c3
    db #10, #00, #fe
#bfdf#585f3
    db #10, #00, #00
#bfe2#5862
#bfe2#5862
Lbfe2_factory:
#bfe2#58623
    db #00, #fe, #00
#bfe5#58653
    db #0f, #00, #fe
#bfe8#58683
    db #10, #02, #00
#bfeb#586b3
    db #10, #02, #00
#bfee#586e3
    db #10, #00, #02
#bff1#58713
    db #0f, #00, #00
#bff4#5874
#bff4#5874
Lbff4:
#bff4#58743
    db #02, #02, #00
#bff7#58773
    db #03, #02, #00
#bffa#587a3
    db #04, #02, #00
#bffd#587d3
    db #05, #fa, #02
#c000#58803
    db #04, #02, #00
#c003#58833
    db #05, #02, #00
#c006#58863
    db #02, #02, #00
#c009#58893
    db #03, #fa, #02
#c00c#588c3
    db #03, #02, #00
#c00f#588f3
    db #02, #02, #00
#c012#58923
    db #05, #02, #00
#c015#58953
    db #04, #00, #00
#c018#5898
#c018#5898
Lc018:
#c018#58983
    db #08, #02, #00
#c01b#589b3
    db #09, #02, #00
#c01e#589e3
    db #0a, #02, #00
#c021#58a13
    db #0b, #fa, #02
#c024#58a43
    db #0a, #02, #00
#c027#58a73
    db #0b, #02, #00
#c02a#58aa3
    db #08, #02, #00
#c02d#58ad3
    db #09, #fa, #02
#c030#58b03
    db #09, #02, #00
#c033#58b33
    db #08, #02, #00
#c036#58b63
    db #0b, #02, #00
#c039#58b93
    db #0a, #00, #00
#c03c#58bc
#c03c#58bc
Lc03c:
#c03c#58bc3
    db #12, #00, #02
#c03f#58bf3
    db #12, #00, #02
#c042#58c23
    db #12, #00, #02
#c045#58c53
    db #12, #00, #00
#c048#58c8
#c048#58c8
Lc048:
#c048#58c83
    db #12, #02, #00
#c04b#58cb3
    db #12, #02, #00
#c04e#58ce3
    db #12, #02, #00
#c051#58d13
    db #12, #00, #00
#c054#58d4
#c054#58d4
Lc054:
#c054#58d43
    db #15, #00, #02
#c057#58d73
    db #15, #00, #02
#c05a#58da3
    db #15, #00, #02
#c05d#58dd3
    db #15, #00, #00
#c060#58e0
#c060#58e0
Lc060:
#c060#58e03
    db #0c, #00, #02
#c063#58e33
    db #0d, #00, #02
#c066#58e63
    db #0d, #00, #02
#c069#58e93
    db #0e, #00, #00
#c06c#58ec
#c06c#58ec
Lc06c:
#c06c#58ec3
    db #0c, #02, #00
#c06f#58ef3
    db #0d, #02, #00
#c072#58f23
    db #0d, #02, #00
#c075#58f53
    db #0e, #00, #00
#c078#58f8
#c078#58f8
Lc078:
#c078#58f83
    db #11, #02, #00
#c07b#58fb3
    db #11, #02, #00
#c07e#58fe3
    db #11, #02, #00
#c081#59013
    db #11, #00, #00
#c084#5904
#c084#5904
Lc084:
#c084#59043
    db #11, #02, #00
#c087#59073
    db #12, #02, #00
#c08a#590a3
    db #11, #00, #00
#c08d#590d
#c08d#590d
#c08d#590d115
    ds #c100 - $, 0  ; 115 bytes of empty space until the game code continues.
#c100#5980
#c100#5980
#c100#5980
; --------------------------------
#c100#5980
Lc100_title_screen:
#c100#5980318
cd b9 d0 
    call Ld0b9_clear_screen
#c103#5983318
cd e3 c1 
    call Lc1e3_draw_game_title
#c106#5986
Lc106_title_screen_redraw_options:
#c106#5986318
cd 2d d4 
    call Ld42d_execute_ui_script
#c109#5989
    ; Script start:
#c109#59892
        db CMD_SET_ATTRIBUTE, #46
#c10b#598b2
        db CMD_SET_SCALE, #21
#c10d#598d3
        db CMD_SET_POSITION, #0b, #08
#c110#599013
        db "0..START GAME"
#c11d#599d2
        db CMD_SET_SCALE, #00
#c11f#599f1
        db CMD_END
#c120#59a0
    ; Script end:
#c120#59a028
0e 01 
    ld c, 1
#c122#59a2318
cd 36 c3 
    call Lc336_highlight_if_selected
#c125#59a5318
cd 2d d4 
    call Ld42d_execute_ui_script
#c128#59a8
    ; Script start:
#c128#59a81
        db CMD_NEXT_LINE
#c129#59a91
        db CMD_NEXT_LINE
#c12a#59aa1
        db CMD_NEXT_LINE
#c12b#59ab11
        db "1..KEYBOARD"
#c136#59b61
        db CMD_END
#c137#59b7
    ; Script end:
#c137#59b728
0e 02 
    ld c, 2
#c139#59b9318
cd 36 c3 
    call Lc336_highlight_if_selected
#c13c#59bc318
cd 2d d4 
    call Ld42d_execute_ui_script
#c13f#59bf
    ; Script start:
#c13f#59bf1
        db CMD_NEXT_LINE
#c140#59c01
        db CMD_NEXT_LINE
#c141#59c115
        db "2..KEMPSTON J/S"
#c150#59d01
        db CMD_END
#c151#59d1
    ; Script end:
#c151#59d128
0e 03 
    ld c, 3
#c153#59d3318
cd 36 c3 
    call Lc336_highlight_if_selected
#c156#59d6318
cd 2d d4 
    call Ld42d_execute_ui_script
#c159#59d9
    ; Script start:
#c159#59d91
        db CMD_NEXT_LINE
#c15a#59da1
        db CMD_NEXT_LINE
#c15b#59db14
        db "3..INTERFACE 2"
#c169#59e91
        db CMD_NEXT_LINE
#c16a#59ea1
        db CMD_NEXT_LINE
#c16b#59eb2
        db CMD_SET_ATTRIBUTE, #46
#c16d#59ed16
        db "4..REDEFINE KEYS"
#c17d#59fd1
        db CMD_NEXT_LINE
#c17e#59fe1
        db CMD_NEXT_LINE
#c17f#59ff18
        db "5..LOAD SAVED GAME"
#c191#5a111
        db CMD_END
#c192#5a12
    ; Script end:
#c192#5a12
Lc192_wait_for_key_not_pressed_loop:
#c192#5a1215
76 
    halt
#c193#5a13318
cd 20 c8 
    call Lc820_title_color_cycle
#c196#5a16318
cd 8e 02 
    call L028e_BIOS_POLL_KEYBOARD
#c199#5a1915
7b 
    ld a, e
#c19a#5a1a15
b7 
    or a
#c19b#5a1b311
f2 92 c1 
    jp p, Lc192_wait_for_key_not_pressed_loop
#c19e#5a1e318
cd a7 c4 
    call Lc4a7_title_music_loop
#c1a1#5a21
Lc1a1_wait_for_key_press_loop:
#c1a1#5a2115
76 
    halt
#c1a2#5a22318
cd 20 c8 
    call Lc820_title_color_cycle
#c1a5#5a25318
cd 8e 02 
    call L028e_BIOS_POLL_KEYBOARD
#c1a8#5a2815
7b 
    ld a, e
#c1a9#5a2915
b7 
    or a
#c1aa#5a2a311
fa a1 c1 
    jp m, Lc1a1_wait_for_key_press_loop
#c1ad#5a2d311
21 05 02 
    ld hl, L0205_BIOS_KEYCODE_TABLE
#c1b0#5a3015
85 
    add a, l
#c1b1#5a3115
6f 
    ld l, a
#c1b2#5a3218
7e 
    ld a, (hl)
#c1b3#5a3328
fe 35 
    cp "5"
#c1b5#5a35213/8
28 46 
    jr z, Lc1fd_select_load_saved_game
#c1b7#5a3728
fe 30 
    cp "0"
#c1b9#5a39213/8
28 16 
    jr z, Lc1d1_select_start_game
#c1bb#5a3b28
fe 31 
    cp "1"
#c1bd#5a3d213/8
28 14 
    jr z, Lc1d3_select_keyboard
#c1bf#5a3f28
fe 32 
    cp "2"
#c1c1#5a41213/8
28 14 
    jr z, Lc1d7_select_kempston
#c1c3#5a4328
fe 33 
    cp "3"
#c1c5#5a45213/8
28 14 
    jr z, Lc1db_select_interface2
#c1c7#5a4728
fe 34 
    cp "4"
#c1c9#5a49213/8
20 d6 
    jr nz, Lc1a1_wait_for_key_press_loop
#c1cb#5a4b318
cd 4a c3 
    call Lc34a_redefine_keys
#c1ce#5a4e311
c3 00 c1 
    jp Lc100_title_screen
#c1d1#5a51
#c1d1#5a51
Lc1d1_select_start_game:
#c1d1#5a5115
af 
    xor a
#c1d2#5a52111
c9 
    ret
#c1d3#5a53
#c1d3#5a53
Lc1d3_select_keyboard:
#c1d3#5a5328
3e 01 
    ld a, INPUT_KEYBOARD
#c1d5#5a55213
18 06 
    jr Lc1dd_select_input
#c1d7#5a57
#c1d7#5a57
Lc1d7_select_kempston:
#c1d7#5a5728
3e 02 
    ld a, INPUT_KEMPSTON
#c1d9#5a59213
18 02 
    jr Lc1dd_select_input
#c1db#5a5b
#c1db#5a5b
Lc1db_select_interface2:
#c1db#5a5b28
3e 03 
    ld a, INPUT_INTERFACE2
#c1dd#5a5d
Lc1dd_select_input:
#c1dd#5a5d314
32 e4 d3 
    ld (Ld3e4_input_type), a
#c1e0#5a60311
c3 06 c1 
    jp Lc106_title_screen_redraw_options
#c1e3#5a63
#c1e3#5a63
#c1e3#5a63
; --------------------------------
#c1e3#5a63
Lc1e3_draw_game_title:
#c1e3#5a63318
cd 2d d4 
    call Ld42d_execute_ui_script
#c1e6#5a66
    ; Script start:
#c1e6#5a663
        db CMD_SET_POSITION, #01, #0a
#c1e9#5a692
        db CMD_SET_ATTRIBUTE, #47
#c1eb#5a6b2
        db CMD_SET_SCALE, #32
#c1ed#5a6d6
        db "NETHER"
#c1f3#5a733
        db CMD_SET_POSITION, #05, #0b
#c1f6#5a765
        db "EARTH"
#c1fb#5a7b1
        db CMD_END
#c1fc#5a7c
    ; Script end:
#c1fc#5a7c111
c9 
    ret
#c1fd#5a7d
#c1fd#5a7d
#c1fd#5a7d
; --------------------------------
#c1fd#5a7d
Lc1fd_select_load_saved_game:
#c1fd#5a7d318
cd e3 c1 
    call Lc1e3_draw_game_title
#c200#5a80318
cd 2d d4 
    call Ld42d_execute_ui_script
#c203#5a83
    ; Script start:
#c203#5a833
        db CMD_SET_POSITION, #16, #07
#c206#5a862
        db CMD_SET_ATTRIBUTE, #45
#c208#5a882
        db CMD_SET_SCALE, #21
#c20a#5a8a19
        db "PRESS PLAY ON TAPE "
#c21d#5a9d1
        db CMD_END
#c21e#5a9e
    ; Script end:
#c21e#5a9e28
3e 02 
    ld a, 2
#c220#5aa0212
d3 fe 
    out (ULA_PORT), a  ; change border color
#c222#5aa2416
dd 21 00 5b 
    ld ix, L5b00  ; Address to store the data read from tape
#c226#5aa6311
11 02 00 
    ld de, 2  ; read 2 bytes (checksum)
#c229#5aa915
af 
    xor a
#c22a#5aaa15
37 
    scf
#c22b#5aab15
14 
    inc d
#c22c#5aac15
08 
    ex af, af'
#c22d#5aad15
15 
    dec d
#c22e#5aae15
f3 
    di
#c22f#5aaf318
cd 62 05 
    call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS
#c232#5ab2
#c232#5ab2416
dd 21 2b d9 
    ld ix, Ld92b_save_game_start  ; Address to store the data read from tape
#c236#5ab6311
11 d1 24 
    ld de, Lfdfc_save_game_end - Ld92b_save_game_start  ; read 9425 bytes (the whole RAM space, up 
#c239#5ab9
                                                        ; to the interrupt table!)
#c239#5ab915
af 
    xor a
#c23a#5aba15
37 
    scf
#c23b#5abb15
14 
    inc d
#c23c#5abc15
08 
    ex af, af'
#c23d#5abd15
15 
    dec d
#c23e#5abe15
f3 
    di
#c23f#5abf318
cd 62 05 
    call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS
#c242#5ac2
#c242#5ac215
af 
    xor a
#c243#5ac3212
d3 fe 
    out (ULA_PORT), a  ; border to black
#c245#5ac5
#c245#5ac5
    ; Make sure checksum is correct:
#c245#5ac5318
cd 0f c3 
    call Lc30f_compute_checksum
#c248#5ac8317
2a 00 5b 
    ld hl, (L5b00)
#c24b#5acb15
a7 
    and a
#c24c#5acc217
ed 52 
    sbc hl, de
#c24e#5ace15
7c 
    ld a, h
#c24f#5acf15
b5 
    or l
#c250#5ad0213/8
20 17 
    jr nz, Lc269_checksum_does_not_match
#c252#5ad2311
21 2b d9 
    ld hl, Ld92b_save_game_start
#c255#5ad5311
11 d3 d7 
    ld de, Ld7d3_bullets
#c258#5ad8311
01 2d 00 
    ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE
#c25b#5adb223/18
ed b0 
    ldir  ; Restore the bullet state from the reading buffer.
#c25d#5add311
11 01 ff 
    ld de, Lff01_building_decorations
#c260#5ae0311
01 a8 00 
    ld bc, 168
#c263#5ae3223/18
ed b0 
    ldir
#c265#5ae515
fb 
    ei
#c266#5ae628
f6 01 
    or 1
#c268#5ae8111
c9 
    ret
#c269#5ae9
#c269#5ae9
#c269#5ae9
Lc269_checksum_does_not_match:
#c269#5ae9318
cd 2d d4 
    call Ld42d_execute_ui_script
#c26c#5aec
    ; Script start:
#c26c#5aec3
        db CMD_SET_POSITION, #16, #02
#c26f#5aef2
        db CMD_SET_ATTRIBUTE, #47
#c271#5af12
        db CMD_SET_SCALE, #22
#c273#5af314
        db "LOADING ERROR!"
#c281#5b011
        db CMD_END
#c282#5b02
    ; Script end:
#c282#5b0228
3e fa 
    ld a, 250
#c284#5b04318
cd ac cc 
    call Lccac_beep
#c287#5b07318
cd 25 c3 
    call Lc325_wait_for_key
#c28a#5b0a311
c3 00 a6 
    jp La600_start
#c28d#5b0d
#c28d#5b0d
#c28d#5b0d
; --------------------------------
#c28d#5b0d
; Saves the current game state to tape
#c28d#5b0d
Lc28d_save_game:
#c28d#5b0d311
21 9c d5 
    ld hl, Ld59c_empty_interrupt
#c290#5b10317
22 fe fd 
    ld (Lfdfe_interrupt_pointer), hl
#c293#5b13318
cd 2d d4 
    call Ld42d_execute_ui_script
#c296#5b16
    ; Script start:
#c296#5b163
        db CMD_SET_POSITION, #16, #00
#c299#5b192
        db CMD_SET_ATTRIBUTE, #45
#c29b#5b1b22
        db "PRESS RECORD AND PLAY "
#c2b1#5b311
        db CMD_NEXT_LINE
#c2b2#5b3222
        db "     THEN ANY KEY     "
#c2c8#5b481
        db CMD_END
#c2c9#5b49
    ; Script end:
#c2c9#5b49318
cd 25 c3 
    call Lc325_wait_for_key
#c2cc#5b4c28
3e 01 
    ld a, 1
#c2ce#5b4e314
32 52 fd 
    ld (Lfd52_update_radar_buffer_signal), a
#c2d1#5b51311
21 d3 d7 
    ld hl, Ld7d3_bullets
#c2d4#5b54311
11 2b d9 
    ld de, Ld92b_save_game_start
#c2d7#5b57311
01 2d 00 
    ld bc, MAX_BULLETS * BULLET_STRUCT_SIZE
#c2da#5b5a223/18
ed b0 
    ldir  ; save the bullet state to a buffer for saving the game. Potential optimization: put the 
#c2dc#5b5c
          ; bullets here to begin with.
#c2dc#5b5c311
21 01 ff 
    ld hl, Lff01_building_decorations
#c2df#5b5f311
01 a8 00 
    ld bc, 168
#c2e2#5b62223/18
ed b0 
    ldir
#c2e4#5b6415
f3 
    di
#c2e5#5b65318
cd 0f c3 
    call Lc30f_compute_checksum
#c2e8#5b68422
ed 53 00 5b 
    ld (L5b00), de
#c2ec#5b6c311
21 00 09 
    ld hl, 2304  ; Data timing for saving bytes to disc
#c2ef#5b6f416
dd 21 00 5b 
    ld ix, L5b00
#c2f3#5b73311
11 02 00 
    ld de, 2  ; save 2 bytes to tape (checksum)
#c2f6#5b7615
af 
    xor a
#c2f7#5b7715
37 
    scf
#c2f8#5b78318
cd d0 04 
    call L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS
#c2fb#5b7b311
21 00 09 
    ld hl, 2304  ; Data timing for saving bytes to disc
#c2fe#5b7e416
dd 21 2b d9 
    ld ix, Ld92b_save_game_start
#c302#5b82311
11 d1 24 
    ld de, Lfdfc_save_game_end - Ld92b_save_game_start  ; save 9425 bytes to tape
#c305#5b8515
af 
    xor a
#c306#5b8615
37 
    scf
#c307#5b87318
cd d0 04 
    call L04d0_BIOS_CASSETTE_SAVE_SKIP_TESTS
#c30a#5b8a15
af 
    xor a
#c30b#5b8b212
d3 fe 
    out (ULA_PORT), a  ; border black
#c30d#5b8d15
fb 
    ei
#c30e#5b8e111
c9 
    ret
#c30f#5b8f
#c30f#5b8f
#c30f#5b8f
; --------------------------------
#c30f#5b8f
; Computes the checksum of the whole block of data that is saved
#c30f#5b8f
; in a save game (9425 bytes)
#c30f#5b8f
Lc30f_compute_checksum:
#c30f#5b8f311
21 2b d9 
    ld hl, Ld92b_save_game_start
#c312#5b92311
01 d1 24 
    ld bc, Lfdfc_save_game_end - Ld92b_save_game_start
#c315#5b95311
11 00 00 
    ld de, 0
#c318#5b98
Lc318:
#c318#5b9818
7e 
    ld a, (hl)
#c319#5b9917
23 
    inc hl
#c31a#5b9a15
83 
    add a, e
#c31b#5b9b15
5f 
    ld e, a
#c31c#5b9c213/8
30 01 
    jr nc, Lc31f
#c31e#5b9e15
14 
    inc d
#c31f#5b9f
Lc31f:
#c31f#5b9f17
0b 
    dec bc
#c320#5ba015
78 
    ld a, b
#c321#5ba115
b1 
    or c
#c322#5ba2213/8
20 f4 
    jr nz, Lc318
#c324#5ba4111
c9 
    ret
#c325#5ba5
#c325#5ba5
#c325#5ba5
; --------------------------------
#c325#5ba5
; Waits until the user presses any key
#c325#5ba5
Lc325_wait_for_key:
#c325#5ba5
    ; Wait until no key is pressed:
#c325#5ba5
Lc325_wait_for_key_loop1:
#c325#5ba515
af 
    xor a
#c326#5ba6212
db fe 
    in a, (ULA_PORT)  ; a = high byte, ULA_PORT = low byte
#c328#5ba815
2f 
    cpl
#c329#5ba928
e6 1f 
    and 31
#c32b#5bab213/8
20 f8 
    jr nz, Lc325_wait_for_key_loop1
#c32d#5bad
    ; Wait until the user presses any key:
#c32d#5bad
Lc32d_wait_for_key_loop2:
#c32d#5bad15
af 
    xor a
#c32e#5bae212
db fe 
    in a, (ULA_PORT)  ; a = high byte, ULA_PORT = low byte
#c330#5bb015
2f 
    cpl
#c331#5bb128
e6 1f 
    and 31
#c333#5bb3213/8
28 f8 
    jr z, Lc32d_wait_for_key_loop2
#c335#5bb5111
c9 
    ret
#c336#5bb6
#c336#5bb6
#c336#5bb6
; --------------------------------
#c336#5bb6
Lc336_highlight_if_selected:
#c336#5bb6314
3a e4 d3 
    ld a, (Ld3e4_input_type)
#c339#5bb915
b9 
    cp c
#c33a#5bba213/8
28 07 
    jr z, Lc343_highlight
#c33c#5bbc318
cd 2d d4 
    call Ld42d_execute_ui_script
#c33f#5bbf
    ; Script start:
#c33f#5bbf2
        db CMD_SET_ATTRIBUTE, #46
#c341#5bc11
        db CMD_END
#c342#5bc2
    ; Script end:
#c342#5bc2111
c9 
    ret
#c343#5bc3
Lc343_highlight:
#c343#5bc3318
cd 2d d4 
    call Ld42d_execute_ui_script
#c346#5bc6
    ; Script start:
#c346#5bc62
        db CMD_SET_ATTRIBUTE, #45
#c348#5bc81
        db CMD_END
#c349#5bc9
    ; Script end:
#c349#5bc9111
c9 
    ret
#c34a#5bca
#c34a#5bca
#c34a#5bca
; --------------------------------
#c34a#5bca
Lc34a_redefine_keys:
#c34a#5bca318
cd b9 d0 
    call Ld0b9_clear_screen
#c34d#5bcd318
cd 2d d4 
    call Ld42d_execute_ui_script
#c350#5bd0
    ; Script start:
#c350#5bd03
        db CMD_SET_POSITION, #02, #09
#c353#5bd32
        db CMD_SET_ATTRIBUTE, #47
#c355#5bd52
        db CMD_SET_SCALE, #21
#c357#5bd713
        db "REDEFINE KEYS"
#c364#5be43
        db CMD_SET_POSITION, #05, #03
#c367#5be72
        db CMD_SET_SCALE, #00
#c369#5be91
        db CMD_END
#c36a#5bea
    ; Script end:
#c36a#5bea
Lc36a_wait_for_no_key_pressed_loop:
#c36a#5bea318
cd 8e 02 
    call L028e_BIOS_POLL_KEYBOARD
#c36d#5bed15
7b 
    ld a, e
#c36e#5bee15
b7 
    or a
#c36f#5bef311
f2 6a c3 
    jp p, Lc36a_wait_for_no_key_pressed_loop
#c372#5bf2
    ; Clear all the key definitions:
#c372#5bf2311
21 cc d3 
    ld hl, Ld3cc_key_pause
#c375#5bf5311
11 cd d3 
    ld de, Ld3cc_key_pause + 1
#c378#5bf8311
01 17 00 
    ld bc, 23
#c37b#5bfb211
36 00 
    ld (hl), 0
#c37d#5bfd223/18
ed b0 
    ldir
#c37f#5bff318
cd 0c c4 
    call Lc40c_print_press_key_for
#c382#5c02
    ; Script start:
#c382#5c025
        db "   UP"
#c387#5c071
        db CMD_END
#c388#5c08
    ; Script end:
#c388#5c08311
21 da d3 
    ld hl, Ld3d8_key_up + 2
#c38b#5c0b318
cd 27 c4 
    call Lc427_redefine_one_key
#c38e#5c0e318
cd 0c c4 
    call Lc40c_print_press_key_for
#c391#5c11
    ; Script start:
#c391#5c115
        db " DOWN"
#c396#5c161
        db CMD_END
#c397#5c17
    ; Script end:
#c397#5c17311
21 dd d3 
    ld hl, Ld3db_key_down + 2
#c39a#5c1a318
cd 27 c4 
    call Lc427_redefine_one_key
#c39d#5c1d318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3a0#5c20
    ; Script start:
#c3a0#5c205
        db " LEFT"
#c3a5#5c251
        db CMD_END
#c3a6#5c26
    ; Script end:
#c3a6#5c26311
21 e0 d3 
    ld hl, Ld3de_key_left + 2
#c3a9#5c29318
cd 27 c4 
    call Lc427_redefine_one_key
#c3ac#5c2c318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3af#5c2f
    ; Script start:
#c3af#5c2f5
        db "RIGHT"
#c3b4#5c341
        db CMD_END
#c3b5#5c35
    ; Script end:
#c3b5#5c35311
21 e3 d3 
    ld hl, Ld3e1_key_right + 2
#c3b8#5c38318
cd 27 c4 
    call Lc427_redefine_one_key
#c3bb#5c3b318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3be#5c3e
    ; Script start:
#c3be#5c3e5
        db " FIRE"
#c3c3#5c431
        db CMD_END
#c3c4#5c44
    ; Script end:
#c3c4#5c44311
21 d7 d3 
    ld hl, Ld3d5_key_fire + 2
#c3c7#5c47318
cd 27 c4 
    call Lc427_redefine_one_key
#c3ca#5c4a318
cd 70 d4 
    call Ld470_execute_command_3_next_line
#c3cd#5c4d318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3d0#5c50
    ; Script start:
#c3d0#5c505
        db "PAUSE"
#c3d5#5c551
        db CMD_END
#c3d6#5c56
    ; Script end:
#c3d6#5c56311
21 ce d3 
    ld hl, Ld3cc_key_pause + 2
#c3d9#5c59318
cd 27 c4 
    call Lc427_redefine_one_key
#c3dc#5c5c318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3df#5c5f
    ; Script start:
#c3df#5c5f5
        db "ABORT"
#c3e4#5c641
        db CMD_END
#c3e5#5c65
    ; Script end:
#c3e5#5c65311
21 d1 d3 
    ld hl, Ld3cf_key_abort + 2
#c3e8#5c68318
cd 27 c4 
    call Lc427_redefine_one_key
#c3eb#5c6b318
cd 0c c4 
    call Lc40c_print_press_key_for
#c3ee#5c6e
    ; Script start:
#c3ee#5c6e5
        db " SAVE"
#c3f3#5c731
        db CMD_END
#c3f4#5c74
    ; Script end:
#c3f4#5c74311
21 d4 d3 
    ld hl, Ld3d2_key_save + 2
#c3f7#5c77318
cd 27 c4 
    call Lc427_redefine_one_key
#c3fa#5c7a
Lc3fa:
#c3fa#5c7a318
cd 8e 02 
    call L028e_BIOS_POLL_KEYBOARD
#c3fd#5c7d15
7b 
    ld a, e
#c3fe#5c7e15
b7 
    or a
#c3ff#5c7f311
f2 fa c3 
    jp p, Lc3fa
#c402#5c82311
01 00 00 
    ld bc, 0
#c405#5c85
Lc405:
#c405#5c8517
0b 
    dec bc
#c406#5c8615
00 
    nop
#c407#5c8715
79 
    ld a, c
#c408#5c8815
b0 
    or b
#c409#5c89213/8
20 fa 
    jr nz, Lc405
#c40b#5c8b111
c9 
    ret
#c40c#5c8c
#c40c#5c8c
#c40c#5c8c
; --------------------------------
#c40c#5c8c
Lc40c_print_press_key_for:
#c40c#5c8c318
cd 2d d4 
    call Ld42d_execute_ui_script
#c40f#5c8f
    ; Script start:
#c40f#5c8f1
        db CMD_NEXT_LINE
#c410#5c901
        db CMD_NEXT_LINE
#c411#5c912
        db CMD_SET_ATTRIBUTE, #46
#c413#5c9314
        db "PRESS KEY FOR "
#c421#5ca12
        db CMD_SET_ATTRIBUTE, #45
#c423#5ca31
        db CMD_END
#c424#5ca4
    ; Script end:
#c424#5ca4311
c3 2d d4 
    jp Ld42d_execute_ui_script
#c427#5ca7
#c427#5ca7
#c427#5ca7
; --------------------------------
#c427#5ca7
Lc427_redefine_one_key:
#c427#5ca7112
e5 
    push hl
#c428#5ca8318
cd 2d d4 
        call Ld42d_execute_ui_script
#c42b#5cab
        ; Script start:
#c42b#5cab2
            db "  "
#c42d#5cad2
            db CMD_SET_ATTRIBUTE, #46
#c42f#5caf1
            db CMD_END
#c430#5cb0
        ; Script emd:
#c430#5cb0
Lc430_wait_for_key_pressed_loop:
#c430#5cb0318
cd 8e 02 
        call L028e_BIOS_POLL_KEYBOARD
#c433#5cb315
7b 
        ld a, e
#c434#5cb415
b7 
        or a
#c435#5cb5311
fa 30 c4 
        jp m, Lc430_wait_for_key_pressed_loop
#c438#5cb8311
21 05 02 
        ld hl, L0205_BIOS_KEYCODE_TABLE
#c43b#5cbb15
85 
        add a, l
#c43c#5cbc15
6f 
        ld l, a
#c43d#5cbd18
7e 
        ld a, (hl)
#c43e#5cbe15
57 
        ld d, a
#c43f#5cbf311
21 ce d3 
        ld hl, Ld3cc_key_pause + 2
#c442#5cc228
06 08 
        ld b, 8
#c444#5cc4
Lc444_duplicate_key_check_loop:
#c444#5cc418
be 
        cp (hl)  ; If they key is already used, ignore
#c445#5cc5213/8
28 e9 
        jr z, Lc430_wait_for_key_pressed_loop
#c447#5cc717
23 
        inc hl
#c448#5cc817
23 
        inc hl
#c449#5cc917
23 
        inc hl
#c44a#5cca214/9
10 f8 
        djnz Lc444_duplicate_key_check_loop
#c44c#5ccc111
e1 
    pop hl
#c44d#5ccd18
77 
    ld (hl), a  ; assign the key haracter
#c44e#5cce15
7b 
    ld a, e
#c44f#5ccf28
e6 07 
    and #07
#c451#5cd115
4f 
    ld c, a
#c452#5cd2210
cb 3b 
    srl e
#c454#5cd4210
cb 3b 
    srl e
#c456#5cd6210
cb 3b 
    srl e
#c458#5cd815
43 
    ld b, e
#c459#5cd915
04 
    inc b
#c45a#5cda28
3e 20 
    ld a, 32
#c45c#5cdc
Lc45c:
#c45c#5cdc15
0f 
    rrca
#c45d#5cdd214/9
10 fd 
    djnz Lc45c
#c45f#5cdf17
2b 
    dec hl
#c460#5ce018
77 
    ld (hl), a
#c461#5ce115
41 
    ld b, c
#c462#5ce215
04 
    inc b
#c463#5ce315
af 
    xor a
#c464#5ce415
3d 
    dec a
#c465#5ce5
Lc465:
#c465#5ce515
1f 
    rra
#c466#5ce6214/9
10 fd 
    djnz Lc465
#c468#5ce817
2b 
    dec hl
#c469#5ce918
77 
    ld (hl), a
#c46a#5cea15
7a 
    ld a, d
#c46b#5ceb28
fe 0e 
    cp 14
#c46d#5ced213/8
20 0b 
    jr nz, Lc47a_not_sym_shift
#c46f#5cef318
cd 2d d4 
    call Ld42d_execute_ui_script
#c472#5cf2
    ; Script start:
#c472#5cf26
        db "SYM SH"
#c478#5cf81
        db CMD_END
#c479#5cf9
    ; Script end:
#c479#5cf9111
c9 
    ret
#c47a#5cfa
Lc47a_not_sym_shift:
#c47a#5cfa28
fe 0d 
    cp 13
#c47c#5cfc213/8
20 0a 
    jr nz, Lc488_not_enter
#c47e#5cfe318
cd 2d d4 
    call Ld42d_execute_ui_script
#c481#5d01
    ; Script start:
#c481#5d015
        db "ENTER"
#c486#5d061
        db CMD_END
#c487#5d07
    ; Script end:
#c487#5d07111
c9 
    ret
#c488#5d08
Lc488_not_enter:
#c488#5d0828
fe e3 
    cp 227
#c48a#5d0a213/8
20 0c 
    jr nz, Lc498_not_caps_shift
#c48c#5d0c318
cd 2d d4 
    call Ld42d_execute_ui_script
#c48f#5d0f
    ; Script start:
#c48f#5d0f7
        db "CAPS SH"
#c496#5d161
        db CMD_END
#c497#5d17
    ; Script end:
#c497#5d17111
c9 
    ret
#c498#5d18
Lc498_not_caps_shift:
#c498#5d1828
fe 20 
    cp 32
#c49a#5d1a311
c2 27 d4 
    jp nz, Ld427_draw_character_saving_registers
#c49d#5d1d318
cd 2d d4 
    call Ld42d_execute_ui_script
#c4a0#5d20
    ; Script start:
#c4a0#5d205
        db "SPACE"
#c4a5#5d251
        db CMD_END
#c4a6#5d26
    ; Script end:
#c4a6#5d26
Lc4a6:
#c4a6#5d26
Lc4a6_music_empty_event:  ; event 0
#c4a6#5d26111
c9 
    ret
#c4a7#5d27
#c4a7#5d27
#c4a7#5d27
; --------------------------------
#c4a7#5d27
; Waits until the player presses any number in the keyboard.
#c4a7#5d27
; While waiting, the title color is cycled, and music is played
#c4a7#5d27
Lc4a7_title_music_loop:
#c4a7#5d2715
f3 
    di
#c4a8#5d28422
ed 73 08 fd 
        ld (Lfd08_stack_ptr_buffer), sp  ; store the stack pointer
#c4ac#5d2c311
21 fd c4 
        ld hl, Lc4fd_title_music_loop_interrupt
#c4af#5d2f317
22 fe fd 
        ld (Lfdfe_interrupt_pointer), hl
#c4b2#5d32311
21 78 c6 
        ld hl, Lc678_music_event_table_channel1
#c4b5#5d35311
11 02 c7 
        ld de, Lc702_music_event_table_channel2
#c4b8#5d38311
01 01 01 
        ld bc, #0101  ; duration of the current event in the music channels (c = 1, b = 1 means 
#c4bb#5d3b
                      ; they will be reevaluated in the next frame, in 
#c4bb#5d3b
                      ; "Lc4fd_title_music_loop_interrupt")
#c4bb#5d3b15
d9 
        exx
#c4bc#5d3c311
21 65 c6 
        ld hl, Lc665_percussion_loops
#c4bf#5d3f15
fb 
    ei
#c4c0#5d4028
0e 01 
    ld c, 1
#c4c2#5d4215
76 
    halt
#c4c3#5d43
Lc4c3:
#c4c3#5d43112
f5 
    push af
#c4c4#5d44314
3a 0c fd 
        ld a, (Lfd0c_keyboard_state)  ; Question: what is the effect of this?
#c4c7#5d47314
32 0c fd 
        ld (Lfd0c_keyboard_state), a
#c4ca#5d4a111
f1 
    pop af
#c4cb#5d4b
Lc4cb:
#c4cb#5d4b15
15 
    dec d  ; note: undefined the first time we enter this function
#c4cc#5d4c311
c2 e0 c4 
    jp nz, Lc4e0
#c4cf#5d4f
    ; Produce a wave for channel 2: the events of the channel modify these parameters to produce 
#c4cf#5d4f
    ; the right wave.
#c4cf#5d4f
Lc4d0_selfmodifying: equ $ + 1
#c4cf#5d4f28
16 37 
    ld d, 55  ; mdl:self-modifying
#c4d1#5d51
Lc4d2_selfmodifying: equ $ + 1
#c4d1#5d5128
3e 18 
    ld a, 24  ; mdl:self-modifying
#c4d3#5d53212
d3 fe 
    out (ULA_PORT), a  ; produce sound (wave front up)
#c4d5#5d55
Lc4d6_selfmodifying: equ $ + 1
#c4d5#5d5528
3e 0d 
    ld a, 13  ; mdl:self-modifying
#c4d7#5d57
Lc4d7:
#c4d7#5d5715
3d 
    dec a
#c4d8#5d58311
c2 d7 c4 
    jp nz, Lc4d7
#c4db#5d5b212
d3 fe 
    out (ULA_PORT), a  ; produce sound (wave front down as a == 0)
#c4dd#5d5d311
c3 e8 c4 
    jp Lc4e8
#c4e0#5d60
Lc4e0:
#c4e0#5d60112
f5 
    push af
#c4e1#5d61314
3a 0c fd 
        ld a, (Lfd0c_keyboard_state)  ; Question: what is the effect of this?
#c4e4#5d64314
32 0c fd 
        ld (Lfd0c_keyboard_state), a
#c4e7#5d67111
f1 
    pop af
#c4e8#5d68
Lc4e8:
#c4e8#5d6815
1d 
    dec e
#c4e9#5d69311
c2 c3 c4 
    jp nz, Lc4c3
#c4ec#5d6c
    ; Produce a wave for channel 1: the events of the channel modify these parameters to produce 
#c4ec#5d6c
    ; the right wave.
#c4ec#5d6c
Lc4ed_selfmodifying: equ $ + 1
#c4ec#5d6c28
1e 7c 
    ld e, 124  ; mdl:self-modifying
#c4ee#5d6e
Lc4ef_selfmodifying: equ $ + 1
#c4ee#5d6e28
3e 18 
    ld a, 24  ; mdl:self-modifying
#c4f0#5d70212
d3 fe 
    out (ULA_PORT), a  ; produce sound (wave front up)
#c4f2#5d72
Lc4f3_selfmodifying: equ $ + 1
#c4f2#5d7228
3e 1f 
    ld a, 31  ; mdl:self-modifying
#c4f4#5d74
Lc4f4:
#c4f4#5d7415
3d 
    dec a
#c4f5#5d75311
c2 f4 c4 
    jp nz, Lc4f4
#c4f8#5d78212
d3 fe 
    out (ULA_PORT), a  ; produce sound (wave front down as a == 0)
#c4fa#5d7a311
c3 cb c4 
    jp Lc4cb
#c4fd#5d7d
#c4fd#5d7d
#c4fd#5d7d
; --------------------------------
#c4fd#5d7d
Lc4fd_title_music_loop_interrupt:
#c4fd#5d7d112
f5 
    push af
#c4fe#5d7e15
0d 
        dec c
#c4ff#5d7f318/11
cc db c5 
        call z, Lc5db_music_percussion
#c502#5d8215
d9 
        exx
#c503#5d8315
0d 
            dec c
#c504#5d84318/11
cc 28 c5 
            call z, Lc528_music_next_event_channel1  ; if the duration of the previous event 
#c507#5d87
                                                     ; reached 0, new event!
#c507#5d8715
05 
            dec b
#c508#5d88318/11
cc 3b c5 
            call z, Lc53b_music_next_event_channel2  ; if the duration of the previous event 
#c50b#5d8b
                                                    ; reached 0, new event!
#c50b#5d8b318
cd 20 c8 
            call Lc820_title_color_cycle
#c50e#5d8e28
3e e7 
            ld a, 231  ; read 4th and 5th keyboard rows (all the numbers).
#c510#5d90212
db fe 
            in a, (ULA_PORT)  ; a = high byte, ULA_PORT = low byte.
#c512#5d9215
2f 
            cpl
#c513#5d9328
e6 1f 
            and 31
#c515#5d95213/8
20 04 
            jr nz, Lc51b  ; If any number was pressed, exit the title music loop.
#c517#5d9715
d9 
        exx
#c518#5d98111
f1 
    pop af
#c519#5d9915
fb 
    ei
#c51a#5d9a111
c9 
    ret
#c51b#5d9b
Lc51b:
#c51b#5d9b15
f3 
    di
#c51c#5d9c422
ed 7b 08 fd 
        ld sp, (Lfd08_stack_ptr_buffer)  ; restore the stack pointer that was stored when entering 
#c520#5da0
                                         ; "Lc4a7_title_music_loop".
#c520#5da0311
21 9c d5 
        ld hl, Ld59c_empty_interrupt
#c523#5da3317
22 fe fd 
        ld (Lfdfe_interrupt_pointer), hl
#c526#5da615
fb 
    ei
#c527#5da7111
c9 
    ret  ; this effectively returns from "Lc4a7_title_music_loop".
#c528#5da8
#c528#5da8
#c528#5da8
; --------------------------------
#c528#5da8
; Reads the next event from the music event table 1 and executes it
#c528#5da8
; input:
#c528#5da8
; - hl: next event
#c528#5da8
Lc528_music_next_event_channel1:
#c528#5da818
7e 
    ld a, (hl)
#c529#5da928
fe 09 
    cp 9
#c52b#5dab213/8
38 22 
    jr c, Lc54f_music_event_jump_table_channel1
#c52d#5dad314
32 ed c4 
    ld (Lc4ed_selfmodifying), a
#c530#5db015
0f 
    rrca
#c531#5db115
0f 
    rrca
#c532#5db228
e6 3f 
    and #3f
#c534#5db4314
32 f3 c4 
    ld (Lc4f3_selfmodifying), a
#c537#5db717
23 
    inc hl
#c538#5db818
4e 
    ld c, (hl)
#c539#5db917
23 
    inc hl
#c53a#5dba111
c9 
    ret
#c53b#5dbb
#c53b#5dbb
#c53b#5dbb
; --------------------------------
#c53b#5dbb
; Reads the next event from the music event table 2 and executes it
#c53b#5dbb
; input:
#c53b#5dbb
; - de: next event
#c53b#5dbb
Lc53b_music_next_event_channel2:
#c53b#5dbb18
1a 
    ld a, (de)
#c53c#5dbc28
fe 09 
    cp 9
#c53e#5dbe213/8
38 2e 
    jr c, Lc56e_music_event_jump_table_channel2
#c540#5dc0314
32 d0 c4 
    ld (Lc4d0_selfmodifying), a
#c543#5dc315
0f 
    rrca
#c544#5dc415
0f 
    rrca
#c545#5dc528
e6 3f 
    and #3f
#c547#5dc7314
32 d6 c4 
    ld (Lc4d6_selfmodifying), a
#c54a#5dca17
13 
    inc de
#c54b#5dcb18
1a 
    ld a, (de)
#c54c#5dcc15
47 
    ld b, a
#c54d#5dcd17
13 
    inc de
#c54e#5dce111
c9 
    ret
#c54f#5dcf
#c54f#5dcf
#c54f#5dcf
; --------------------------------
#c54f#5dcf
Lc54f_music_event_jump_table_channel1:
#c54f#5dcf112
e5 
    push hl
#c550#5dd0318
cd 5b c6 
    call Lc65b_jump_table_jump
#c553#5dd3311
c3 a6 c4 
    jp Lc4a6_music_empty_event
#c556#5dd6311
c3 a7 c5 
    jp Lc5a7_music_channel1_jump
#c559#5dd9311
c3 8d c5 
    jp Lc58d_music_channel1_call
#c55c#5ddc311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c55f#5ddf311
c3 35 c6 
    jp Lc635_activate_channel1
#c562#5de2311
c3 3f c6 
    jp Lc63f_silence_channel1
#c565#5de5311
c3 bb c5 
    jp Lc5bb_music_channel1_ret
#c568#5de8311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c56b#5deb311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c56e#5dee
#c56e#5dee
#c56e#5dee
; --------------------------------
#c56e#5dee
Lc56e_music_event_jump_table_channel2:
#c56e#5dee112
e5 
    push hl
#c56f#5def318
cd 5b c6 
    call Lc65b_jump_table_jump
#c572#5df2311
c3 a6 c4 
    jp Lc4a6_music_empty_event
#c575#5df5311
c3 b0 c5 
    jp Lc5b0_music_channel2_jump
#c578#5df8311
c3 99 c5 
    jp Lc599_music_channel2_call
#c57b#5dfb311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c57e#5dfe311
c3 48 c6 
    jp Lc648_activate_channel2
#c581#5e01311
c3 52 c6 
    jp Lc652_silence_channel2
#c584#5e04311
c3 c3 c5 
    jp Lc5c3_music_channel2_ret
#c587#5e07311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c58a#5e0a311
c3 cc c5 
    jp Lc5cc_set_percussion_ptr
#c58d#5e0d
#c58d#5e0d
#c58d#5e0d
; --------------------------------
#c58d#5e0d
; Event 2
#c58d#5e0d
Lc58d_music_channel1_call:
#c58d#5e0d111
e1 
    pop hl
#c58e#5e0e17
23 
    inc hl
#c58f#5e0f18
7e 
    ld a, (hl)
#c590#5e1017
23 
    inc hl
#c591#5e11317
22 54 fd 
    ld (Lfd54_music_channel1_ret_address), hl
#c594#5e1418
66 
    ld h, (hl)
#c595#5e1515
6f 
    ld l, a
#c596#5e16311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c599#5e19
#c599#5e19
#c599#5e19
; --------------------------------
#c599#5e19
; Event 2
#c599#5e19
Lc599_music_channel2_call:
#c599#5e19111
e1 
    pop hl
#c59a#5e1a15
eb 
    ex de, hl
#c59b#5e1b17
23 
        inc hl
#c59c#5e1c18
7e 
        ld a, (hl)
#c59d#5e1d17
23 
        inc hl
#c59e#5e1e317
22 56 fd 
        ld (Lfd56_music_channel2_ret_address), hl
#c5a1#5e2118
66 
        ld h, (hl)
#c5a2#5e2215
6f 
        ld l, a
#c5a3#5e2315
eb 
    ex de, hl
#c5a4#5e24311
c3 3b c5 
    jp Lc53b_music_next_event_channel2
#c5a7#5e27
#c5a7#5e27
#c5a7#5e27
; --------------------------------
#c5a7#5e27
; Event 1
#c5a7#5e27
Lc5a7_music_channel1_jump:
#c5a7#5e27111
e1 
    pop hl
#c5a8#5e2817
23 
    inc hl
#c5a9#5e2918
7e 
    ld a, (hl)
#c5aa#5e2a17
23 
    inc hl
#c5ab#5e2b18
66 
    ld h, (hl)
#c5ac#5e2c15
6f 
    ld l, a
#c5ad#5e2d311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c5b0#5e30
#c5b0#5e30
#c5b0#5e30
; --------------------------------
#c5b0#5e30
; Event 1
#c5b0#5e30
Lc5b0_music_channel2_jump:
#c5b0#5e30111
e1 
    pop hl
#c5b1#5e3115
eb 
    ex de, hl
#c5b2#5e3217
23 
    inc hl
#c5b3#5e3318
7e 
    ld a, (hl)
#c5b4#5e3417
23 
    inc hl
#c5b5#5e3518
66 
    ld h, (hl)
#c5b6#5e3615
6f 
    ld l, a
#c5b7#5e3715
eb 
    ex de, hl
#c5b8#5e38311
c3 3b c5 
    jp Lc53b_music_next_event_channel2
#c5bb#5e3b
#c5bb#5e3b
#c5bb#5e3b
; --------------------------------
#c5bb#5e3b
; Event 6
#c5bb#5e3b
Lc5bb_music_channel1_ret:
#c5bb#5e3b111
e1 
    pop hl
#c5bc#5e3c317
2a 54 fd 
    ld hl, (Lfd54_music_channel1_ret_address)
#c5bf#5e3f17
23 
    inc hl
#c5c0#5e40311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c5c3#5e43
#c5c3#5e43
#c5c3#5e43
; --------------------------------
#c5c3#5e43
; Event 6
#c5c3#5e43
Lc5c3_music_channel2_ret:
#c5c3#5e43111
e1 
    pop hl
#c5c4#5e44422
ed 5b 56 fd 
    ld de, (Lfd56_music_channel2_ret_address)
#c5c8#5e4817
13 
    inc de
#c5c9#5e49311
c3 3b c5 
    jp Lc53b_music_next_event_channel2
#c5cc#5e4c
#c5cc#5e4c
#c5cc#5e4c
; --------------------------------
#c5cc#5e4c
; Event 3, 7 or 8
#c5cc#5e4c
Lc5cc_set_percussion_ptr:
#c5cc#5e4c111
e1 
    pop hl
#c5cd#5e4d17
23 
    inc hl
#c5ce#5e4e18
7e 
    ld a, (hl)
#c5cf#5e4f17
23 
    inc hl
#c5d0#5e5015
d9 
    exx
#c5d1#5e5115
6f 
        ld l, a
#c5d2#5e5215
d9 
    exx
#c5d3#5e5318
7e 
    ld a, (hl)
#c5d4#5e5417
23 
    inc hl
#c5d5#5e5515
d9 
    exx
#c5d6#5e5615
67 
        ld h, a
#c5d7#5e5715
d9 
    exx
#c5d8#5e58311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c5db#5e5b
#c5db#5e5b
#c5db#5e5b
; --------------------------------
#c5db#5e5b
Lc5db_music_percussion:
#c5db#5e5b18
7e 
    ld a, (hl)
#c5dc#5e5c17
23 
    inc hl
#c5dd#5e5d28
fe 01 
    cp 1
#c5df#5e5f213/8
28 20 
    jr z, Lc601_go_to  ; command == 1: go-to
#c5e1#5e6115
4f 
    ld c, a  ; Otherwise, repeat the following command for "a" steps
#c5e2#5e6218
7e 
    ld a, (hl)
#c5e3#5e6317
23 
    inc hl
#c5e4#5e6428
fe 02 
    cp 2
#c5e6#5e66213/8
28 2e 
    jr z, Lc616_tone_drum  ; 2: beep
#c5e8#5e6815
a7 
    and a
#c5e9#5e69213/8
28 1d 
    jr z, Lc608_drum1  ; 0: noisy beep
#c5eb#5e6b
    ; any number != 0 and != 2:
#c5eb#5e6b112
e5 
    push hl
#c5ec#5e6c28
26 00 
        ld h, 0  ; read 80 random bytes from the BIOS
#c5ee#5e6e28
06 50 
        ld b, 80
#c5f0#5e70
Lc5f0_drum2:
#c5f0#5e7018
7e 
        ld a, (hl)
#c5f1#5e7128
e6 18 
        and 24  ; sets all bits to 0 except those referring to MIC/EAR (to produce sound).
#c5f3#5e73212
d3 fe 
        out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#c5f5#5e7515
78 
        ld a, b
#c5f6#5e7615
2f 
        cpl
#c5f7#5e7728
e6 3f 
        and 63
#c5f9#5e79
Lc5f9_wait_pulse_on:
#c5f9#5e7915
3d 
        dec a
#c5fa#5e7a213/8
20 fd 
        jr nz, Lc5f9_wait_pulse_on
#c5fc#5e7c17
23 
        inc hl
#c5fd#5e7d214/9
10 f1 
        djnz Lc5f0_drum2
#c5ff#5e7f111
e1 
    pop hl
#c600#5e80111
c9 
    ret
#c601#5e81
#c601#5e81
#c601#5e81
; --------------------------------
#c601#5e81
Lc601_go_to:
#c601#5e8118
7e 
    ld a, (hl)
#c602#5e8217
23 
    inc hl
#c603#5e8318
66 
    ld h, (hl)
#c604#5e8415
6f 
    ld l, a
#c605#5e85311
c3 db c5 
    jp Lc5db_music_percussion
#c608#5e88
#c608#5e88
#c608#5e88
; --------------------------------
#c608#5e88
Lc608_drum1:
#c608#5e88112
e5 
    push hl
#c609#5e8928
26 08 
        ld h, 8
#c60b#5e8b28
06 60 
        ld b, 96
#c60d#5e8d
Lc60d:
#c60d#5e8d18
7e 
        ld a, (hl)  ; This is just reading a random byte from the BIOS (so, probably to produce 
#c60e#5e8e
                    ; noise).
#c60e#5e8e28
e6 18 
        and 24
#c610#5e90212
d3 fe 
        out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#c612#5e92214/9
10 f9 
        djnz Lc60d
#c614#5e94111
e1 
    pop hl
#c615#5e95111
c9 
    ret
#c616#5e96
#c616#5e96
#c616#5e96
; --------------------------------
#c616#5e96
Lc616_tone_drum:
#c616#5e9618
7e 
    ld a, (hl)
#c617#5e9717
23 
    inc hl
#c618#5e98112
e5 
    push hl
#c619#5e9928
06 30 
        ld b, 48  ; number of pulses the sound wave will have
#c61b#5e9b15
6f 
        ld l, a
#c61c#5e9c15
0f 
        rrca
#c61d#5e9d15
67 
        ld h, a
#c61e#5e9e
Lc61e_wave_loop:
#c61e#5e9e15
af 
        xor a
#c61f#5e9f212
d3 fe 
        out (ULA_PORT), a  ; change MIC/EAR state (sound off)
#c621#5ea115
2d 
        dec l
#c622#5ea215
7d 
        ld a, l
#c623#5ea3
Lc623_wait_pulse_off:
#c623#5ea315
3d 
        dec a
#c624#5ea4213/8
20 fd 
        jr nz, Lc623_wait_pulse_off
#c626#5ea628
3e 18 
        ld a, 24
#c628#5ea8212
d3 fe 
        out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#c62a#5eaa28
3e 04 
        ld a, 4
#c62c#5eac15
84 
        add a, h
#c62d#5ead15
67 
        ld h, a
#c62e#5eae
Lc62e_wait_pulse_on:
#c62e#5eae15
3d 
        dec a
#c62f#5eaf213/8
20 fd 
        jr nz, Lc62e_wait_pulse_on
#c631#5eb1214/9
10 eb 
        djnz Lc61e_wave_loop
#c633#5eb3111
e1 
    pop hl
#c634#5eb4111
c9 
    ret
#c635#5eb5
#c635#5eb5
#c635#5eb5
; --------------------------------
#c635#5eb5
; Event 4
#c635#5eb5
Lc635_activate_channel1:
#c635#5eb5111
e1 
    pop hl
#c636#5eb628
3e 18 
    ld a, 24
#c638#5eb8314
32 ef c4 
    ld (Lc4ef_selfmodifying), a
#c63b#5ebb17
23 
    inc hl
#c63c#5ebc311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c63f#5ebf
#c63f#5ebf
#c63f#5ebf
; --------------------------------
#c63f#5ebf
; Event 5
#c63f#5ebf
Lc63f_silence_channel1:
#c63f#5ebf111
e1 
    pop hl
#c640#5ec015
af 
    xor a
#c641#5ec1314
32 ef c4 
    ld (Lc4ef_selfmodifying), a
#c644#5ec417
23 
    inc hl
#c645#5ec5311
c3 28 c5 
    jp Lc528_music_next_event_channel1
#c648#5ec8
#c648#5ec8
#c648#5ec8
; --------------------------------
#c648#5ec8
; Event 4
#c648#5ec8
Lc648_activate_channel2:
#c648#5ec8111
e1 
    pop hl
#c649#5ec928
3e 18 
    ld a, 24
#c64b#5ecb314
32 d2 c4 
    ld (Lc4d2_selfmodifying), a
#c64e#5ece17
13 
    inc de
#c64f#5ecf311
c3 3b c5 
    jp Lc53b_music_next_event_channel2
#c652#5ed2
#c652#5ed2
#c652#5ed2
; --------------------------------
#c652#5ed2
; Event 5
#c652#5ed2
Lc652_silence_channel2:
#c652#5ed2111
e1 
    pop hl
#c653#5ed315
af 
    xor a
#c654#5ed4314
32 d2 c4 
    ld (Lc4d2_selfmodifying), a
#c657#5ed717
13 
    inc de
#c658#5ed8311
c3 3b c5 
    jp Lc53b_music_next_event_channel2
#c65b#5edb
#c65b#5edb
#c65b#5edb
; --------------------------------
#c65b#5edb
; Gets the pointer to the list of jumps from the stack, selects the pointer index "a", and jumps
#c65b#5edb
; Input:
#c65b#5edb
; - stack: jump table pointer
#c65b#5edb
; - a: index of the function to jump to
#c65b#5edb
Lc65b_jump_table_jump:
#c65b#5edb15
6f 
    ld l, a
#c65c#5edc15
87 
    add a, a
#c65d#5edd15
85 
    add a, l  ; a = a*3
#c65e#5ede111
e1 
    pop hl  ; get the pointer to the jump table
#c65f#5edf
    ; hl += a:
#c65f#5edf15
85 
    add a, l
#c660#5ee015
6f 
    ld l, a
#c661#5ee1213/8
30 01 
    jr nc, Lc664
#c663#5ee315
24 
    inc h
#c664#5ee4
Lc664:
#c664#5ee415
e9 
    jp hl
#c665#5ee5
#c665#5ee5
#c665#5ee5
; --------------------------------
#c665#5ee5
; Title Music:
#c665#5ee5
; Music in Nether Earth is defined in a scripting language with a series of commands, and has 3 
#c665#5ee5
; channels:
#c665#5ee5
; - one channel just contains percussion loops
#c665#5ee5
; - the other two channels (channel 1, channel 2) contain the notes.
#c665#5ee5
; For example, command "2" is a "call" to a music subroutine, "3" is a "jump" to a different
#c665#5ee5
; part of the score, etc. These commands basically index the functions in two jumptables:
#c665#5ee5
; "Lc54f_music_event_jump_table_channel1" and "Lc54f_music_event_jump_table_channel2".
#c665#5ee5
Lc665_percussion_loops:
#c665#5ee52
    db #20, #00  ; 32 steps of drum 1
#c667#5ee73
    db #01, #65, #c6  ; go-to #c665
#c66a#5eea2
    db #20, #00  ; 32 steps of drum 1  [I think this is unused]
#c66c#5eec
Lc66c:
#c66c#5eec2
    db #10, #01  ; 16 steps of drum 2
#c66e#5eee2
    db #08, #00  ; 8 steps of drum 1
#c670#5ef02
    db #08, #00  ; 8 steps of drum 1
#c672#5ef23
    db #20, #02, #30  ; 32 steps of clean beep drum instrument
#c675#5ef53
    db #01, #6c, #c6  ; go-to #c66c
#c678#5ef8
#c678#5ef8
Lc678_music_event_table_channel1:
#c678#5ef83
    db #03, #65, #c6
#c67b#5efb3
    db #02, #bd, #c6  ; call Lc6bd
#c67e#5efe3
    db #02, #bd, #c6  ; call Lc6bd
#c681#5f013
    db #02, #bd, #c6  ; call Lc6bd
#c684#5f043
    db #02, #bd, #c6  ; call Lc6bd
#c687#5f073
    db #03, #6c, #c6
#c68a#5f0a3
    db #02, #cc, #c6  ; call Lc6cc
#c68d#5f0d3
    db #02, #cc, #c6  ; call Lc6cc
#c690#5f103
    db #02, #dd, #c6  ; call Lc6dd
#c693#5f133
    db #02, #dd, #c6  ; call Lc6dd
#c696#5f163
    db #02, #dd, #c6  ; call Lc6dd
#c699#5f193
    db #02, #dd, #c6  ; call Lc6dd
#c69c#5f1c3
    db #02, #dd, #c6  ; call Lc6dd
#c69f#5f1f3
    db #02, #dd, #c6  ; call Lc6dd
#c6a2#5f223
    db #02, #dd, #c6  ; call Lc6dd
#c6a5#5f253
    db #02, #dd, #c6  ; call Lc6dd
#c6a8#5f283
    db #02, #cc, #c6  ; call Lc6cc
#c6ab#5f2b3
    db #02, #cc, #c6  ; call Lc6cc
#c6ae#5f2e3
    db #02, #cc, #c6  ; call Lc6cc
#c6b1#5f313
    db #02, #cc, #c6  ; call Lc6cc
#c6b4#5f343
    db #02, #cc, #c6  ; call Lc6cc
#c6b7#5f373
    db #03, #65, #c6
#c6ba#5f3a3
    db #01, #78, #c6  ; jump back to the beginning
#c6bd#5f3d
Lc6bd:
#c6bd#5f3d14
    db #7c, #10, #05, #7c, #08, #04, #7c, #10, #05, #7c, #40, #52, #18, #04
#c6cb#5f4b1
    db #06  ; ret
#c6cc#5f4c
Lc6cc:
#c6cc#5f4c16
    db #7c, #40, #6e, #40, #68, #40, #5d, #40, #7c, #40, #6e, #40, #68, #40, #5d, #40
#c6dc#5f5c1
    db #06  ; ret
#c6dd#5f5d
Lc6dd:
#c6dd#5f5d16
    db #7c, #08, #05, #7c, #08, #04, #7c, #08, #05, #7c, #08, #04, #7c, #08, #8b, #08
#c6ed#5f6d16
    db #93, #08, #a5, #08, #ba, #08, #a5, #08, #93, #08, #8b, #08, #7c, #08, #8b, #08
#c6fd#5f7d4
    db #93, #08, #a5, #08
#c701#5f811
    db #06  ; ret
#c702#5f82
#c702#5f82
Lc702_music_event_table_channel2:
#c702#5f823
    db #02, #89, #c7  ; call Lc789
#c705#5f853
    db #02, #89, #c7  ; call Lc789
#c708#5f883
    db #02, #89, #c7  ; call Lc789
#c70b#5f8b3
    db #02, #89, #c7  ; call Lc789
#c70e#5f8e3
    db #02, #aa, #c7  ; call Lc7aa
#c711#5f913
    db #02, #aa, #c7  ; call Lc7aa
#c714#5f943
    db #02, #aa, #c7  ; call Lc7aa
#c717#5f973
    db #02, #aa, #c7  ; call Lc7aa
#c71a#5f9a1
    db #05
#c71b#5f9b3
    db #02, #aa, #c7  ; call Lc7aa
#c71e#5f9e1
    db #04
#c71f#5f9f3
    db #02, #c5, #c7  ; call Lc7c5
#c722#5fa23
    db #02, #c5, #c7  ; call Lc7c5
#c725#5fa53
    db #02, #c5, #c7  ; call Lc7c5
#c728#5fa83
    db #02, #c5, #c7  ; call Lc7c5
#c72b#5fab3
    db #02, #c5, #c7  ; call Lc7c5
#c72e#5fae3
    db #02, #d2, #c7  ; call Lc7d2
#c731#5fb13
    db #02, #c5, #c7  ; call Lc7c5
#c734#5fb43
    db #02, #d2, #c7  ; call Lc7d2
#c737#5fb73
    db #02, #c5, #c7  ; call Lc7c5
#c73a#5fba3
    db #02, #d2, #c7  ; call Lc7d2
#c73d#5fbd3
    db #02, #c5, #c7  ; call Lc7c5
#c740#5fc04
    db #3e, #20, #37, #20
#c744#5fc43
    db #02, #aa, #c7  ; call Lc7aa
#c747#5fc73
    db #02, #aa, #c7  ; call Lc7aa
#c74a#5fca3
    db #02, #df, #c7  ; call Lc7df
#c74d#5fcd3
    db #02, #df, #c7  ; call Lc7df
#c750#5fd03
    db #02, #df, #c7  ; call Lc7df
#c753#5fd33
    db #02, #df, #c7  ; call Lc7df
#c756#5fd63
    db #02, #89, #c7  ; call Lc789
#c759#5fd93
    db #02, #89, #c7  ; call Lc789
#c75c#5fdc3
    db #02, #89, #c7  ; call Lc789
#c75f#5fdf3
    db #02, #89, #c7  ; call Lc789
#c762#5fe23
    db #02, #c5, #c7  ; call Lc7c5
#c765#5fe53
    db #02, #c5, #c7  ; call Lc7c5
#c768#5fe83
    db #02, #c5, #c7  ; call Lc7c5
#c76b#5feb3
    db #02, #c5, #c7  ; call Lc7c5
#c76e#5fee3
    db #02, #c5, #c7  ; call Lc7c5
#c771#5ff13
    db #02, #c5, #c7  ; call Lc7c5
#c774#5ff43
    db #02, #c5, #c7  ; call Lc7c5
#c777#5ff73
    db #02, #c5, #c7  ; call Lc7c5
#c77a#5ffa3
    db #02, #89, #c7  ; call Lc789
#c77d#5ffd3
    db #02, #89, #c7  ; call Lc789
#c780#60003
    db #02, #89, #c7  ; call Lc789
#c783#60033
    db #02, #89, #c7  ; call Lc789
#c786#60063
    db #01, #02, #c7  ; jump back to the beginning
#c789#6009
Lc789:
#c789#600916
    db #37, #10, #05, #37, #08, #04, #37, #10, #05, #37, #08, #04, #29, #08, #2e, #08
#c799#601916
    db #29, #08, #2e, #08, #29, #08, #2e, #08, #29, #08, #2e, #08, #37, #08, #3e, #08
#c7a9#60291
    db #06  ; ret
#c7aa#602a
Lc7aa:
#c7aa#602a11
    db #29, #10, #2e, #10, #31, #10, #37, #10, #3e, #20, #49
#c7b5#603515
    db #10, #3e, #10, #45, #20, #2e, #20, #29, #10, #2e, #10, #34, #10, #2e, #10
#c7c4#60441
    db #06  ; ret
#c7c5#6045
Lc7c5:
#c7c5#604512
    db #3e, #10, #52, #08, #7c, #08, #3e, #10, #52, #08, #7c, #08
#c7d1#60511
    db #06  ; ret
#c7d2#6052
Lc7d2:
#c7d2#605212
    db #45, #10, #5d, #08, #8b, #08, #45, #10, #5d, #08, #8b, #08
#c7de#605e1
    db #06  ; ret
#c7df#605f
Lc7df:
#c7df#605f16
    db #29, #04, #2e, #04, #34, #04, #37, #04, #3e, #04, #45, #04, #49, #04, #52, #04
#c7ef#606f16
    db #5d, #04, #68, #04, #6e, #04, #7c, #04, #8b, #04, #93, #04, #a5, #04, #ba, #04
#c7ff#607f16
    db #29, #04, #2e, #04, #34, #04, #37, #04, #3e, #04, #45, #04, #49, #04, #52, #04
#c80f#608f16
    db #5d, #04, #68, #04, #6e, #04, #7c, #04, #8b, #04, #93, #04, #a5, #04, #ba, #04
#c81f#609f1
    db #06  ; ret
#c820#60a0
#c820#60a0
#c820#60a0
; --------------------------------
#c820#60a0
Lc820_title_color_cycle:
#c820#60a0112
c5 
    push bc
#c821#60a1112
e5 
    push hl
#c822#60a2311
21 2a 58 
        ld hl, L5800_VIDEOMEM_ATTRIBUTES + 32 + 10
#c825#60a5314
3a 33 fd 
        ld a, (Lfd33_title_color)
#c828#60a815
3c 
        inc a
#c829#60a928
e6 0f 
        and #0f
#c82b#60ab314
32 33 fd 
        ld (Lfd33_title_color), a
#c82e#60ae15
0f 
        rrca
#c82f#60af213/8
38 15 
        jr c, Lc846
#c831#60b128
f6 40 
        or 64
#c833#60b3311
01 07 0c 
        ld bc, #0c07  ; change the color of 12 columns and 7 rows
#c836#60b6
Lc836:
#c836#60b6112
c5 
        push bc
#c837#60b7
Lc837:
#c837#60b718
77 
            ld (hl), a
#c838#60b817
23 
            inc hl
#c839#60b9214/9
10 fc 
            djnz Lc837
#c83b#60bb15
47 
            ld b, a
#c83c#60bc28
3e 14 
            ld a, 20
#c83e#60be318
cd 51 d3 
            call Ld351_add_hl_a
#c841#60c115
78 
            ld a, b
#c842#60c2111
c1 
        pop bc
#c843#60c315
0d 
        dec c
#c844#60c4213/8
20 f0 
        jr nz, Lc836
#c846#60c6
Lc846:
#c846#60c6111
e1 
    pop hl
#c847#60c7111
c1 
    pop bc
#c848#60c8111
c9 
    ret
#c849#60c9
#c849#60c9
#c849#60c9
; --------------------------------
#c849#60c9
; Checks if the player has less than the maximum number of robots, and if so, jumps to the robot 
#c849#60c9
; construction screen with "iy" pointing to a free robot structure.
#c849#60c9
Lc849_robot_construction_if_possible:
#c849#60c9416
fd 21 00 da 
    ld iy, Lda00_player1_robots
#c84d#60cd311
11 10 00 
    ld de, 16
#c850#60d028
06 18 
    ld b, MAX_ROBOTS_PER_PLAYER
#c852#60d2
Lc852_loop:
#c852#60d2321
fd 7e 01 
    ld a, (iy + 1)
#c855#60d515
b7 
    or a
#c856#60d6213/8
28 05 
    jr z, Lc85d_robot_construction
#c858#60d8217
fd 19 
    add iy, de
#c85a#60da214/9
10 f6 
    djnz Lc852_loop
#c85c#60dc111
c9 
    ret
#c85d#60dd
#c85d#60dd
#c85d#60dd
; --------------------------------
#c85d#60dd
; Robot construction screen:
#c85d#60dd
; input:
#c85d#60dd
; - iy: pointer to the robot struct that we will be editing.
#c85d#60dd
Lc85d_robot_construction:
#c85d#60dd15
f3 
    di
#c85e#60de311
21 9c d5 
    ld hl, Ld59c_empty_interrupt
#c861#60e1317
22 fe fd 
    ld (Lfdfe_interrupt_pointer), hl
#c864#60e415
fb 
    ei
#c865#60e5318
cd b9 d0 
    call Ld0b9_clear_screen
#c868#60e828
06 08 
    ld b, 8  ; there are 8 pieces to draw
#c86a#60ea311
11 f0 57 
    ld de, #57f0  ; Video pointer: (x, y) = (128, 191)  (bottom center of the screen)
#c86d#60ed
Lc86d_robot_construction_draw_piece_loop:
#c86d#60ed112
c5 
    push bc
#c86e#60ee112
d5 
    push de
#c86f#60ef28
3e 08 
        ld a, 8
#c871#60f115
90 
        sub b
#c872#60f215
87 
        add a, a
#c873#60f315
87 
        add a, a  ; a contains the index of the piece we want to draw in the 
#c874#60f4
                  ; Ld6c8_piece_direction_graphic_indices table
#c874#60f415
3c 
        inc a  ; we add 1 to select the index for the south-west direction
#c875#60f5311
21 c8 d6 
        ld hl, Ld6c8_piece_direction_graphic_indices
#c878#60f8318
cd 51 d3 
        call Ld351_add_hl_a
#c87b#60fb18
7e 
        ld a, (hl)  ; get the graphic index
#c87c#60fc15
87 
        add a, a
#c87d#60fd15
3c 
        inc a
#c87e#60fe311
21 40 d7 
        ld hl, Ld740_isometric_graphic_pointers
#c881#6101318
cd 48 d3 
        call Ld348_get_ptr_from_table
#c884#610418
4e 
        ld c, (hl)
#c885#610517
23 
        inc hl
#c886#610618
46 
        ld b, (hl)
#c887#610717
23 
        inc hl
#c888#610815
78 
        ld a, b
#c889#610915
87 
        add a, a
#c88a#610a318
cd 51 d3 
        call Ld351_add_hl_a
#c88d#610d15
0d 
        dec c
#c88e#610e15
79 
        ld a, c
#c88f#610f
        ; Limit the height to draw to 24 pixels (some pieces are taller than that):
#c88f#610f28
fe 18 
        cp 24
#c891#6111213/8
38 02 
        jr c, Lc895_height_calculated
#c893#611328
0e 18 
        ld c, 24
#c895#6115
Lc895_height_calculated:
#c895#6115
        ; Draw a piece sprite:
#c895#6115318
cd 15 d3 
        call Ld315_draw_masked_sprite_bottom_up
#c898#6118111
d1 
    pop de
#c899#6119111
c1 
    pop bc
#c89a#611a
    ; move the drawing coordinates 24 pixels up:
#c89a#611a15
7b 
    ld a, e
#c89b#611b28
d6 60 
    sub 96
#c89d#611d15
5f 
    ld e, a
#c89e#611e213/8
30 04 
    jr nc, Lc8a4
#c8a0#612015
7a 
    ld a, d
#c8a1#612128
d6 08 
    sub 8
#c8a3#612315
57 
    ld d, a
#c8a4#6124
Lc8a4:
#c8a4#6124214/9
10 c7 
    djnz Lc86d_robot_construction_draw_piece_loop
#c8a6#6126
#c8a6#6126
    ; Set the part of the screen where the robot under construction will be drawn to yellow:
#c8a6#6126311
01 09 04 
    ld bc, #0409
#c8a9#6129311
21 e0 59 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + 15 * 32
#c8ac#612c
Lc8ac_loop_y:
#c8ac#612c112
c5 
    push bc
#c8ad#612d
Lc8ad_loop_x:
#c8ad#612d211
36 46 
        ld (hl), #46  ; bright, black paper, ink color 6 (yellow)
#c8af#612f17
23 
        inc hl
#c8b0#6130214/9
10 fb 
        djnz Lc8ad_loop_x
#c8b2#613228
3e 1c 
        ld a, 28
#c8b4#6134318
cd 51 d3 
        call Ld351_add_hl_a
#c8b7#6137111
c1 
    pop bc
#c8b8#613815
0d 
    dec c
#c8b9#6139213/8
20 f1 
    jr nz, Lc8ac_loop_y
#c8bb#613b
#c8bb#613b318
cd 2d d4 
    call Ld42d_execute_ui_script
#c8be#613e
    ; Script start:
#c8be#613e2
        db CMD_SET_SCALE, #22
#c8c0#61402
        db CMD_SET_ATTRIBUTE, #47
#c8c2#61423
        db CMD_SET_POSITION, #00, #03
#c8c5#61455
        db "ROBOT"
#c8ca#614a3
        db CMD_SET_POSITION, #02, #02
#c8cd#614d2
        db CMD_SET_SCALE, #21
#c8cf#614f12
        db "CONSTRUCTION"
#c8db#615b2
        db CMD_SET_SCALE, #00
#c8dd#615d2
        db CMD_SET_ATTRIBUTE, #45
#c8df#615f3
        db CMD_SET_POSITION, #01, #15
#c8e2#616211
        db "ELECTRONICS"
#c8ed#616d3
        db CMD_SET_POSITION, #04, #15
#c8f0#61707
        db "NUCLEAR"
#c8f7#61773
        db CMD_SET_POSITION, #07, #15
#c8fa#617a7
        db "PHASERS"
#c901#61813
        db CMD_SET_POSITION, #0a, #15
#c904#61848
        db "MISSILES"
#c90c#618c3
        db CMD_SET_POSITION, #0d, #15
#c90f#618f6
        db "CANNON"
#c915#61953
        db CMD_SET_POSITION, #10, #15
#c918#61989
        db "ANTI-GRAV"
#c921#61a13
        db CMD_SET_POSITION, #13, #15
#c924#61a46
        db "TRACKS"
#c92a#61aa3
        db CMD_SET_POSITION, #16, #15
#c92d#61ad5
        db "BIPOD"
#c932#61b23
        db CMD_SET_POSITION, #15, #05
#c935#61b510
        db "EXIT START"
#c93f#61bf1
        db CMD_NEXT_LINE
#c940#61c010
        db "MENU ROBOT"
#c94a#61ca2
        db CMD_SET_ATTRIBUTE, #43
#c94c#61cc3
        db CMD_SET_POSITION, #02, #16
#c94f#61cf1
        db "3"
#c950#61d03
        db CMD_SET_POSITION, #05, #16
#c953#61d32
        db "20"
#c955#61d53
        db CMD_SET_POSITION, #08, #16
#c958#61d81
        db "4"
#c959#61d93
        db CMD_SET_POSITION, #0b, #16
#c95c#61dc1
        db "4"
#c95d#61dd3
        db CMD_SET_POSITION, #0e, #16
#c960#61e01
        db "2"
#c961#61e13
        db CMD_SET_POSITION, #11, #16
#c964#61e42
        db "10"
#c966#61e63
        db CMD_SET_POSITION, #14, #16
#c969#61e91
        db "5"
#c96a#61ea3
        db CMD_SET_POSITION, #17, #16
#c96d#61ed1
        db "3"
#c96e#61ee2
        db CMD_SET_SCALE, #00
#c970#61f02
        db CMD_SET_ATTRIBUTE, #46
#c972#61f23
        db CMD_SET_POSITION, #06, #00
#c975#61f515
        db "-- RESOURCES --"
#c984#62041
        db CMD_NEXT_LINE
#c985#620515
        db "-- AVAILABLE --"
#c994#62142
        db CMD_SET_ATTRIBUTE, #44
#c996#62163
        db CMD_SET_POSITION, #09, #04
#c999#62197
        db "GENERAL"
#c9a0#62203
        db CMD_SET_POSITION, #0b, #00
#c9a3#622311
        db "ELECTRONICS"
#c9ae#622e3
        db CMD_SET_POSITION, #0c, #04
#c9b1#62317
        db "NUCLEAR"
#c9b8#62381
        db CMD_NEXT_LINE
#c9b9#62397
        db "PHASERS"
#c9c0#62403
        db CMD_SET_POSITION, #0e, #03
#c9c3#62438
        db "MISSILES"
#c9cb#624b3
        db CMD_SET_POSITION, #0f, #05
#c9ce#624e6
        db "CANNON"
#c9d4#62543
        db CMD_SET_POSITION, #10, #04
#c9d7#62577
        db "CHASSIS"
#c9de#625e3
        db CMD_SET_POSITION, #12, #06
#c9e1#62615
        db "TOTAL"
#c9e6#62661
        db CMD_END
#c9e7#6267
    ; Script end:
#c9e7#6267421
fd 36 08 04 
    ld (iy + ROBOT_STRUCT_DIRECTION), 4  ; Robot facing south-east initially
#c9eb#626b421
fd 36 0d 00 
    ld (iy + ROBOT_STRUCT_ALTITUDE), 0
#c9ef#626f
#c9ef#626f
    ; Make a copy of the player resources:
#c9ef#626f311
21 22 fd 
    ld hl, Lfd22_player1_resource_counts
#c9f2#6272311
11 29 fd 
    ld de, Lfd29_resource_counts_buffer
#c9f5#6275311
01 07 00 
    ld bc, 7
#c9f8#6278223/18
ed b0 
    ldir
#c9fa#627a
#c9fa#627a318
cd e0 cb 
    call Lcbe0_draw_resource_counts_in_construction_screen
#c9fd#627d311
21 02 00 
    ld hl, 2
#ca00#6280317
22 1f fd 
    ld (Lfd1f_cursor_position), hl  ; start in the second column, first piece ("bipod")
#ca03#628315
af 
    xor a
#ca04#6284314
32 21 fd 
    ld (Lfd21_construction_selected_pieces), a
#ca07#6287318
cd 1f cc 
    call Lcc1f_update_selected_pieces_and_robot_preview
#ca0a#628a28
0e 46 
    ld c, COLOR_YELLOW + COLOR_BRIGHT
#ca0c#628c318
cd a9 cb 
    call Lcba9_construction_screen_set_option_color
#ca0f#628f
Lca0f_waiting_for_key_press_loop:
#ca0f#628f318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#ca12#629228
e6 1f 
    and #1f
#ca14#6294
    ; some key has been pressed:
#ca14#6294213/8
28 f9 
    jr z, Lca0f_waiting_for_key_press_loop
#ca16#6296317
2a 1f fd 
    ld hl, (Lfd1f_cursor_position)
#ca19#6299314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#ca1c#629c28
e6 10 
    and #10
#ca1e#629e311
ca 00 cb 
    jp z, Lcb00_construction_screen_move  ; Moving through the options (no space pressed)
#ca21#62a1
    ; "fire" has been pressed:
#ca21#62a115
7d 
    ld a, l  ; which column is the cursor in:
#ca22#62a215
b7 
    or a
#ca23#62a3311
ca 8e cb 
    jp z, Lcb8e_construction_screen_exit  ; "fire" pressed on "exit menu" (column 0)
#ca26#62a615
3d 
    dec a
#ca27#62a7311
ca 52 cb 
    jp z, Lcb52_construction_screen_start_robot  ; "fire" pressed on "start robot" (column 1)
#ca2a#62aa
    ; "fire" pressed on a piece:
#ca2a#62aa15
7c 
    ld a, h  ; a = selected piece
#ca2b#62ab15
5f 
    ld e, a  ; potential optimization: no need for the ld a, h; just ld e, a; ld b, e
#ca2c#62ac15
47 
    ld b, a
#ca2d#62ad15
04 
    inc b
#ca2e#62ae15
af 
    xor a
#ca2f#62af15
37 
    scf
#ca30#62b0
    ; get the selected piece as a one-hot representation (one bit on, all others off):
#ca30#62b0
Lca30_piece_to_one_hot_loop:
#ca30#62b015
17 
    rla
#ca31#62b1214/9
10 fd 
    djnz Lca30_piece_to_one_hot_loop
#ca33#62b315
57 
    ld d, a
#ca34#62b4314
3a 21 fd 
    ld a, (Lfd21_construction_selected_pieces)
#ca37#62b715
4f 
    ld c, a
#ca38#62b815
a2 
    and d  ; check if we already had that piece:
#ca39#62b9213/8
20 69 
    jr nz, Lcaa4_construction_remove_piece
#ca3b#62bb15
7b 
    ld a, e  ; e has the new selected piece
#ca3c#62bc28
fe 03 
    cp 3
#ca3e#62be213/8
30 17 
    jr nc, Lca57_construction_add_piece  ; If it's not a chassis piece, just add it
#ca40#62c0
    ; It's a chassis piece, check if we already had one selected:
#ca40#62c015
79 
    ld a, c  ; c still has the currently selected pieces in the robot
#ca41#62c128
e6 07 
    and 7
#ca43#62c3213/8
28 12 
    jr z, Lca57_construction_add_piece
#ca45#62c5
    ; Replace chassis piece:
#ca45#62c5112
d5 
    push de
#ca46#62c628
1e ff 
        ld e, 255
#ca48#62c8
        ; Here a = still has the currently selected pieces in the robot
#ca48#62c8
        ; This loop gets in "e" the index of the currently selected chassis in the robot:        
#ca48#62c8
Lca48_get_current_chassis_loop:
#ca48#62c815
1c 
        inc e
#ca49#62c915
0f 
        rrca
#ca4a#62ca213/8
30 fc 
        jr nc, Lca48_get_current_chassis_loop
#ca4c#62cc318
cd c1 ca 
        call Lcac1_update_resources_buffer_when_removing_a_piece
#ca4f#62cf
        ; We remove the current chassis from the robot:
#ca4f#62cf15
79 
        ld a, c
#ca50#62d028
e6 f8 
        and #f8
#ca52#62d215
4f 
        ld c, a
#ca53#62d3314
32 21 fd 
        ld (Lfd21_construction_selected_pieces), a
#ca56#62d6111
d1 
    pop de
#ca57#62d7
Lca57_construction_add_piece:
#ca57#62d715
79 
    ld a, c  ; c still has the currently selected pieces in the robot
#ca58#62d815
b2 
    or d  ; we add in the new piece
#ca59#62d928
e6 78 
    and #78
#ca5b#62db28
fe 78 
    cp #78
#ca5d#62dd311
ca ac ca 
    jp z, Lcaac_construction_beep_and_back_to_loop
#ca60#62e0
    ; Update the resources:
#ca60#62e0311
21 f0 ca 
    ld hl, Lcaf0_piece_costs
#ca63#62e315
7b 
    ld a, e
#ca64#62e4318
cd 51 d3 
    call Ld351_add_hl_a
#ca67#62e718
46 
    ld b, (hl)  ; b has the piece cost
#ca68#62e8311
21 f8 ca 
    ld hl, Lcaf8_piece_factory_type
#ca6b#62eb15
7b 
    ld a, e
#ca6c#62ec318
cd 51 d3 
    call Ld351_add_hl_a
#ca6f#62ef18
7e 
    ld a, (hl)  ; a has the index of the resource to subtract from
#ca70#62f0311
21 29 fd 
    ld hl, Lfd29_resource_counts_buffer
#ca73#62f3318
cd 51 d3 
    call Ld351_add_hl_a
#ca76#62f618
7e 
    ld a, (hl)
#ca77#62f715
90 
    sub b
#ca78#62f8311
d2 89 ca 
    jp nc, Lca89_construction_add_piece_continue  ; If we had enough, we are good
#ca7b#62fb210
ed 44 
    neg
#ca7d#62fd15
47 
    ld b, a
#ca7e#62fe314
3a 29 fd 
    ld a, (Lfd29_resource_counts_buffer)
#ca81#630115
90 
    sub b
#ca82#6302311
da ac ca 
    jp c, Lcaac_construction_beep_and_back_to_loop
#ca85#6305314
32 29 fd 
    ld (Lfd29_resource_counts_buffer), a
#ca88#630815
af 
    xor a
#ca89#6309
Lca89_construction_add_piece_continue:
#ca89#630918
77 
    ld (hl), a  ; update the resource counts after subtracting the piece cost
#ca8a#630a15
79 
    ld a, c
#ca8b#630b15
b2 
    or d
#ca8c#630c314
32 21 fd 
    ld (Lfd21_construction_selected_pieces), a  ; update the robot pieces
#ca8f#630f28
3e 64 
    ld a, 100
#ca91#6311318
cd ac cc 
    call Lccac_beep  ; Potential optimization: the following lines are identical to the end of the 
#ca94#6314
                     ; function below, unify.
#ca94#6314318
cd 1f cc 
    call Lcc1f_update_selected_pieces_and_robot_preview
#ca97#6317318
cd e0 cb 
    call Lcbe0_draw_resource_counts_in_construction_screen
#ca9a#631a
Lca9a_wait_for_fire_button_release:
#ca9a#631a318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#ca9d#631d28
e6 10 
    and 16
#ca9f#631f213/8
20 f9 
    jr nz, Lca9a_wait_for_fire_button_release
#caa1#6321311
c3 4a cb 
    jp Lcb4a_pause_and_back_to_construction_loop
#caa4#6324
#caa4#6324
#caa4#6324
; --------------------------------
#caa4#6324
; Removes a piece from the current robot we are editing
#caa4#6324
; Input:
#caa4#6324
; - e: piece to remove
#caa4#6324
Lcaa4_construction_remove_piece:
#caa4#6324318
cd c1 ca 
    call Lcac1_update_resources_buffer_when_removing_a_piece
#caa7#632715
79 
    ld a, c
#caa8#632815
aa 
    xor d
#caa9#6329314
32 21 fd 
    ld (Lfd21_construction_selected_pieces), a
#caac#632c
Lcaac_construction_beep_and_back_to_loop:
#caac#632c28
3e 78 
    ld a, 120
#caae#632e318
cd ac cc 
    call Lccac_beep
#cab1#6331318
cd 1f cc 
    call Lcc1f_update_selected_pieces_and_robot_preview
#cab4#6334318
cd e0 cb 
    call Lcbe0_draw_resource_counts_in_construction_screen
#cab7#6337
Lcab7_wait_for_fire_button_release:
#cab7#6337318
cd 7c d3 
    call Ld37c_read_keyboard_joystick_input
#caba#633a28
e6 10 
    and 16
#cabc#633c213/8
20 f9 
    jr nz, Lcab7_wait_for_fire_button_release
#cabe#633e311
c3 4a cb 
    jp Lcb4a_pause_and_back_to_construction_loop
#cac1#6341
#cac1#6341
#cac1#6341
; --------------------------------
#cac1#6341
; Update the resource counts buffer in the construction screen after removing a piece from the 
#cac1#6341
; robot.
#cac1#6341
; Input:
#cac1#6341
; - e: piece to remove
#cac1#6341
Lcac1_update_resources_buffer_when_removing_a_piece:
#cac1#6341311
21 f0 ca 
    ld hl, Lcaf0_piece_costs
#cac4#634415
7b 
    ld a, e
#cac5#6345318
cd 51 d3 
    call Ld351_add_hl_a
#cac8#634818
46 
    ld b, (hl)  ; get the cost of the piece.
#cac9#6349311
21 f8 ca 
    ld hl, Lcaf8_piece_factory_type
#cacc#634c15
7b 
    ld a, e
#cacd#634d318
cd 51 d3 
    call Ld351_add_hl_a
#cad0#635018
7e 
    ld a, (hl)  ; Get the index in the resource counts that we should add it to.
#cad1#6351311
21 29 fd 
    ld hl, Lfd29_resource_counts_buffer
#cad4#6354318
cd 51 d3 
    call Ld351_add_hl_a
#cad7#635718
7e 
    ld a, (hl)
#cad8#635815
80 
    add a, b  ; Add the piece cost to the corresponding resource counts.
#cad9#635918
77 
    ld (hl), a
#cada#635a
    ; See if we have added more than the player had:
#cada#635a112
e5 
    push hl
#cadb#635b15
7d 
        ld a, l
#cadc#635c28
d6 07 
        sub 7  ; The actual player resource counts (Lfd22_player1_resource_counts) are just 7 bytes 
#cade#635e
               ; offset from the buffer.
#cade#635e15
6f 
        ld l, a
#cadf#635f18
46 
        ld b, (hl)  ; Get the current resources that the player has on the index we just added to.
#cae0#6360111
e1 
    pop hl
#cae1#636118
7e 
    ld a, (hl)
#cae2#636215
b8 
    cp b
#cae3#6363112/6
c8 
    ret z  ; If after adding the piece cost, we still haven't reached the resources the player had 
#cae4#6364
           ; originally in that index, we are done.
#cae4#6364112/6
d8 
    ret c
#cae5#6365
    ; Otherwise, we need to cap the resource count in this index to what the player had, and add 
#cae5#6365
    ; the rest to the general resources index (0):
#cae5#636518
70 
    ld (hl), b
#cae6#636615
90 
    sub b
#cae7#636715
47 
    ld b, a
#cae8#6368314
3a 29 fd 
    ld a, (Lfd29_resource_counts_buffer)
#caeb#636b15
80 
    add a, b
#caec#636c314
32 29 fd 
    ld (Lfd29_resource_counts_buffer), a
#caef#636f111
c9 
    ret
#caf0#6370
#caf0#6370
#caf0#6370
; --------------------------------
#caf0#6370
; How much does each piece cost: bipod, tracks, anti-grav, cannon, missiles, phasers, nuclear, 
#caf0#6370
; electronics:
#caf0#6370
Lcaf0_piece_costs:
#caf0#63708
    db 3, 5, 10, 2, 4, 4, 20, 3
#caf8#6378
#caf8#6378
; Which factory type produces resources for each piece:
#caf8#6378
; - bipod, tracks, anti-grav are all produced in the "chassis" factory types (6), whereas the other 
#caf8#6378
;   pieces.
#caf8#6378
;   have dedicated factories for themselves.
#caf8#6378
Lcaf8_piece_factory_type:
#caf8#63788
    db 6, 6, 6, 5, 4, 3, 2, 1
#cb00#6380
#cb00#6380
#cb00#6380
; --------------------------------
#cb00#6380
; Moves the cursor around the construction screen after pressing one of the direction keys
#cb00#6380
; Input:
#cb00#6380
; - h: cursor row (selected piece if column == 2)
#cb00#6380
; - l: cursor column
#cb00#6380
Lcb00_construction_screen_move:
#cb00#6380314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#cb03#638328
e6 03 
    and 3
#cb05#6385213/8
28 14 
    jr z, Lcb1b_construction_screen_move_up_down
#cb07#638715
4f 
    ld c, a
#cb08#638815
7d 
    ld a, l
#cb09#6389210
cb 19 
    rr c
#cb0b#638b213/8
30 01 
    jr nc, Lcb0e_right_not_pressed
#cb0d#638d15
3c 
    inc a
#cb0e#638e
Lcb0e_right_not_pressed:
#cb0e#638e210
cb 19 
    rr c
#cb10#6390213/8
30 01 
    jr nc, Lcb13_left_not_pressed
#cb12#639215
3d 
    dec a
#cb13#6393
Lcb13_left_not_pressed:
#cb13#639328
fe 03 
    cp 3  ; make sure we did not move out of bounds
#cb15#6395213/8
30 33 
    jr nc, Lcb4a_pause_and_back_to_construction_loop
#cb17#639715
6f 
    ld l, a  ; l = new cursor column
#cb18#6398311
c3 36 cb 
    jp Lcb36_construction_screen_update_color_of_selected_option_after_move
#cb1b#639b
#cb1b#639b
Lcb1b_construction_screen_move_up_down:
#cb1b#639b314
3a 0c fd 
    ld a, (Lfd0c_keyboard_state)
#cb1e#639e
    ; Rotate the keyboard state to get to the bits representing up/down
#cb1e#639e15
0f 
    rrca
#cb1f#639f15
0f 
    rrca
#cb20#63a015
4f 
    ld c, a
#cb21#63a115
7d 
    ld a, l
#cb22#63a228
fe 02 
    cp 2  ; If we are not on the pieces column, just return as we cannot move up/down:
#cb24#63a4213/8
20 24 
    jr nz, Lcb4a_pause_and_back_to_construction_loop
#cb26#63a615
7c 
    ld a, h
#cb27#63a7210
cb 19 
    rr c
#cb29#63a9213/8
30 01 
    jr nc, Lcb2c_up_not_pressed
#cb2b#63ab15
3d 
    dec a  ; move up
#cb2c#63ac
Lcb2c_up_not_pressed:
#cb2c#63ac210
cb 19 
    rr c
#cb2e#63ae213/8
30 01 
    jr nc, Lcb31_down_not_pressed
#cb30#63b015
3c 
    inc a  ; move down
#cb31#63b1
Lcb31_down_not_pressed:
#cb31#63b128
fe 08 
    cp 8  ; make sure we did not move out of bounds
#cb33#63b3213/8
30 15 
    jr nc, Lcb4a_pause_and_back_to_construction_loop
#cb35#63b515
67 
    ld h, a  ; h = new cursor row
#cb36#63b6
Lcb36_construction_screen_update_color_of_selected_option_after_move:
#cb36#63b6112
e5 
    push hl
#cb37#63b728
0e 45 
        ld c, COLOR_CYAN + COLOR_BRIGHT
#cb39#63b9318
cd a9 cb 
        call Lcba9_construction_screen_set_option_color
#cb3c#63bc111
e1 
    pop hl
#cb3d#63bd317
22 1f fd 
    ld (Lfd1f_cursor_position), hl
#cb40#63c028
0e 46 
    ld c, COLOR_YELLOW + COLOR_BRIGHT
#cb42#63c2318
cd a9 cb 
    call Lcba9_construction_screen_set_option_color
#cb45#63c528
3e 14 
    ld a, 20
#cb47#63c7318
cd ac cc 
    call Lccac_beep
#cb4a#63ca
#cb4a#63ca
Lcb4a_pause_and_back_to_construction_loop:
#cb4a#63ca28
06 0a 
    ld b, 10
#cb4c#63cc
Lcb4c_pause_loop:
#cb4c#63cc15
76 
    halt
#cb4d#63cd214/9
10 fd 
    djnz Lcb4c_pause_loop
#cb4f#63cf311
c3 0f ca 
    jp Lca0f_waiting_for_key_press_loop
#cb52#63d2
#cb52#63d2
#cb52#63d2
; --------------------------------
#cb52#63d2
Lcb52_construction_screen_start_robot:
#cb52#63d2314
3a 21 fd 
    ld a, (Lfd21_construction_selected_pieces)
#cb55#63d515
4f 
    ld c, a
#cb56#63d628
e6 07 
    and 7
#cb58#63d8213/8
28 f0 
    jr z, Lcb4a_pause_and_back_to_construction_loop  ; If we have not selected any piece, do not 
#cb5a#63da
                                                     ; allow the robot to start
#cb5a#63da15
79 
    ld a, c
#cb5b#63db28
e6 78 
    and #78
#cb5d#63dd213/8
28 eb 
    jr z, Lcb4a_pause_and_back_to_construction_loop  ; If we have not selected any weapon, do not 
#cb5f#63df
                                                     ; allow the robot to start
#cb5f#63df311
21 29 fd 
    ld hl, Lfd29_resource_counts_buffer
#cb62#63e2311
11 22 fd 
    ld de, Lfd22_player1_resource_counts
#cb65#63e5311
01 07 00 
    ld bc, 7
#cb68#63e8223/18
ed b0 
    ldir  ; copy the resource buffer (that has the price of the robot discounted) to the player 
#cb6a#63ea
          ; resources
#cb6a#63ea317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#cb6d#63ed314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#cb70#63f028
c6 04 
    add a, 4
#cb72#63f215
47 
    ld b, a  ; robot starts 4 positions off the player in the y axis to be placed at the entrance 
#cb73#63f3
             ; of the factory
#cb73#63f3421
fd 36 0a 00 
    ld (iy + ROBOT_STRUCT_CONTROL), ROBOT_CONTROL_AUTO
#cb77#63f7318
cd 7c cc 
    call Lcc7c_set_robot_position
#cb7a#63fa314
3a 21 fd 
    ld a, (Lfd21_construction_selected_pieces)
#cb7d#63fd321
fd 77 07 
    ld (iy + ROBOT_STRUCT_PIECES), a
#cb80#6400
    ; Make the sound corresponding to having created a robot:
#cb80#640028
06 50 
    ld b, 80
#cb82#6402
Lcb82_sound_loop:
#cb82#640215
78 
    ld a, b
#cb83#6403318
cd ac cc 
    call Lccac_beep
#cb86#640615
78 
    ld a, b
#cb87#640728
d6 05 
    sub 5
#cb89#640915
47 
    ld b, a
#cb8a#640a28
fe 14 
    cp 20
#cb8c#640c213/8
30 f4 
    jr nc, Lcb82_sound_loop
#cb8e#640e
    ; And then just exit the construction screen:
#cb8e#640e
    ; jp Lcb8e_construction_screen_exit
#cb8e#640e
#cb8e#640e
#cb8e#640e
; --------------------------------
#cb8e#640e
Lcb8e_construction_screen_exit:
#cb8e#640e28
3e c8 
    ld a, 200
#cb90#6410318
cd ac cc 
    call Lccac_beep  ; make a sound
#cb93#641328
3e 05 
    ld a, 5
#cb95#6415314
32 30 fd 
    ld (Lfd30_player_elevate_timer), a  ; make the player levitate a bit after exiting
#cb98#6418217
fd e5 
    push iy
#cb9a#641a318
cd fe cf 
        call Lcffe_clear_5b00_buffer  ; clear the screen buffer
#cb9d#641d318
cd ca d0 
        call Ld0ca_draw_in_game_screen_and_hud
#cba0#6420216
fd e1 
    pop iy
#cba2#6422
    ; Restore the in-game interrupt (which was deactivated in the construction screen):
#cba2#6422311
21 66 d5 
    ld hl, Ld566_interrupt
#cba5#6425317
22 fe fd 
    ld (Lfdfe_interrupt_pointer), hl
#cba8#6428111
c9 
    ret
#cba9#6429
#cba9#6429
#cba9#6429
; --------------------------------
#cba9#6429
; input:
#cba9#6429
; - (Lfd1f_cursor_position): option to change the color
#cba9#6429
; - c: color to set
#cba9#6429
Lcba9_construction_screen_set_option_color:
#cba9#6429317
2a 1f fd 
    ld hl, (Lfd1f_cursor_position)
#cbac#642c15
7d 
    ld a, l
#cbad#642d28
fe 02 
    cp 2  ; if cursor is in column "2' (the piece names)
#cbaf#642f213/8
28 15 
    jr z, Lcbc6_set_attribute_piece_name
#cbb1#643115
87 
    add a, a
#cbb2#643215
85 
    add a, l
#cbb3#643315
87 
    add a, a
#cbb4#643428
c6 a4 
    add a, 164
#cbb6#643615
6f 
    ld l, a  ; l = a*6 + 5*32 + 4  
#cbb7#643728
26 5a 
    ld h, #5a  ; Here, if a == 0, we will change the color of the "EXIT MENU" option, and if a == 
#cbb9#6439
               ; 1, of the "START ROBOT" option.
#cbb9#643928
06 05 
    ld b, 5
#cbbb#643b318
cd db cb 
    call Lcbdb_set_attribute_loop  ; change color of the first line
#cbbe#643e15
7d 
    ld a, l
#cbbf#643f28
c6 1b 
    add a, 27
#cbc1#644115
6f 
    ld l, a
#cbc2#644228
06 05 
    ld b, 5
#cbc4#6444213
18 15 
    jr Lcbdb_set_attribute_loop  ; change color of the second line
#cbc6#6446
#cbc6#6446
Lcbc6_set_attribute_piece_name:
#cbc6#6446
    ; Calculate the position of the "h"-th piece name and paint it with color "c"
#cbc6#644615
7c 
    ld a, h
#cbc7#644715
87 
    add a, a
#cbc8#644815
84 
    add a, h  ; a = h*3
#cbc9#6449210
ed 44 
    neg  ; a = -h*3
#cbcb#644b28
c6 16 
    add a, 22  ; a = 22 - h*3
#cbcd#644d15
87 
    add a, a
#cbce#644e15
87 
    add a, a
#cbcf#644f15
87 
    add a, a  ; a = 8*(22 - h*3)
#cbd0#645015
6f 
    ld l, a
#cbd1#645128
26 00 
    ld h, 0
#cbd3#6453112
29 
    add hl, hl
#cbd4#6454112
29 
    add hl, hl  ; hl = 32 * (22 - h*3)
#cbd5#6455311
11 15 58 
    ld de, L5800_VIDEOMEM_ATTRIBUTES + 21
#cbd8#6458112
19 
    add hl, de  ; hl = L5800_VIDEOMEM_ATTRIBUTES + 21 + 32 * (22 - h*3)
#cbd9#6459
    ; set the attribute for 11 characters in a row (which is the length of the larger piece name 
#cbd9#6459
    ; "electronics"):
#cbd9#645928
06 0b 
    ld b, 11
#cbdb#645b
    ; set "b" positions in the attribute table to attribute "c":
#cbdb#645b
Lcbdb_set_attribute_loop:
#cbdb#645b18
71 
    ld (hl), c
#cbdc#645c17
23 
    inc hl
#cbdd#645d214/9
10 fc 
    djnz Lcbdb_set_attribute_loop
#cbdf#645f111
c9 
    ret
#cbe0#6460
#cbe0#6460
#cbe0#6460
; --------------------------------
#cbe0#6460
Lcbe0_draw_resource_counts_in_construction_screen:
#cbe0#6460311
11 29 fd 
    ld de, Lfd29_resource_counts_buffer
#cbe3#6463311
21 00 00 
    ld hl, 0  ; hl will accumulate total resources
#cbe6#646628
0e 09 
    ld c, 9  ; start y coordinate to draw resource counts
#cbe8#646828
06 07 
    ld b, 7
#cbea#646a
Lcbea:
#cbea#646a18
1a 
    ld a, (de)
#cbeb#646b318
cd 51 d3 
    call Ld351_add_hl_a
#cbee#646e18
1a 
    ld a, (de)
#cbef#646f318
cd 08 cc 
    call Lcc08_draw_single_resource_count_in_construction_screen
#cbf2#647217
13 
    inc de
#cbf3#647315
0c 
    inc c
#cbf4#647415
78 
    ld a, b
#cbf5#647528
fe 07 
    cp 7
#cbf7#6477213/8
20 01 
    jr nz, Lcbfa
#cbf9#647915
0c 
    inc c  ; the fist time, we leave a blank space between general resources and the rest
#cbfa#647a
Lcbfa:
#cbfa#647a214/9
10 ee 
    djnz Lcbea
#cbfc#647c318
cd 2d d4 
    call Ld42d_execute_ui_script
#cbff#647f
    ; script start:
#cbff#647f3
        db CMD_SET_POSITION, #12, #0c
#cc02#64821
        db CMD_END
#cc03#6483
    ; script end:
#cc03#648328
1e 20 
    ld e, " "
#cc05#6485311
c3 01 d4 
    jp Ld401_render_16bit_number_3digits  ; render the sum of all resources
#cc08#6488
#cc08#6488
#cc08#6488
; --------------------------------
#cc08#6488
Lcc08_draw_single_resource_count_in_construction_screen:
#cc08#6488112
f5 
    push af
#cc09#648915
79 
        ld a, c
#cc0a#648a314
32 11 cc 
        ld (Lcc11_selfmodifying), a  ; set the desired y coordinate
#cc0d#648d318
cd 2d d4 
        call Ld42d_execute_ui_script
#cc10#6490
        ; script start:
#cc10#64901
            db CMD_SET_POSITION
#cc11#6491
Lcc11_selfmodifying:
#cc11#64912
            db #00, #0d
#cc13#64931
            db CMD_END
#cc14#6494
        ; script end:
#cc14#6494111
f1 
    pop af
#cc15#6495112
c5 
    push bc
#cc16#6496112
d5 
    push de
#cc17#6497112
e5 
    push hl
#cc18#6498318
cd e5 d3 
        call Ld3e5_render_8bit_number
#cc1b#649b111
e1 
    pop hl
#cc1c#649c111
d1 
    pop de
#cc1d#649d111
c1 
    pop bc
#cc1e#649e111
c9 
    ret
#cc1f#649f
#cc1f#649f
#cc1f#649f
; --------------------------------
#cc1f#649f
; - Paints the selected pieces in white
#cc1f#649f
; - those not selected in yellow
#cc1f#649f
; - synthesizes the robot preview and draws it to screen
#cc1f#649f
; input:
#cc1f#649f
; - iy: robot struct pointer
#cc1f#649f
Lcc1f_update_selected_pieces_and_robot_preview:
#cc1f#649f311
21 10 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + 16
#cc22#64a2314
3a 21 fd 
    ld a, (Lfd21_construction_selected_pieces)
#cc25#64a515
4f 
    ld c, a
#cc26#64a628
06 08 
    ld b, 8  ; 8 pieces
#cc28#64a8
    ; paint the selected pieces in white color, and non-selected in yellow:
#cc28#64a8
Lcc28_loop_piece:
#cc28#64a828
1e 06 
    ld e, COLOR_YELLOW
#cc2a#64aa210
cb 11 
    rl c
#cc2c#64ac213/8
30 02 
    jr nc, Lcc30
#cc2e#64ae28
1e 47 
    ld e, COLOR_BRIGHT + COLOR_WHITE
#cc30#64b0
Lcc30:
#cc30#64b0112
c5 
    push bc
#cc31#64b1311
01 03 04 
        ld bc, #0403
#cc34#64b4
Lcc34_loop_y:
#cc34#64b4112
c5 
        push bc
#cc35#64b5
Lcc35_loop_x:
#cc35#64b518
73 
            ld (hl), e
#cc36#64b617
23 
            inc hl
#cc37#64b7214/9
10 fc 
            djnz Lcc35_loop_x
#cc39#64b928
3e 1c 
            ld a, 28  ; next line
#cc3b#64bb318
cd 51 d3 
            call Ld351_add_hl_a
#cc3e#64be111
c1 
        pop bc
#cc3f#64bf15
0d 
        dec c
#cc40#64c0213/8
20 f2 
        jr nz, Lcc34_loop_y
#cc42#64c2111
c1 
    pop bc
#cc43#64c3214/9
10 e3 
    djnz Lcc28_loop_piece
#cc45#64c5
#cc45#64c5318
cd fe cf 
    call Lcffe_clear_5b00_buffer
#cc48#64c8314
3a 21 fd 
    ld a, (Lfd21_construction_selected_pieces)
#cc4b#64cb321
fd 77 07 
    ld (iy + ROBOT_STRUCT_PIECES), a
#cc4e#64ce311
11 07 0a 
    ld de, #0a07  ; isometric coordinates of the robot, so it shows up in the right place in the 
#cc51#64d1
                  ; screen.
#cc51#64d1318
cd e8 ce 
    call Lcee8_draw_robot_to_buffer
#cc54#64d4314
3a 3f cf 
    ld a, (Lcf3f_selfmodifying_sprite_elevation)
#cc57#64d7321
fd 77 09 
    ld (iy + ROBOT_STRUCT_HEIGHT), a
#cc5a#64da
    ; Copies a block of 32*48 pixels from #6168 to (0,120) in video memory: this is the preview of 
#cc5a#64da
    ; the robot being constructed.
#cc5a#64da311
01 48 04 
    ld bc, #0448
#cc5d#64dd311
11 68 61 
    ld de, #6168
#cc60#64e0311
21 e0 48 
    ld hl, L4000_VIDEOMEM_PATTERNS + #08e0  ; (x, y) = (0, 120)
#cc63#64e3
Lcc63_loop_y:
#cc63#64e3112
c5 
    push bc
#cc64#64e4112
e5 
        push hl
#cc65#64e5
Lcc65_loop_x:
#cc65#64e518
1a 
            ld a, (de)
#cc66#64e618
77 
            ld (hl), a
#cc67#64e717
13 
            inc de
#cc68#64e817
23 
            inc hl
#cc69#64e9214/9
10 fa 
            djnz Lcc65_loop_x
#cc6b#64eb15
7b 
            ld a, e
#cc6c#64ec28
c6 10 
            add a, 16
#cc6e#64ee15
5f 
            ld e, a
#cc6f#64ef15
7a 
            ld a, d
#cc70#64f028
ce 00 
            adc a, 0
#cc72#64f215
57 
            ld d, a
#cc73#64f3111
e1 
        pop hl
#cc74#64f4318
cd 2a d3 
        call Ld32a_inc_video_ptr_y_hl
#cc77#64f7111
c1 
    pop bc
#cc78#64f815
0d 
    dec c
#cc79#64f9213/8
20 e8 
    jr nz, Lcc63_loop_y
#cc7b#64fb111
c9 
    ret
#cc7c#64fc
#cc7c#64fc
#cc7c#64fc
; --------------------------------
#cc7c#64fc
; Input:
#cc7c#64fc
; - hl: x coordinate
#cc7c#64fc
; - b: y coordinate
#cc7c#64fc
Lcc7c_set_robot_position:
#cc7c#64fc321
fd 75 02 
    ld (iy + ROBOT_STRUCT_X), l
#cc7f#64ff321
fd 74 03 
    ld (iy + ROBOT_STRUCT_X + 1), h
#cc82#6502321
fd 70 04 
    ld (iy + ROBOT_STRUCT_Y), b
#cc85#6505112
e5 
    push hl
#cc86#650615
78 
        ld a, b
#cc87#6507318
cd a6 cc 
        call Lcca6_compute_map_ptr
#cc8a#650a321
fd 75 00 
        ld (iy + ROBOT_STRUCT_MAP_PTR), l
#cc8d#650d321
fd 74 01 
        ld (iy + ROBOT_STRUCT_MAP_PTR + 1), h
#cc90#6510217
cb f6 
        set 6, (hl)
#cc92#6512111
e1 
    pop hl
#cc93#6513321
fd 4e 04 
    ld c, (iy + ROBOT_STRUCT_Y)
#cc96#6516321
fd 7e 0a 
    ld a, (iy + ROBOT_STRUCT_CONTROL)
#cc99#651915
07 
    rlca
#cc9a#651a28
e6 01 
    and 1
#cc9c#651c15
47 
    ld b, a  ; b = 0 if player robot, and b = 1 if enemy robot.
#cc9d#651d311
c3 5a d6 
    jp Ld65a_flip_2x2_radar_area
#cca0#6520
#cca0#6520
#cca0#6520
; --------------------------------
#cca0#6520
; Computes the pointer in the map corresponding to the current x, y coordinates of the player.
#cca0#6520
Lcca0_compute_player_map_ptr:
#cca0#6520317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#cca3#6523314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#cca6#6526
    ; jp Lcca6_compute_map_ptr
#cca6#6526
#cca6#6526
#cca6#6526
; --------------------------------
#cca6#6526
; Computes the pointer in the map corresponding to some x, y coordinates.
#cca6#6526
; Input:
#cca6#6526
; - hl: x
#cca6#6526
; - a: y
#cca6#6526
; Output:
#cca6#6526
; - hl: map ptr
#cca6#6526
Lcca6_compute_map_ptr:
#cca6#652615
87 
    add a, a
#cca7#652728
c6 dd 
    add a, #dd
#cca9#652915
84 
    add a, h
#ccaa#652a15
67 
    ld h, a  ; h += a*2 + #dd
#ccab#652b111
c9 
    ret
#ccac#652c
#ccac#652c
#ccac#652c
; --------------------------------
#ccac#652c
; Produces a beep sound.
#ccac#652c
; input:
#ccac#652c
; - a: sound period (lower means higher pitch)
#ccac#652c
Lccac_beep:
#ccac#652c112
c5 
    push bc
#ccad#652d15
47 
        ld b, a
#ccae#652e15
af 
        xor a
#ccaf#652f15
4f 
        ld c, a
#ccb0#6530
Lccb0_beep_outer_loop:
#ccb0#6530112
c5 
        push bc
#ccb1#653128
ee 10 
            xor 16
#ccb3#6533212
d3 fe 
            out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#ccb5#6535
Lccb5_inner_loop:
#ccb5#6535214/9
10 fe 
            djnz Lccb5_inner_loop
#ccb7#6537111
c1 
        pop bc
#ccb8#653815
0d 
        dec c
#ccb9#6539213/8
20 f5 
        jr nz, Lccb0_beep_outer_loop
#ccbb#653b111
c1 
    pop bc
#ccbc#653c111
c9 
    ret
#ccbd#653d
#ccbd#653d
#ccbd#653d
; --------------------------------
#ccbd#653d
; Clears the double buffer, draws the game area there, and copies it to the video memory.
#ccbd#653d
Lccbd_redraw_game_area:
#ccbd#653d318
cd d7 cf 
    call Lcfd7_draw_blank_map_in_buffer
#ccc0#6540318
cd c6 cc 
    call Lccc6_draw_map_to_buffer
#ccc3#6543311
c3 71 d0 
    jp Ld071_copy_game_area_buffer_to_screen
#ccc6#6546
#ccc6#6546
#ccc6#6546
; --------------------------------
#ccc6#6546
; Renders the player and the map to the buffer
#ccc6#6546
Lccc6_draw_map_to_buffer:
#ccc6#6546311
21 00 00 
    ld hl, 0
#ccc9#6549317
22 11 fd 
    ld (Lfd11_player_iso_coordinates_if_deferred), hl  ; mark that the player rendering is not 
#cccc#654c
                                                       ; deferred.
#cccc#654c
    ; Draw the player shadow:
#cccc#654c15
af 
    xor a
#cccd#654d314
32 3f cf 
    ld (Lcf3f_selfmodifying_sprite_elevation), a
#ccd0#6550317
2a 0e fd 
    ld hl, (Lfd0e_player_x)
#ccd3#6553422
ed 5b 06 fd 
    ld de, (Lfd06_scroll_ptr)
#ccd7#655715
7a 
    ld a, d
#ccd8#655828
e6 01 
    and #01
#ccda#655a15
57 
    ld d, a  ; keep only the lower 9 bits of (Lfd06_scroll_ptr), which contain the x coordinate
#ccdb#655b15
af 
    xor a
#ccdc#655c217
ed 52 
    sbc hl, de  ; hl = player_x - scroll_x
#ccde#655e15
5d 
    ld e, l
#ccdf#655f314
3a 0d fd 
    ld a, (Lfd0d_player_y)
#cce2#656215
57 
    ld d, a
#cce3#656328
3e 01 
    ld a, 1  ; draw graphic 1 (player shadow)
#cce5#6565318
cd 2d cf 
    call Lcf2d_draw_sprite_to_buffer
#cce8#6568
#cce8#6568317
2a 06 fd 
    ld hl, (Lfd06_scroll_ptr)
#cceb#656b28
3e 20 
    ld a, 32
#cced#656d318
cd 51 d3 
    call Ld351_add_hl_a
#ccf0#6570311
11 20 00 
    ld de, 32
#ccf3#6573
    ; Draw the visible part of the map:
#ccf3#6573
    ; - "de" starts at 32 and decrements at each loop, and keeps track of the visible area we need 
#ccf3#6573
    ;   to draw.
#ccf3#6573
Lccf3_outer_loop:
#ccf3#657317
2b 
    dec hl
#ccf4#657415
1d 
    dec e
#ccf5#6575112
e5 
    push hl
#ccf6#6576112
d5 
    push de
#ccf7#6577
        ; Each inner iteration represents a diagonal row of the map (horizontal when projected to 
#ccf7#6577
        ; the screen).
#ccf7#6577
        ; - So, if a row starts in (7,0), it will draw: (7,0), (8,1), (9,2), etc.
#ccf7#6577
        ; - In the first iteration, it'll draw the objects that appear in the top of the screen.
#ccf7#6577
        ; - In subsequent iterations it goes down one row every time. 
#ccf7#6577
        ; - In the first iteration of the outer loop "e" will go from 31 -> 32, then from 30 -> 32, 
#ccf7#6577
        ;   29 -> 32, etc.
#ccf7#6577
        ; - until we reach 15 -> 31, 14 -> 30, etc. as at most the inner loop loops 16 times (
#ccf7#6577
        ;   controlled by "d").
#ccf7#6577
        ; - This is to capture the visible part of the screen with the isometric projection.
#ccf7#6577
Lccf7_inner_loop:
#ccf7#657715
7b 
        ld a, e
#ccf8#657815
b7 
        or a
#ccf9#6579311
fa 01 cd 
        jp m, Lcd01_not_visible  ; if we are outside of the visible area, skip
#ccfc#657c18
7e 
        ld a, (hl)
#ccfd#657d15
b7 
        or a
#ccfe#657e318/11
c4 18 cd 
        call nz, Lcd18_draw_map_cell  ; If there is anything in the map, draw it!
#cd01#6581
Lcd01_not_visible:
#cd01#6581
        ; move to the next position of the map to draw:
#cd01#658115
24 
        inc h  ; This does "y++" (since each row is 512 bytes long)
#cd02#658215
24 
        inc h
#cd03#658317
23 
        inc hl  ; This does "x++". Potential optimization: "inc l"?
#cd04#658415
14 
        inc d  ; keep track of how many positions we have drawn in this outer loop iteration
#cd05#658515
1c 
        inc e
#cd06#658615
7a 
        ld a, d
#cd07#658728
fe 10 
        cp 16
#cd09#6589213/8
30 05 
        jr nc, Lcd10_exit_inner_loop  ; If we have done 16 iterations of the inner loop, end
#cd0b#658b15
7b 
        ld a, e
#cd0c#658c28
fe 20 
        cp 32  ; if we have reached the limit visible in the screen, we are done.
#cd0e#658e213/8
20 e7 
        jr nz, Lccf7_inner_loop
#cd10#6590
Lcd10_exit_inner_loop:
#cd10#659015
7b 
        ld a, e
#cd11#6591111
d1 
    pop de
#cd12#6592111
e1 
    pop hl
#cd13#659328
fe 01 
    cp 1  ; when after drawing one row, "e == 1", end, which means there is no chance of anything 
#cd15#6595
          ; visible any more in subsequent outer loop iterations.
#cd15#6595213/8
20 dc 
    jr nz, Lccf3_outer_loop
#cd17#6597111
c9 
    ret
#cd18#6598
#cd18#6598
#cd18#6598
; --------------------------------
#cd18#6598
; Draws whatever is in this map cell: map elements, robots, player, etc.
#cd18#6598
; Input:
#cd18#6598
; - hl: map ptr
#cd18#6598
Lcd18_draw_map_cell:
#cd18#6598
    ; Start by drawing the map element in this position, if any:
#cd18#6598112
e5 
    push hl
#cd19#6599112
d5 
    push de
#cd1a#659a112
f5 
    push af
#cd1b#659b210
cb 6f 
        bit 5, a  ; Map elements occupy a 2x2 block in the map, but only the bottom-left corner has 
#cd1d#659d
                  ; bit 5 == 0.
#cd1d#659d213/8
20 0c 
        jr nz, Lcd2b_skip_map_element_draw
#cd1f#659f28
e6 1f 
        and #1f  ; If there is no map element in this position, skip.
#cd21#65a1213/8
28 08 
        jr z, Lcd2b_skip_map_element_draw
#cd23#65a3311
21 3f cf 
        ld hl, Lcf3f_selfmodifying_sprite_elevation
#cd26#65a6211
36 00 
        ld (hl), 0
#cd28#65a8318
cd 2d cf 
        call Lcf2d_draw_sprite_to_buffer
#cd2b#65ab
Lcd2b_skip_map_element_draw:
#cd2b#65ab111
f1 
    pop af
#cd2c#65ac111
d1 
    pop de
#cd2d#65ad111
e1 
    pop hl
#cd2e#65ae
    ; Now check if there is an object here (robot, etc.):
#cd2e#65ae210
cb 77 
    bit 6, a  ; objects are marked with bit 6
#cd30#65b0318/11
c4 12 ce 
    call nz, Lce12_draw_object_to_map
#cd33#65b318
7e 
    ld a, (hl)
#cd34#65b4210
cb 7f 
    bit 7, a  ; the player is marked with bit 7
#cd36#65b6112/6
c8 
    ret z  ; player is not here
#cd37#65b7
    ; Draw the player:
#cd37#65b7422
ed 4b 11 fd 
    ld bc, (Lfd11_player_iso_coordinates_if_deferred)
#cd3b#65bb15
78 
    ld a, b
#cd3c#65bc15
b1 
    or c
#cd3d#65bd213/8
20 3a 
    jr nz, Lcd79_player_rendering_was_deferred  ; player rendering was already deferred.
#cd3f#65bf
    ; Check if there is a map element that would occlude the player sprite when it shouldn't,
#cd3f#65bf
    ; and defer player rendering if so:
#cd3f#65bf112
d5 
    push de
#cd40#65c0
        ; "de" will have the map pointer where the player should be rendered at.
#cd40#65c0
        ; It should be == "hl" if not deferred.
#cd40#65c015
54 
        ld d, h
#cd41#65c115
5d 
        ld e, l
#cd42#65c2318
cd 96 cd 
        call Lcd96_find_near_in_front_map_element
#cd45#65c5112
e5 
        push hl
#cd46#65c617
2b 
            dec hl
#cd47#65c715
25 
            dec h
#cd48#65c815
25 
            dec h
#cd49#65c9318
cd 90 cd 
            call Lcd90_find_near_in_front_map_element
#cd4c#65cc15
24 
            inc h
#cd4d#65cd15
24 
            inc h
#cd4e#65ce318
cd 90 cd 
            call Lcd90_find_near_in_front_map_element
#cd51#65d115
24 
            inc h
#cd52#65d215
24 
            inc h
#cd53#65d315
7c 
            ld a, h
#cd54#65d428
fe fd 
            cp #fd
#cd56#65d6213/8
30 0b 
            jr nc, Lcd63_out_of_map_bounds
#cd58#65d8318
cd 90 cd 
            call Lcd90_find_near_in_front_map_element
#cd5b#65db17
23 
            inc hl
#cd5c#65dc318
cd 90 cd 
            call Lcd90_find_near_in_front_map_element
#cd5f#65df17
23 
            inc hl
#cd60#65e0318
cd 90 cd 
            call Lcd90_find_near_in_front_map_element
#cd63#65e3
Lcd63_out_of_map_bounds:
#cd63#65e3111
e1 
        pop hl
#cd64#65e415
7a 
        ld a, d
#cd65#65e515
bc 
        cp h
#cd66#65e6213/8
20 07 
        jr nz, Lcd6f_defer_player_rendering
#cd68#65e815
7b 
        ld a, e
#cd69#65e915
bd 
        cp l
#cd6a#65ea213/8
20 03 
        jr nz, Lcd6f_defer_player_rendering
#cd6c#65ec111
d1 
    pop de
#cd6d#65ed213
18 12 
    jr Lcd81_render_player_push
#cd6f#65ef
Lcd6f_defer_player_rendering:
#cd6f#65ef15
eb 
        ex de, hl
#cd70#65f0217
cb fe 
        set 7, (hl)  ; mark the player as being in the deferred coordinates.
#cd72#65f215
eb 
        ex de, hl
#cd73#65f3111
d1 
    pop de
#cd74#65f4422
ed 53 11 fd 
    ld (Lfd11_player_iso_coordinates_if_deferred), de
#cd78#65f8111
c9 
    ret
#cd79#65f9
#cd79#65f9
Lcd79_player_rendering_was_deferred:
#cd79#65f9217
cb be 
    res 7, (hl)  ; remove the player mark from the deferred position
#cd7b#65fb112
e5 
    push hl
#cd7c#65fc112
d5 
    push de
#cd7d#65fd15
50 
        ld d, b
#cd7e#65fe15
59 
        ld e, c  ; set the correct isometric coordinates (before it was deferred).
#cd7f#65ff213
18 02 
        jr Lcd83_render_player
#cd81#6601
#cd81#6601
Lcd81_render_player_push:
#cd81#6601112
e5 
    push hl
#cd82#6602112
d5 
    push de
#cd83#6603
Lcd83_render_player:
#cd83#6603314
3a 10 fd 
        ld a, (Lfd10_player_altitude)
#cd86#6606314
32 3f cf 
        ld (Lcf3f_selfmodifying_sprite_elevation), a
#cd89#660915
af 
        xor a
#cd8a#660a318
cd 2d cf 
        call Lcf2d_draw_sprite_to_buffer
#cd8d#660d111
d1 
    pop de
#cd8e#660e111
e1 
    pop hl
#cd8f#660f111
c9 
    ret
#cd90#6610
#cd90#6610
#cd90#6610
; --------------------------------
#cd90#6610
; Sees if there is a map element that would be rendered on top of the object in "hl", and
#cd90#6610
; returns its map pointer in de
#cd90#6610
; Input:
#cd90#6610
; - hl: map ptr to check
#cd90#6610
; - de: map ptr to update if we find a "more in front" map element
#cd90#6610
Lcd90_find_near_in_front_map_element:
#cd90#6610214
cb 76 
    bit 6, (hl)
#cd92#6612112/6
c8 
    ret z
#cd93#6613318
cd bf cd 
    call Lcdbf_update_de_if_hl_more_in_front_internal
#cd96#6616
Lcd96_find_near_in_front_map_element:
#cd96#6616112
e5 
    push hl
#cd97#661717
2b 
        dec hl  ; x -= 1
#cd98#661815
24 
        inc h  ; y += 1
#cd99#661915
24 
        inc h
#cd9a#661a15
7c 
        ld a, h
#cd9b#661b28
fe fd 
        cp #fd  ; check if pointer is outside of map bounds
#cd9d#661d213/8
30 08 
        jr nc, Lcda7_skip_first_row  ; out of bounds
#cd9f#661f318
cd b8 cd 
        call Lcdb8_update_de_if_hl_more_in_front
#cda2#662217
23 
        inc hl  ; x += 1
#cda3#6623318
cd b8 cd 
        call Lcdb8_update_de_if_hl_more_in_front
#cda6#662617
2b 
        dec hl  ; x -= 1
#cda7#6627
Lcda7_skip_first_row:
#cda7#662715
25 
        dec h
#cda8#662815
25 
        dec h  ; y -= 1
#cda9#6629318
cd b8 cd 
        call Lcdb8_update_de_if_hl_more_in_front
#cdac#662c17
23 
        inc hl  ; x += 1
#cdad#662d17
23 
        inc hl  ; x += 1
#cdae#662e15
24 
        inc h  ; y += 1
#cdaf#662f15
24 
        inc h
#cdb0#663015
7c 
        ld a, h
#cdb1#663128
fe fd 
        cp #fd  ; check if pointer is outside of map bounds
#cdb3#6633318/11
dc b8 cd 
        call c, Lcdb8_update_de_if_hl_more_in_front
#cdb6#6636111
e1 
    pop hl
#cdb7#6637111
c9 
    ret
#cdb8#6638
#cdb8#6638
#cdb8#6638
; --------------------------------
#cdb8#6638
; Checks if there is a map element in "hl" that is "in front" (rendered lower in the screen) of the
#cdb8#6638
; position pointed to by "de", and if so, overwrites "de" with "hl".
#cdb8#6638
; Input:
#cdb8#6638
; - hl: map ptr to check
#cdb8#6638
; - de: map ptr to update if we find a "more in front" map element
#cdb8#6638
Lcdb8_update_de_if_hl_more_in_front:
#cdb8#6638214
cb 6e 
    bit 5, (hl)
#cdba#663a112/6
c0 
    ret nz  ; return if this is not the bottom-left corner of the a map object
#cdbb#663b18
7e 
    ld a, (hl)
#cdbc#663c28
e6 1f 
    and #1f
#cdbe#663e112/6
c8 
    ret z  ; return if there is nothing in this map position
#cdbf#663f
    ; If we are here is that we are in a map position with the bottom-left corner of a map element.
#cdbf#663f
Lcdbf_update_de_if_hl_more_in_front_internal:
#cdbf#663f15
7b 
    ld a, e
#cdc0#664015
95 
    sub l
#cdc1#664115
4f 
    ld c, a  ; c = e - l  (difference in x, ignoring highest bit)
#cdc2#664215
7a 
    ld a, d
#cdc3#664328
d6 dd 
    sub #dd
#cdc5#6645210
cb 3f 
    srl a
#cdc7#664715
47 
    ld b, a  ; b = (d - #dd) / 2
#cdc8#664815
7c 
    ld a, h
#cdc9#664928
d6 dd 
    sub #dd
#cdcb#664b210
cb 3f 
    srl a  ; a = (h - #dd) / 2
#cdcd#664d15
90 
    sub b  ; a = ((h - #dd) / 2) - ((d - #dd) / 2)  (difference in y)
#cdce#664e15
81 
    add a, c  ; "a" has (hl.y - de.y) + (de.x - hl.x)
#cdcf#664f112/6
f8 
    ret m  ; return if whatever is in "de" is rendered "lower on the screen" when projected, 
#cdd0#6650213/8
20 03 
    jr nz, Lcdd5
#cdd2#665215
79 
    ld a, c  ; c still contains e - l (difference in x)
#cdd3#665315
b7 
    or a
#cdd4#6654112/6
f0 
    ret p  ; return if whatever is in de has a higher x coordinate.
#cdd5#6655
Lcdd5:
#cdd5#665515
54 
    ld d, h
#cdd6#665615
5d 
    ld e, l
#cdd7#6657111
c9 
    ret
#cdd8#6658
#cdd8#6658
#cdd8#6658
; --------------------------------
#cdd8#6658
; Finds if there is a robot with the same map pointer as hl, and returns it in "iy".
#cdd8#6658
; Input:
#cdd8#6658
; - hl: map ptr
#cdd8#6658
; Output:
#cdd8#6658
; - iy: robot ptr
#cdd8#6658
; - z: robot found
#cdd8#6658
; - nz: no robot found
#cdd8#6658
Lcdd8_get_robot_at_ptr:
#cdd8#6658416
fd 21 00 da 
    ld iy, Lda00_player1_robots
#cddc#665c28
06 30 
    ld b, MAX_ROBOTS_PER_PLAYER * 2
#cdde#665e
Lcdde_get_robot_below_player_loop:
#cdde#665e321
fd 7e 00 
    ld a, (iy + ROBOT_STRUCT_MAP_PTR)
#cde1#666115
bd 
    cp l
#cde2#6662213/8
20 05 
    jr nz, Lcde9_next_robot
#cde4#6664321
fd 7e 01 
    ld a, (iy + ROBOT_STRUCT_MAP_PTR + 1)
#cde7#666715
bc 
    cp h
#cde8#6668112/6
c8 
    ret z
#cde9#6669
Lcde9_next_robot:
#cde9#6669112
d5 
    push de
#cdea#666a311
11 10 00 
        ld de, ROBOT_STRUCT_SIZE
#cded#666d217
fd 19 
        add iy, de
#cdef#666f111
d1 
    pop de
#cdf0#6670214/9
10 ec 
    djnz Lcdde_get_robot_below_player_loop
#cdf2#667228
f6 01 
    or 1
#cdf4#6674111
c9 
    ret
#cdf5#6675
#cdf5#6675
#cdf5#6675
; --------------------------------
#cdf5#6675
; Find decoration at map pointer hl
#cdf5#6675
; Input:
#cdf5#6675
; - hl: map pointer to find a decoration for.
#cdf5#6675
; Returns:
#cdf5#6675
; - iy: ptr to a decoration that has "hl" as the map pointer (if found)
#cdf5#6675
; - z: decoration found.
#cdf5#6675
; - nz: decoration not found.
#cdf5#6675
Lcdf5_find_building_decoration_with_ptr:
#cdf5#6675416
fd 21 01 ff 
    ld iy, Lff01_building_decorations
#cdf9#667928
06 38 
    ld b, 56
#cdfb#667b
Lcdfb_loop:
#cdfb#667b321
fd 7e 00 
    ld a, (iy + BULLET_STRUCT_MAP_PTR)
#cdfe#667e15
bd 
    cp l
#cdff#667f213/8
20 05 
    jr nz, Lce06_skip
#ce01#6681321
fd 7e 01 
    ld a, (iy + BULLET_STRUCT_MAP_PTR + 1)
#ce04#668415
bc 
    cp h
#ce05#6685112/6
c8 
    ret z
#ce06#6686
Lce06_skip:
#ce06#6686112
d5 
    push de
#ce07#6687311
11 03 00 
        ld de, 3
#ce0a#668a217
fd 19 
        add iy, de
#ce0c#668c111
d1 
    pop de
#ce0d#668d214/9
10 ec 
    djnz Lcdfb_loop
#ce0f#668f28
f6 01 
    or 1
#ce11#6691111
c9 
    ret
#ce12#6692
#ce12#6692
#ce12#6692
; --------------------------------
#ce12#6692
; See if there is an object (robot, decoration, bullet) with map ptr equal to "hl" and draws it.
#ce12#6692
; Input:
#ce12#6692
; - hl: map ptr
#ce12#6692
; - de: isometric coordinates
#ce12#6692
Lce12_draw_object_to_map:
#ce12#6692318
cd d8 cd 
    call Lcdd8_get_robot_at_ptr
#ce15#6695213/8
28 51 
    jr z, Lce68_draw_robot_or_bullet  ; if there is a robot, draw it
#ce17#6697318
cd f5 cd 
    call Lcdf5_find_building_decoration_with_ptr
#ce1a#669a213/8
28 1c 
    jr z, Lce38_draw_decoration  ; if there is a decoration, draw it
#ce1c#669c416
fd 21 d3 d7 
    ld iy, Ld7d3_bullets
#ce20#66a028
06 05 
    ld b, MAX_BULLETS
#ce22#66a2
Lce22_loop_bullet:
#ce22#66a2321
fd 7e 00 
    ld a, (iy + BULLET_STRUCT_MAP_PTR)
#ce25#66a515
bd 
    cp l
#ce26#66a6213/8
20 06 
    jr nz, Lce2e_next_bullet
#ce28#66a8321
fd 7e 01 
    ld a, (iy + BULLET_STRUCT_MAP_PTR + 1)
#ce2b#66ab15
bc 
    cp h
#ce2c#66ac213/8
28 3a 
    jr z, Lce68_draw_robot_or_bullet  ; if there is a bullet, draw it
#ce2e#66ae
Lce2e_next_bullet:
#ce2e#66ae112
d5 
    push de
#ce2f#66af311
11 09 00 
        ld de, BULLET_STRUCT_SIZE
#ce32#66b2217
fd 19 
        add iy, de
#ce34#66b4111
d1 
    pop de
#ce35#66b5214/9
10 eb 
    djnz Lce22_loop_bullet
#ce37#66b7111
c9 
    ret
#ce38#66b8
#ce38#66b8
#ce38#66b8
; --------------------------------
#ce38#66b8
; Draws a decoration to the map (a flag, the "H" in a warbase, pieces on top of factories.)
#ce38#66b8
; Input:
#ce38#66b8
; - iy: decoration ptr
#ce38#66b8
; - de: isometric coordinates
#ce38#66b8
Lce38_draw_decoration:
#ce38#66b8112
e5 
    push hl
#ce39#66b9112
d5 
    push de
#ce3a#66ba321
fd 7e 02 
        ld a, (iy + BUILDING_DECORATION_STRUCT_TYPE)
#ce3d#66bd15
4f 
        ld c, a
#ce3e#66be311
21 5f ce 
        ld hl, Lce5f_decoration_drawing_elevations
#ce41#66c1318
cd 51 d3 
        call Ld351_add_hl_a
#ce44#66c418
7e 
        ld a, (hl)
#ce45#66c5314
32 3f cf 
        ld (Lcf3f_selfmodifying_sprite_elevation), a
#ce48#66c815
79 
        ld a, c
#ce49#66c9311
21 56 ce 
        ld hl, Lce56_decoration_sprite_indexes
#ce4c#66cc318
cd 51 d3 
        call Ld351_add_hl_a
#ce4f#66cf18
7e 
        ld a, (hl)
#ce50#66d0318
cd 2d cf 
        call Lcf2d_draw_sprite_to_buffer
#ce53#66d3111
d1 
    pop de
#ce54#66d4111
e1 
    pop hl
#ce55#66d5111
c9 
    ret
#ce56#66d6
#ce56#66d6
Lce56_decoration_sprite_indexes:
#ce56#66d69
    db #2c, #28, #25, #23, #20, #1d, #17, #2a, #2b
#ce5f#66df
Lce5f_decoration_drawing_elevations:
#ce5f#66df9
    db #13, #0f, #0f, #0f, #0f, #0f, #0f, #1a, #1a
#ce68#66e8
#ce68#66e8
#ce68#66e8
; --------------------------------
#ce68#66e8
; Draws a bullet to the map.
#ce68#66e8
; Input:
#ce68#66e8
; - iy: bullet/robot struct ptr.
#ce68#66e8
; - hl: map ptr.
#ce68#66e8
; - d, e: isometric coordinates.
#ce68#66e8
Lce68_draw_robot_or_bullet:
#ce68#66e8112
d5 
    push de
#ce69#66e915
54 
        ld d, h
#ce6a#66ea15
5d 
        ld e, l
#ce6b#66eb318
cd 96 cd 
        call Lcd96_find_near_in_front_map_element
#ce6e#66ee
        ; if "de" is different from "hl", update the ptr of the bullet/robot instead of drawing it:
#ce6e#66ee
        ; This is because it could be that the object in "de" would overwrite the bottom of the 
#ce6e#66ee
        ; object in "hl". So, we are just "deferring" the rendering.
#ce6e#66ee15
7a 
        ld a, d
#ce6f#66ef15
bc 
        cp h
#ce70#66f0213/8
20 04 
        jr nz, Lce76_update_robot_bullet_ptr  ; defer rendering
#ce72#66f215
7b 
        ld a, e
#ce73#66f315
bd 
        cp l
#ce74#66f4213/8
28 0c 
        jr z, Lce82_draw_robot_or_bullet_continue  ; if we only differ in "x" form the potential
#ce76#66f6
                                                   ; occluder, continue
#ce76#66f6
Lce76_update_robot_bullet_ptr:
#ce76#66f6
        ; Defer rendering to later, after we have drawn the map element in "de":
#ce76#66f615
eb 
        ex de, hl
#ce77#66f7217
cb f6 
            set 6, (hl)
#ce79#66f9321
fd 75 00 
            ld (iy + BULLET_STRUCT_MAP_PTR), l
#ce7c#66fc321
fd 74 01 
            ld (iy + BULLET_STRUCT_MAP_PTR + 1), h
#ce7f#66ff15
eb 
        ex de, hl
#ce80#6700111
d1 
    pop de
#ce81#6701111
c9 
    ret
#ce82#6702
#ce82#6702
Lce82_draw_robot_or_bullet_continue:
#ce82#6702111
d1 
    pop de  ; pop "de", which was pushed when we jumped here (isometric coordinates)
#ce83#6703112
d5 
    push de
#ce84#670415
eb 
        ex de, hl  ; de = original map ptr.
#ce85#6705321
fd 6e 02 
        ld l, (iy + ROBOT_STRUCT_X)
#ce88#6708321
fd 66 03 
        ld h, (iy + ROBOT_STRUCT_X + 1)
#ce8b#670b321
fd 7e 04 
        ld a, (iy + ROBOT_STRUCT_Y)
#ce8e#670e318
cd a6 cc 
        call Lcca6_compute_map_ptr  ; recompute map ptr in "hl" from the x, y coordinates in "hl", 
#ce91#6711
                                    ; "a".
#ce91#6711
        ; If the "Lcd96_find_near_in_front_map_element" call above found an object that will be 
#ce91#6711
        ; drawn later and would occlude this one, do not draw yet:
#ce91#671115
7a 
        ld a, d
#ce92#671215
bc 
        cp h
#ce93#6713213/8
20 07 
        jr nz, Lce9c_object_was_deferred  ; This means that the object was deferred for rendering 
#ce95#6715
                                          ; earlier, so, we draw it now.
#ce95#671515
7b 
        ld a, e
#ce96#671615
bd 
        cp l
#ce97#6717213/8
20 03 
        jr nz, Lce9c_object_was_deferred  ; This means that the object was deferred for rendering 
#ce99#6719
                                          ; earlier, so, we draw it now.
#ce99#6719111
d1 
    pop de
#ce9a#671a213
18 27 
    jr Lcec3_draw_robot_or_bullet_internal
#ce9c#671c
Lce9c_object_was_deferred:
#ce9c#671c
        ; Reestablish the pointer of the object to its original value:
#ce9c#671c321
fd 75 00 
        ld (iy + ROBOT_STRUCT_MAP_PTR), l
#ce9f#671f321
fd 74 01 
        ld (iy + ROBOT_STRUCT_MAP_PTR + 1), h
#cea2#672215
44 
        ld b, h
#cea3#672315
4d 
        ld c, l
#cea4#672415
eb 
        ex de, hl
#cea5#6725111
d1 
    pop de
#cea6#6726112
d5 
    push de
#cea7#6727112
e5 
    push hl
#cea8#6728217
cb b6 
        res 6, (hl)  ; remove the object from its deferred position
#ceaa#672a17
2b 
        dec hl
#ceab#672b15
1d 
        dec e
#ceac#672c
        ; Adjust the isometric coordinates to account for the fact that the object was moved to 
#ceac#672c
        ; defer its rendering.
#ceac#672c
Lceac_loop_x:
#ceac#672c15
79 
        ld a, c
#cead#672d15
bd 
        cp l
#ceae#672e213/8
28 04 
        jr z, Lceb4_loop_y
#ceb0#673017
23 
        inc hl
#ceb1#673115
1c 
        inc e
#ceb2#6732213
18 f8 
        jr Lceac_loop_x
#ceb4#6734
Lceb4_loop_y:
#ceb4#673415
78 
        ld a, b
#ceb5#673515
bc 
        cp h
#ceb6#6736213/8
28 05 
        jr z, Lcebd_loop_exit
#ceb8#673815
25 
        dec h
#ceb9#673915
25 
        dec h
#ceba#673a15
15 
        dec d
#cebb#673b213
18 f7 
        jr Lceb4_loop_y
#cebd#673d
Lcebd_loop_exit:
#cebd#673d318
cd c3 ce 
        call Lcec3_draw_robot_or_bullet_internal
#cec0#6740111
e1 
    pop hl
#cec1#6741111
d1 
    pop de
#cec2#6742111
c9 
    ret
#cec3#6743
#cec3#6743
#cec3#6743
; --------------------------------
#cec3#6743
; Draws the sprites corresponding to a bullet or robot to the double buffer.
#cec3#6743
; Input:
#cec3#6743
; - iy: robot/bullet ptr.
#cec3#6743
Lcec3_draw_robot_or_bullet_internal:
#cec3#6743217
fd e5 
    push iy
#cec5#6745111
c1 
    pop bc
#cec6#674615
78 
    ld a, b  ; Potential optimization: push/pop not needed, just "la a,iyh"
#cec7#674728
fe d8 
    cp #d8  ; bullets have pointers < #d800, if its bigger, it's a robot.
#cec9#6749311
d2 e8 ce 
    jp nc, Lcee8_draw_robot_to_buffer
#cecc#674c
    ; Draw the bullet
#cecc#674c112
e5 
    push hl
#cecd#674d112
d5 
    push de
#cece#674e321
fd 4e 07 
        ld c, (iy + BULLET_STRUCT_TYPE)
#ced1#6751321
fd 7e 05 
        ld a, (iy + BULLET_STRUCT_DIRECTION)
#ced4#6754
        ; get the sprite # of the bullet:
#ced4#675428
fe 03 
        cp 3
#ced6#675615
3f 
        ccf
#ced7#6757210
cb 11 
        rl c
#ced9#6759321
fd 7e 08 
        ld a, (iy + BULLET_STRUCT_ALTITUDE)
#cedc#675c314
32 3f cf 
        ld (Lcf3f_selfmodifying_sprite_elevation), a
#cedf#675f
        ; get the sprite # of the bullet (continued):
#cedf#675f28
3e 2b 
        ld a, 43
#cee1#676115
81 
        add a, c
#cee2#6762318
cd 2d cf 
        call Lcf2d_draw_sprite_to_buffer
#cee5#6765111
d1 
    pop de
#cee6#6766111
e1 
    pop hl
#cee7#6767111
c9 
    ret
#cee8#6768
#cee8#6768
#cee8#6768
; --------------------------------
#cee8#6768
; Input:
#cee8#6768
; - de: isometric coordinates
#cee8#6768
; - iy: pointer to the robot struct
#cee8#6768
Lcee8_draw_robot_to_buffer:
#cee8#6768112
e5 
    push hl
#cee9#6769321
fd 4e 07 
        ld c, (iy + ROBOT_STRUCT_PIECES)  ; which pieces are selected for the robot (1 bit per 
#ceec#676c
                                          ; piece).
#ceec#676c28
06 08 
        ld b, 8  ; up to 8 different pieces
#ceee#676e321
fd 7e 0d 
        ld a, (iy + ROBOT_STRUCT_ALTITUDE)
#cef1#6771314
32 3f cf 
        ld (Lcf3f_selfmodifying_sprite_elevation), a
#cef4#6774
Lcef4_piece_loop:
#cef4#6774210
cb 19 
        rr c
#cef6#6776318/11
dc fd ce 
        call c, Lcefd_draw_robot_piece_to_buffer  ; if the piece is selected, draw it.
#cef9#6779214/9
10 f9 
        djnz Lcef4_piece_loop
#cefb#677b111
e1 
    pop hl
#cefc#677c111
c9 
    ret
#cefd#677d
#cefd#677d
#cefd#677d
; --------------------------------
#cefd#677d
; Input:
#cefd#677d
; - b: 8 - piece to draw
#cefd#677d
; - de: isometric coordinates
#cefd#677d
; - iy: robot ptr.
#cefd#677d
Lcefd_draw_robot_piece_to_buffer:
#cefd#677d112
c5 
    push bc
#cefe#677e112
d5 
    push de
#ceff#677f28
3e 08 
        ld a, 8
#cf01#678115
90 
        sub b  ; a = piece to draw (0 = bipod, 1 = tracks, etc.)
#cf02#6782112
f5 
        push af
#cf03#6783321
fd 4e 08 
            ld c, (iy + ROBOT_STRUCT_DIRECTION)  ; one-hot representation of the robot direction
#cf06#678628
06 ff 
            ld b, 255  ; b will contain the direction (south-east, south-west, etc.)
#cf08#6788
Lcf08_direction_loop:
#cf08#678815
04 
            inc b
#cf09#6789210
cb 19 
            rr c
#cf0b#678b213/8
30 fb 
            jr nc, Lcf08_direction_loop
#cf0d#678d15
87 
            add a, a
#cf0e#678e15
87 
            add a, a
#cf0f#678f15
80 
            add a, b  ; a now contains the offset in the graphic indices table of the piece graphic 
#cf10#6790
                      ; to draw.
#cf10#6790311
21 c8 d6 
            ld hl, Ld6c8_piece_direction_graphic_indices
#cf13#6793318
cd 51 d3 
            call Ld351_add_hl_a
#cf16#679618
7e 
            ld a, (hl)  ; a now contains the index of the piece graphic to draw in the graphics 
#cf17#6797
                        ; table.
#cf17#679728
c6 16 
            add a, 22  ; + 22, since this will be later multiplied by 2, and is to skip the first 
#cf19#6799
                       ; 44 graphics in the "Ld6e8_additional_isometric_graphic_pointers" table.
#cf19#6799318
cd 2d cf 
            call Lcf2d_draw_sprite_to_buffer
#cf1c#679c111
f1 
        pop af
#cf1d#679d111
d1 
    pop de
#cf1e#679e111
c1 
    pop bc
#cf1f#679f311
21 b4 d7 
    ld hl, Ld7b4_piece_heights
#cf22#67a2318
cd 51 d3 
    call Ld351_add_hl_a  ; get piece height
#cf25#67a5314
3a 3f cf 
    ld a, (Lcf3f_selfmodifying_sprite_elevation)
#cf28#67a818
86 
    add a, (hl)
#cf29#67a9314
32 3f cf 
    ld (Lcf3f_selfmodifying_sprite_elevation), a
#cf2c#67ac111
c9 
    ret
#cf2d#67ad
#cf2d#67ad
#cf2d#67ad
; --------------------------------
#cf2d#67ad
; input:
#cf2d#67ad
; - a: index of the graphic to draw from Ld6e8_additional_isometric_graphic_pointers (divided by 2)
#cf2d#67ad
; - d, e: isometric coordinates.
#cf2d#67ad
Lcf2d_draw_sprite_to_buffer:
#cf2d#67ad15
4f 
    ld c, a  ; we save the graphic to draw in c
#cf2e#67ae
    ; calculate the screen x coordinate:
#cf2e#67ae210
cb 03 
    rlc e
#cf30#67b015
7b 
    ld a, e
#cf31#67b115
82 
    add a, d
#cf32#67b228
d6 18 
    sub 24
#cf34#67b415
6f 
    ld l, a  ; l (x coordinate in nibbles) = e*2 + d - 24
#cf35#67b5
    ; calculate the screen y coordinate:
#cf35#67b5210
cb 03 
    rlc e
#cf37#67b715
7a 
    ld a, d
#cf38#67b815
87 
    add a, a
#cf39#67b915
87 
    add a, a
#cf3a#67ba15
87 
    add a, a
#cf3b#67bb28
c6 64 
    add a, 100
#cf3d#67bd15
93 
    sub e
#cf3e#67be
Lcf3f_selfmodifying_sprite_elevation: equ $ + 1
#cf3e#67be28
d6 00 
    sub 0  ; a = d*8+100 - e*4 - (Lcf3f_selfmodifying_sprite_elevation)  ; mdl:self-modifying
#cf40#67c015
67 
    ld h, a  ; h: y coordinate to draw to in pixels (starting from the bottom of the sprite)
#cf41#67c115
79 
    ld a, c  ; restore the graphic to draw
#cf42#67c228
e6 3f 
    and #3f
#cf44#67c4
    ; here l = x coordinate in nibbles
#cf44#67c4210
cb 2d 
    sra l  ; we push the least significant bit to the carry (now l is x coordinate in bytes)
#cf46#67c6
    ; Here we have the coordinates where to draw:
#cf46#67c6
    ; - l: x coordinate in bytes
#cf46#67c6
    ; - h: y coordinate in pixels
#cf46#67c615
8f 
    adc a, a  ; The carry is now added to the index, since each odd sprite is already
#cf47#67c7
              ; pre-calculated with a 4 pixel offset in the x axis.
#cf47#67c7112
e5 
    push hl
#cf48#67c8311
21 e8 d6 
        ld hl, Ld6e8_additional_isometric_graphic_pointers
#cf4b#67cb318
cd 48 d3 
        call Ld348_get_ptr_from_table
#cf4e#67ce18
4e 
        ld c, (hl)  ; height in pixels
#cf4f#67cf17
23 
        inc hl
#cf50#67d018
46 
        ld b, (hl)  ; width in bytes
#cf51#67d117
23 
        inc hl
#cf52#67d215
eb 
        ex de, hl  ; de: pointer to the actual graphic data
#cf53#67d3111
e1 
    pop hl
#cf54#67d415
af 
    xor a
#cf55#67d5314
32 af cf 
    ld (Lcfaf_selfmodifying_left_pixel_skip), a  ; do not skip pixels from the left by default
#cf58#67d815
7d 
    ld a, l
#cf59#67d928
fe 14 
    cp 20
#cf5b#67db112/6
f0 
    ret p  ; if we are drawing beyond the buffer right edge, we are done
#cf5c#67dc15
7c 
    ld a, h
#cf5d#67dd28
fe a0 
    cp 160
#cf5f#67df213/8
38 16 
    jr c, Lcf77_clip_sprite_left
#cf61#67e128
fe e2 
    cp 226
#cf63#67e3112/6
d0 
    ret nc  ; if we are drawing outside of the draw-able area from top/bottom, we are done
#cf64#67e428
d6 9f 
    sub 159
#cf66#67e615
91 
    sub c  ; if we are drawing starting outside the buffer area, and the sprite is not tall enough 
#cf67#67e7
           ; to actually overlap with the viewable area, we are done.
#cf67#67e7112/6
f0 
    ret p
#cf68#67e8210
ed 44 
    neg
#cf6a#67ea15
4f 
    ld c, a  ; update the height of the sprite to draw
#cf6b#67eb
Lcf6b_skip_line_outer_loop:
#cf6b#67eb
    ; skip all the lines that would be drawn outside of the viewable area:
#cf6b#67eb112
c5 
    push bc
#cf6c#67ec
Lcf6c_skip_line_inner_loop:
#cf6c#67ec17
13 
        inc de
#cf6d#67ed17
13 
        inc de
#cf6e#67ee214/9
10 fc 
        djnz Lcf6c_skip_line_inner_loop
#cf70#67f0111
c1 
    pop bc
#cf71#67f115
25 
    dec h
#cf72#67f215
7c 
    ld a, h
#cf73#67f328
fe 9f 
    cp 159
#cf75#67f5213/8
20 f4 
    jr nz, Lcf6b_skip_line_outer_loop
#cf77#67f7
Lcf77_clip_sprite_left:
#cf77#67f715
7d 
    ld a, l  ; start x coordinate
#cf78#67f815
b7 
    or a
#cf79#67f9311
f2 85 cf 
    jp p, Lcf85_clip_sprite_right
#cf7c#67fc210
ed 44 
    neg  ; if sprite overflows from the left, clip sprite from the left:
#cf7e#67fe314
32 af cf 
    ld (Lcfaf_selfmodifying_left_pixel_skip), a
#cf81#680128
2e 00 
    ld l, 0  ; set drawing coordinate to 0
#cf83#680315
b8 
    cp b  ; if we are skipping the whole sprite, we are done
#cf84#6804112/6
d0 
    ret nc
#cf85#6805
Lcf85_clip_sprite_right:
#cf85#6805
    ; See if the sprite would overflow the buffer from the right, and clip sprite from the right if 
#cf85#6805
    ; necessary:
#cf85#680515
7d 
    ld a, l  ; start x coordinate
#cf86#680615
80 
    add a, b  ; sprite width
#cf87#680728
fe 15 
    cp 21
#cf89#6809213/8
38 0a 
    jr c, Lcf95_calculate_buffer_pointer_to_draw_to
#cf8b#680b28
d6 14 
    sub 20  ; a now has the number of bytes we want to skip from the left of the sprite
#cf8d#680d314
32 af cf 
    ld (Lcfaf_selfmodifying_left_pixel_skip), a
#cf90#6810
    ; What this loop does is to move the pointer to draw to the left, and set the number of pixels 
#cf90#6810
    ; to skip from the left, so that, effectively, we are skipping pixels from the right:
#cf90#6810
Lcf90_skip_right_pixels_initially_loop:
#cf90#681017
1b 
    dec de
#cf91#681117
1b 
    dec de
#cf92#681215
3d 
    dec a
#cf93#6813213/8
20 fb 
    jr nz, Lcf90_skip_right_pixels_initially_loop
#cf95#6815
Lcf95_calculate_buffer_pointer_to_draw_to:
#cf95#6815112
d5 
    push de
#cf96#6816
        ; Calculate the pointer to where we want to draw the sprite in the buffer:
#cf96#6816
        ; - l: x coordinate in bytes
#cf96#6816
        ; - h: y coordinate in pixels
#cf96#681615
7d 
        ld a, l
#cf97#6817112
f5 
        push af
#cf98#681815
6c 
            ld l, h
#cf99#681928
26 00 
            ld h, 0
#cf9b#681b112
29 
            add hl, hl
#cf9c#681c112
29 
            add hl, hl  ; hl = h*4
#cf9d#681d15
54 
            ld d, h
#cf9e#681e15
5d 
            ld e, l
#cf9f#681f112
29 
            add hl, hl
#cfa0#6820112
29 
            add hl, hl
#cfa1#6821112
19 
            add hl, de
#cfa2#6822111
f1 
        pop af
#cfa3#6823318
cd 51 d3 
        call Ld351_add_hl_a  ; hl = h*20 + l
#cfa6#6826311
11 00 5b 
        ld de, L5b00_double_buffer
#cfa9#6829112
19 
        add hl, de  ; hl = buffer pointer where to start drawing
#cfaa#682a111
d1 
    pop de
#cfab#682b15
eb 
    ex de, hl
#cfac#682c
    ; Draws a sprite from "hl" to "de" ("de" points to a memory buffer with 20 bytes per row of 
#cfac#682c
    ; pixels):
#cfac#682c
    ; - b: sprite width in bytes (b*8 pixels)
#cfac#682c
    ; - c: sprite height in pixels
#cfac#682c
Lcfac_draw_loop_y:
#cfac#682c112
c5 
    push bc
#cfad#682d112
d5 
    push de
#cfae#682e
Lcfaf_selfmodifying_left_pixel_skip: equ $ + 1
#cfae#682e28
3e 00 
        ld a, 0  ; mdl:self-modifying
#cfb0#683015
b7 
        or a  ; if we are no skipping pixels from the left, skip the loop
#cfb1#6831311
ca bb cf 
        jp z, Lcfbb_draw_loop_x
#cfb4#6834
        ; Skips "a*8" from the left of the sprite to draw:
#cfb4#6834
Lcfb4_skip_left_pixels_loop:
#cfb4#683417
23 
        inc hl
#cfb5#683517
23 
        inc hl
#cfb6#683615
05 
        dec b
#cfb7#683715
3d 
        dec a
#cfb8#6838311
c2 b4 cf 
        jp nz, Lcfb4_skip_left_pixels_loop
#cfbb#683b
        ; Writes a row of "b*8" pixels from hl to de:
#cfbb#683b
Lcfbb_draw_loop_x:
#cfbb#683b18
1a 
        ld a, (de)  ; read pixel from currently in the memory buffer
#cfbc#683c18
a6 
        and (hl)  ; applies and mask
#cfbd#683d17
23 
        inc hl
#cfbe#683e18
b6 
        or (hl)  ; applies or mask
#cfbf#683f18
12 
        ld (de), a  ; write pixel to the screen again
#cfc0#684017
23 
        inc hl
#cfc1#684117
13 
        inc de
#cfc2#6842214/9
10 f7 
        djnz Lcfbb_draw_loop_x
#cfc4#6844111
d1 
    pop de
#cfc5#6845111
c1 
    pop bc
#cfc6#6846
    ; move to the previous row in the buffer (20 bytes per row, as that's the width of the in-game 
#cfc6#6846
    ; area)
#cfc6#684628
3e ec 
    ld a, -20
#cfc8#684815
83 
    add a, e
#cfc9#684915
5f 
    ld e, a  ; e -= 20
#cfca#684a311
da d2 cf 
    jp c, Lcfd2_no_msb_update  ; if we don't need to update the most significant byte of the buffer 
#cfcd#684d
                               ; address, just skip
#cfcd#684d15
15 
    dec d
#cfce#684e15
7a 
    ld a, d
#cfcf#684f28
fe 5a 
    cp #5a  ; we are drawing in a buffer that starts in #5b00, so, if the most-significant byte is 
#cfd1#6851
            ; #5a, it means we are out of the buffer area, and we should stop drawing.
#cfd1#6851112/6
c8 
    ret z
#cfd2#6852
Lcfd2_no_msb_update:
#cfd2#685215
0d 
    dec c
#cfd3#6853311
c2 ac cf 
    jp nz, Lcfac_draw_loop_y
#cfd6#6856111
c9 
    ret
#cfd7#6857
#cfd7#6857
#cfd7#6857
; --------------------------------
#cfd7#6857
; Clears the screen buffer in #5b00, and draws the basic map frame (thw two diagonal cut-out 
#cfd7#6857
; patterns that can be seen in the game, to give the appearance of 3d).
#cfd7#6857
Lcfd7_draw_blank_map_in_buffer:
#cfd7#6857318
cd fe cf 
    call Lcffe_clear_5b00_buffer
#cfda#685a318
cd 26 d0 
    call Ld026_draw_top_left_diagonal_map_edge
#cfdd#685d311
21 a8 d6 
    ld hl, Ld6a8_diagonal_pattern1
#cfe0#686028
06 06 
    ld b, 6
#cfe2#6862311
11 0a 5b 
    ld de, L5b00_double_buffer + 10
#cfe5#6865318
cd 57 d0 
    call Ld057_draw_diagonal_line  ; draws the top-left edge of the map in screen
#cfe8#6868311
21 a8 d6 
    ld hl, Ld6a8_diagonal_pattern1
#cfeb#686b28
06 03 
    ld b, 3
#cfed#686d311
11 b2 65 
    ld de, L5b00_double_buffer + 136 * 20 + 18
#cff0#6870318
cd 57 d0 
    call Ld057_draw_diagonal_line  ; draws the first part of the bottom-right edge of the map in 
#cff3#6873
                                   ; the screen.
#cff3#6873311
21 b8 d6 
    ld hl, Ld6b8_diagonal_pattern2
#cff6#687628
06 04 
    ld b, 4
#cff8#6878311
11 12 65 
    ld de, L5b00_double_buffer + 128 * 20 + 18
#cffb#687b311
c3 57 d0 
    jp Ld057_draw_diagonal_line  ; draws the second part of the bottom-right edge of the map in the 
#cffe#687e
                                 ; screen.
#cffe#687e
#cffe#687e
#cffe#687e
; --------------------------------
#cffe#687e
Lcffe_clear_5b00_buffer:
#cffe#687e
    ; clears memory to 0 in the following ranges:
#cffe#687e
    ;   #5b00 - #6780 (6400 bytes)
#cffe#687e422
ed 73 08 fd 
    ld (Lfd08_stack_ptr_buffer), sp
#d002#6882311
31 80 67 
    ld sp, L6780_graphic_patterns  ; pointer to the definition of the " " character
#d005#688528
06 c6 
    ld b, 198
#d007#6887311
21 00 00 
    ld hl, 0
#d00a#688a
    ; This loop clears from #5b20 - #6780
#d00a#688a
Ld00a:
#d00a#688a112
e5 
    push hl
#d00b#688b112
e5 
    push hl
#d00c#688c112
e5 
    push hl
#d00d#688d112
e5 
    push hl
#d00e#688e112
e5 
    push hl
#d00f#688f112
e5 
    push hl
#d010#6890112
e5 
    push hl
#d011#6891112
e5 
    push hl
#d012#6892214/9
10 f6 
    djnz Ld00a
#d014#6894422
ed 7b 08 fd 
    ld sp, (Lfd08_stack_ptr_buffer)
#d018#6898
    ; This clears from #5b00 - #5b20. Potential optimization: just set b above to 200, and remove 
#d018#6898
    ; the rest of this function.
#d018#6898311
21 00 5b 
    ld hl, L5b00_double_buffer
#d01b#689b311
11 01 5b 
    ld de, L5b00_double_buffer + 1
#d01e#689e311
01 1f 00 
    ld bc, 31
#d021#68a1211
36 00 
    ld (hl), 0
#d023#68a3223/18
ed b0 
    ldir
#d025#68a5111
c9 
    ret
#d026#68a6
#d026#68a6
#d026#68a6
; --------------------------------
#d026#68a6
; Draws the top-left diagonal black part of the screen (at an 8x8 pixel resolution, the pixel-level 
#d026#68a6
; edges are drawn later in the Ld057_draw_diagonal_line function).
#d026#68a6
Ld026_draw_top_left_diagonal_map_edge:
#d026#68a628
3e 0a 
    ld a, 10
#d028#68a8314
32 38 d0 
    ld (Ld038_selfmodifying), a
#d02b#68ab314
32 41 d0 
    ld (Ld041_selfmodifying), a
#d02e#68ae311
21 00 5b 
    ld hl, L5b00_double_buffer
#d031#68b128
06 05 
    ld b, 5
#d033#68b3
Ld033:
#d033#68b3112
c5 
    push bc
#d034#68b428
06 08 
        ld b, 8
#d036#68b6
Ld036:
#d036#68b6112
c5 
        push bc
#d037#68b7
Ld038_selfmodifying: equ $ + 1
#d037#68b728
06 0a 
            ld b, 10  ; mdl:self-modifying
#d039#68b928
3e ff 
            ld a, 255
#d03b#68bb
Ld03b:
#d03b#68bb18
77 
            ld (hl), a
#d03c#68bc17
23 
            inc hl
#d03d#68bd214/9
10 fc 
            djnz Ld03b
#d03f#68bf111
c1 
        pop bc
#d040#68c0
Ld041_selfmodifying: equ $ + 1
#d040#68c028
3e 0a 
        ld a, 10  ; mdl:self-modifying
#d042#68c2318
cd 51 d3 
        call Ld351_add_hl_a
#d045#68c5214/9
10 ef 
        djnz Ld036
#d047#68c7111
c1 
    pop bc
#d048#68c8112
e5 
    push hl
#d049#68c9311
21 38 d0 
        ld hl, Ld038_selfmodifying
#d04c#68cc112
35 
        dec (hl)
#d04d#68cd112
35 
        dec (hl)
#d04e#68ce311
21 41 d0 
        ld hl, Ld041_selfmodifying
#d051#68d1112
34 
        inc (hl)
#d052#68d2112
34 
        inc (hl)
#d053#68d3111
e1 
    pop hl
#d054#68d4214/9
10 dd 
    djnz Ld033
#d056#68d6111
c9 
    ret
#d057#68d7
#d057#68d7
#d057#68d7
; --------------------------------
#d057#68d7
; Draws one of the diagonal line patterns in either Ld6a8 or Ld6b8 to the rendering buffer
#d057#68d7
; Input:
#d057#68d7
; - hl: pointer to the source data (16 bytes)
#d057#68d7
; - de: pointer to the destination buffer to start drawing. At each repetition, we go down 8 
#d057#68d7
;       pixels, and left 16 pixels (to draw a continuous diagonal line)
#d057#68d7
; - b: number of times to copy the patterh (each time is a 16*8 pixel block). 
#d057#68d7
Ld057_draw_diagonal_line:
#d057#68d7
Ld057_draw_diagonal_line_loop:
#d057#68d7112
c5 
    push bc
#d058#68d8112
e5 
    push hl
#d059#68d9311
01 ff 08 
        ld bc, #08ff  ; c to 255 (just a large enough value so that the auto decrement of ldi does 
#d05c#68dc
                      ; not get in the way of the djnz).
#d05c#68dc
        ; Draw the diagonal pattern once (16x8 pixels).
#d05c#68dc
Ld05c_draw_diagonal_line_inner_loop:
#d05c#68dc218
ed a0 
        ldi
#d05e#68de218
ed a0 
        ldi
#d060#68e028
3e 12 
        ld a, 18
#d062#68e215
83 
        add a, e
#d063#68e315
5f 
        ld e, a
#d064#68e415
7a 
        ld a, d
#d065#68e528
ce 00 
        adc a, 0
#d067#68e715
57 
        ld d, a  ; de += 18 (i.e., 1 line down, since each line of the buffer is 20 bytes wide, and 
#d068#68e8
                 ; each ldi already increments in one).
#d068#68e8214/9
10 f2 
        djnz Ld05c_draw_diagonal_line_inner_loop
#d06a#68ea111
e1 
    pop hl
#d06b#68eb111
c1 
    pop bc
#d06c#68ec17
1b 
    dec de
#d06d#68ed17
1b 
    dec de
#d06e#68ee214/9
10 e7 
    djnz Ld057_draw_diagonal_line_loop
#d070#68f0111
c9 
    ret
#d071#68f1
#d071#68f1
#d071#68f1
; --------------------------------
#d071#68f1
; Copies the 160x160 pixels buffer from #5b00 to video memory
#d071#68f1
Ld071_copy_game_area_buffer_to_screen:
#d071#68f1311
21 00 5b 
    ld hl, L5b00_double_buffer
#d074#68f4311
11 21 40 
    ld de, L4000_VIDEOMEM_PATTERNS + 33
#d077#68f728
0e 14 
    ld c, 20
#d079#68f9
Ld079_row_outer_loop:
#d079#68f928
06 08 
    ld b, 8
#d07b#68fb
Ld07b_row_inner_loop:
#d07b#68fb112
c5 
    push bc
#d07c#68fc112
d5 
    push de
#d07d#68fd
        ; copy one whole buffer row (20 bytes)
#d07d#68fd218
ed a0 
        ldi
#d07f#68ff218
ed a0 
        ldi
#d081#6901218
ed a0 
        ldi
#d083#6903218
ed a0 
        ldi
#d085#6905218
ed a0 
        ldi
#d087#6907218
ed a0 
        ldi
#d089#6909218
ed a0 
        ldi
#d08b#690b218
ed a0 
        ldi
#d08d#690d218
ed a0 
        ldi
#d08f#690f218
ed a0 
        ldi
#d091#6911218
ed a0 
        ldi
#d093#6913218
ed a0 
        ldi
#d095#6915218
ed a0 
        ldi
#d097#6917218
ed a0 
        ldi
#d099#6919218
ed a0 
        ldi
#d09b#691b218
ed a0 
        ldi
#d09d#691d218
ed a0 
        ldi
#d09f#691f218
ed a0 
        ldi
#d0a1#6921218
ed a0 
        ldi
#d0a3#6923218
ed a0 
        ldi
#d0a5#6925111
d1 
    pop de
#d0a6#6926111
c1 
    pop bc
#d0a7#692715
14 
    inc d  ; next pixel row
#d0a8#6928214/9
10 d1 
    djnz Ld07b_row_inner_loop
#d0aa#692a
    ; update the video pointer to the next block of 8 rows:
#d0aa#692a15
7b 
    ld a, e
#d0ab#692b28
c6 20 
    add a, 32
#d0ad#692d15
5f 
    ld e, a
#d0ae#692e213/8
38 04 
    jr c, Ld0b4
#d0b0#693015
7a 
    ld a, d
#d0b1#693128
d6 08 
    sub 8
#d0b3#693315
57 
    ld d, a
#d0b4#6934
Ld0b4:
#d0b4#693415
0d 
    dec c
#d0b5#6935311
c2 79 d0 
    jp nz, Ld079_row_outer_loop
#d0b8#6938111
c9 
    ret
#d0b9#6939
#d0b9#6939
#d0b9#6939
; --------------------------------
#d0b9#6939
; Clear the screen
#d0b9#6939
Ld0b9_clear_screen:
#d0b9#693915
af 
    xor a
#d0ba#693a212
d3 fe 
    out (ULA_PORT), a  ; set border to black, speaker off
#d0bc#693c311
21 00 40 
    ld hl, #4000
#d0bf#693f311
11 01 40 
    ld de, #4001
#d0c2#6942311
01 ff 1a 
    ld bc, 6911
#d0c5#6945211
36 00 
    ld (hl), 0
#d0c7#6947223/18
ed b0 
    ldir
#d0c9#6949111
c9 
    ret
#d0ca#694a
#d0ca#694a
#d0ca#694a
; --------------------------------
#d0ca#694a
Ld0ca_draw_in_game_screen_and_hud:
#d0ca#694a318
cd b9 d0 
    call Ld0b9_clear_screen
#d0cd#694d318
cd bd cc 
    call Lccbd_redraw_game_area
#d0d0#6950
    ; Draw white frame around the game area:
#d0d0#6950
    ; Top horizontal black line 1:
#d0d0#6950311
21 00 40 
    ld hl, L4000_VIDEOMEM_PATTERNS  ; (x, y) = (0, 0)
#d0d3#6953311
11 01 40 
    ld de, L4000_VIDEOMEM_PATTERNS + 1
#d0d6#6956311
01 15 00 
    ld bc, 21
#d0d9#6959211
36 ff 
    ld (hl), 255
#d0db#695b223/18
ed b0 
    ldir
#d0dd#695d
    ; Top horizontal black line 2:
#d0dd#695d311
21 01 47 
    ld hl, L4000_VIDEOMEM_PATTERNS + #0701  ; (x, y) = (8, 7)
#d0e0#6960311
11 02 47 
    ld de, L4000_VIDEOMEM_PATTERNS + #0702
#d0e3#6963311
01 13 00 
    ld bc, 19
#d0e6#6966211
36 ff 
    ld (hl), 255
#d0e8#6968223/18
ed b0 
    ldir
#d0ea#696a
    ; Bottom horizontal black line 1:
#d0ea#696a311
21 a1 50 
    ld hl, L4000_VIDEOMEM_PATTERNS + #10a1  ; (x, y) = (8, 168)
#d0ed#696d311
11 a2 50 
    ld de, L4000_VIDEOMEM_PATTERNS + #10a2
#d0f0#6970311
01 13 00 
    ld bc, 19
#d0f3#6973211
36 ff 
    ld (hl), 255
#d0f5#6975223/18
ed b0 
    ldir
#d0f7#6977
    ; Bottom horizontal black line 2:
#d0f7#6977311
21 a0 57 
    ld hl, L4000_VIDEOMEM_PATTERNS + #17a0  ; (x, y) = (0, 175)
#d0fa#697a311
11 a1 57 
    ld de, L4000_VIDEOMEM_PATTERNS + #17a1
#d0fd#697d311
01 15 00 
    ld bc, 21
#d100#6980211
36 ff 
    ld (hl), 255
#d102#6982223/18
ed b0 
    ldir
#d104#6984
    ; top-left corner:
#d104#6984311
21 00 41 
    ld hl, L4000_VIDEOMEM_PATTERNS + #0100  ; (x, y) = (0, 1)
#d107#698728
06 06 
    ld b, 6
#d109#6989
Ld109_loop:
#d109#6989211
36 80 
    ld (hl), 128
#d10b#698b15
24 
    inc h
#d10c#698c214/9
10 fb 
    djnz Ld109_loop
#d10e#698e
    ; top-right corner:
#d10e#698e311
21 15 41 
    ld hl, L4000_VIDEOMEM_PATTERNS + #0115  ; (x, y) = (168, 1)
#d111#699128
06 06 
    ld b, 6
#d113#6993
Ld113_loop:
#d113#6993211
36 01 
    ld (hl), 1
#d115#699515
24 
    inc h
#d116#6996214/9
10 fb 
    djnz Ld113_loop
#d118#6998
    ; bottom-left corner:
#d118#6998311
21 a0 50 
    ld hl, L4000_VIDEOMEM_PATTERNS + #10a0  ; (x, y) = (0, 168)
#d11b#699b28
06 07 
    ld b, 7
#d11d#699d
Ld11d_loop:
#d11d#699d211
36 80 
    ld (hl), 128
#d11f#699f15
24 
    inc h
#d120#69a0214/9
10 fb 
    djnz Ld11d_loop
#d122#69a2
    ; bottom-right corner:
#d122#69a2311
21 b5 50 
    ld hl, L4000_VIDEOMEM_PATTERNS + #10b5  ; (x, y) = (168, 168)
#d125#69a528
06 07 
    ld b, 7
#d127#69a7
Ld127_loop:
#d127#69a7211
36 01 
    ld (hl), 1
#d129#69a915
24 
    inc h
#d12a#69aa214/9
10 fb 
    djnz Ld127_loop
#d12c#69ac
    ; left bar:
#d12c#69ac311
21 00 47 
    ld hl, L4000_VIDEOMEM_PATTERNS + #0700  ; (x, y) = (0, 7)
#d12f#69af28
06 a2 
    ld b, 162
#d131#69b1
Ld131_loop:
#d131#69b1211
36 81 
    ld (hl), 129
#d133#69b3318
cd 2a d3 
    call Ld32a_inc_video_ptr_y_hl
#d136#69b6214/9
10 f9 
    djnz Ld131_loop
#d138#69b8
    ; right bar:
#d138#69b8311
21 15 47 
    ld hl, L4000_VIDEOMEM_PATTERNS + #0715  ; (x, y) = (128, 7)
#d13b#69bb28
06 a2 
    ld b, 162
#d13d#69bd
Ld13d_loop:
#d13d#69bd211
36 81 
    ld (hl), 129
#d13f#69bf318
cd 2a d3 
    call Ld32a_inc_video_ptr_y_hl
#d142#69c2214/9
10 f9 
    djnz Ld13d_loop
#d144#69c4
#d144#69c4
    ; Set the screen attributes:
#d144#69c4
    ; Whole thing to WHITE over BLACK to start:
#d144#69c4311
21 00 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES
#d147#69c7311
11 01 58 
    ld de, L5800_VIDEOMEM_ATTRIBUTES + 1
#d14a#69ca311
01 ff 02 
    ld bc, 767
#d14d#69cd211
36 07 
    ld (hl), COLOR_WHITE
#d14f#69cf223/18
ed b0 
    ldir
#d151#69d1
    ; Black over white for the frame around the game (top)""
#d151#69d1
    ; Potential optimization: If we change the pixels in the border drawing code above, we can 
#d151#69d1
    ; remove all of the lines below for the frame attributes
#d151#69d1
    ; Top line:
#d151#69d1311
21 00 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES
#d154#69d4311
11 01 58 
    ld de, L5800_VIDEOMEM_ATTRIBUTES + 1
#d157#69d7311
01 15 00 
    ld bc, 21
#d15a#69da211
36 78 
    ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER
#d15c#69dc223/18
ed b0 
    ldir
#d15e#69de
    ; Bottom line:
#d15e#69de311
21 a0 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #02a0
#d161#69e1311
11 a1 5a 
    ld de, L5800_VIDEOMEM_ATTRIBUTES + #02a0 + 1
#d164#69e4311
01 15 00 
    ld bc, 21
#d167#69e7211
36 78 
    ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER
#d169#69e9223/18
ed b0 
    ldir
#d16b#69eb
    ; Side bars:
#d16b#69eb311
21 20 58 
    ld hl, 22560
#d16e#69ee28
06 14 
    ld b, 20
#d170#69f0
Ld170_loop:
#d170#69f0211
36 78 
    ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER
#d172#69f228
3e 15 
    ld a, 21
#d174#69f4318
cd 51 d3 
    call Ld351_add_hl_a
#d177#69f7211
36 78 
    ld (hl), COLOR_BRIGHT + COLOR_WHITE * PAPER_COLOR_MULTIPLIER
#d179#69f928
3e 0b 
    ld a, 11
#d17b#69fb318
cd 51 d3 
    call Ld351_add_hl_a
#d17e#69fe214/9
10 f0 
    djnz Ld170_loop
#d180#6a00
#d180#6a00
    ; In-game screen yellow color:
#d180#6a00311
21 21 58 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0021
#d183#6a03311
01 14 14 
    ld bc, #1414  ; 20, 20
#d186#6a06
Ld186_outer_loop:
#d186#6a06112
c5 
    push bc
#d187#6a07
Ld187_inner_loop:
#d187#6a07211
36 70 
        ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER
#d189#6a0917
23 
        inc hl
#d18a#6a0a214/9
10 fb 
        djnz Ld187_inner_loop
#d18c#6a0c111
c1 
    pop bc
#d18d#6a0d28
3e 0c 
    ld a, 12
#d18f#6a0f318
cd 51 d3 
    call Ld351_add_hl_a
#d192#6a1215
0d 
    dec c
#d193#6a13213/8
20 f1 
    jr nz, Ld186_outer_loop
#d195#6a15
#d195#6a15
    ; blue 3-d effect in the bottom-right of the map:
#d195#6a15
    ; Yellow -> blue border:
#d195#6a1528
06 04 
    ld b, 4
#d197#6a17311
21 33 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0233
#d19a#6a1a
Ld19a_loop:
#d19a#6a1a211
36 71 
    ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER + COLOR_BLUE
#d19c#6a1c17
23 
    inc hl
#d19d#6a1d211
36 71 
    ld (hl), COLOR_BRIGHT + COLOR_YELLOW * PAPER_COLOR_MULTIPLIER + COLOR_BLUE
#d19f#6a1f28
3e 1d 
    ld a, 29
#d1a1#6a21318
cd 51 d3 
    call Ld351_add_hl_a
#d1a4#6a24214/9
10 f4 
    djnz Ld19a_loop
#d1a6#6a26
    ; Blue -> black border:
#d1a6#6a26311
21 53 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0253
#d1a9#6a29211
36 41 
    ld (hl), COLOR_BRIGHT + COLOR_BLUE
#d1ab#6a2b17
23 
    inc hl
#d1ac#6a2c211
36 41 
    ld (hl), COLOR_BRIGHT + COLOR_BLUE
#d1ae#6a2e311
21 71 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #0271
#d1b1#6a3128
06 04 
    ld b, 4
#d1b3#6a33
Ld1b3_loop:
#d1b3#6a33211
36 41 
    ld (hl), COLOR_BRIGHT + COLOR_BLUE
#d1b5#6a3517
23 
    inc hl
#d1b6#6a36214/9
10 fb 
    djnz Ld1b3_loop
#d1b8#6a38311
21 8f 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #028f
#d1bb#6a3b28
06 06 
    ld b, 6
#d1bd#6a3d
Ld1bd_loop:
#d1bd#6a3d211
36 41 
    ld (hl), COLOR_BRIGHT + COLOR_BLUE
#d1bf#6a3f17
23 
    inc hl
#d1c0#6a40214/9
10 fb 
    djnz Ld1bd_loop
#d1c2#6a42
#d1c2#6a42318
cd 2d d4 
    call Ld42d_execute_ui_script
#d1c5#6a45
    ; Script start:
#d1c5#6a452
        db CMD_SET_ATTRIBUTE, #57
#d1c7#6a473
        db CMD_SET_POSITION, #00, #16
#d1ca#6a4a2
        db CMD_SET_SCALE, #00
#d1cc#6a4c5
        db " DAY:"
#d1d1#6a511
        db CMD_NEXT_LINE
#d1d2#6a525
        db "TIME:"
#d1d7#6a573
        db CMD_SET_POSITION, #16, #00
#d1da#6a5a2
        db CMD_SET_SCALE, #21
#d1dc#6a5c2
        db CMD_SET_ATTRIBUTE, #45
#d1de#6a5e6
        db "RADAR:"
#d1e4#6a641
        db CMD_END
#d1e5#6a65
    ; Script end:
#d1e5#6a65
Ld1e5_draw_in_game_right_hud:
#d1e5#6a65318
cd f6 d2 
    call Ld2f6_clear_in_game_right_hud
#d1e8#6a68318
cd 2d d4 
    call Ld42d_execute_ui_script
#d1eb#6a6b
    ; Script start:
#d1eb#6a6b3
        db CMD_SET_POSITION, #03, #16
#d1ee#6a6e2
        db CMD_SET_ATTRIBUTE, #46
#d1f0#6a708
        db "  STATUS"
#d1f8#6a781
        db CMD_NEXT_LINE
#d1f9#6a7910
        db "INSG  HUMN"
#d203#6a833
        db CMD_SET_POSITION, #06, #17
#d206#6a862
        db CMD_SET_ATTRIBUTE, #45
#d208#6a888
        db "WARBASES"
#d210#6a901
        db CMD_NEXT_LINE
#d211#6a918
        db "ELECTR'S"
#d219#6a991
        db CMD_NEXT_LINE
#d21a#6a9a7
        db "NUCLEAR"
#d221#6aa11
        db CMD_NEXT_LINE
#d222#6aa27
        db "PHASERS"
#d229#6aa91
        db CMD_NEXT_LINE
#d22a#6aaa8
        db "MISSILES"
#d232#6ab21
        db CMD_NEXT_LINE
#d233#6ab37
        db " CANNON"
#d23a#6aba1
        db CMD_NEXT_LINE
#d23b#6abb7
        db "CHASSIS"
#d242#6ac21
        db CMD_NEXT_LINE
#d243#6ac37
        db " ROBOTS"
#d24a#6aca3
        db CMD_SET_POSITION, #0f, #17
#d24d#6acd2
        db CMD_SET_ATTRIBUTE, #46
#d24f#6acf9
        db "RESOURCES"
#d258#6ad81
        db CMD_NEXT_LINE
#d259#6ad91
        db CMD_NEXT_LINE
#d25a#6ada2
        db CMD_SET_ATTRIBUTE, #44
#d25c#6adc7
        db "GENERAL"
#d263#6ae31
        db CMD_NEXT_LINE
#d264#6ae47
        db "ELECTR'"
#d26b#6aeb1
        db CMD_NEXT_LINE
#d26c#6aec7
        db "NUCLEAR"
#d273#6af31
        db CMD_NEXT_LINE
#d274#6af47
        db "PHASERS"
#d27b#6afb1
        db CMD_NEXT_LINE
#d27c#6afc7
        db "MISSILE"
#d283#6b031
        db CMD_NEXT_LINE
#d284#6b046
        db "CANNON"
#d28a#6b0a1
        db CMD_NEXT_LINE
#d28b#6b0b7
        db "CHASSIS"
#d292#6b121
        db CMD_END
#d293#6b13
    ; Script end:
#d293#6b13
Ld293_update_stats_in_right_hud:
#d293#6b13314
3a 39 fd 
    ld a, (Lfd39_current_in_game_right_hud)
#d296#6b1615
b7 
    or a
#d297#6b17112/6
c0 
    ret nz  ; If the stats are not to be displayed now, just return
#d298#6b18318
cd 2d d4 
    call Ld42d_execute_ui_script
#d29b#6b1b
    ; Script start:
#d29b#6b1b3
        db CMD_SET_POSITION, #10, #1e
#d29e#6b1e2
        db CMD_SET_ATTRIBUTE, #4e
#d2a0#6b202
        db CMD_SET_SCALE, #00
#d2a2#6b221
        db CMD_END
#d2a3#6b23
    ; Script end:
#d2a3#6b23
    ; Print player resources:
#d2a3#6b23311
21 22 fd 
    ld hl, Lfd22_player1_resource_counts
#d2a6#6b2628
06 07 
    ld b, 7
#d2a8#6b28
Ld2a8_player_resources_loop:
#d2a8#6b28112
c5 
    push bc
#d2a9#6b29112
e5 
        push hl
#d2aa#6b2a318
cd 70 d4 
            call Ld470_execute_command_3_next_line
#d2ad#6b2d111
e1 
        pop hl
#d2ae#6b2e18
7e 
        ld a, (hl)
#d2af#6b2f17
23 
        inc hl
#d2b0#6b30112
e5 
        push hl
#d2b1#6b31318
cd e5 d3 
            call Ld3e5_render_8bit_number
#d2b4#6b34111
e1 
        pop hl
#d2b5#6b35111
c1 
    pop bc
#d2b6#6b36214/9
10 f0 
    djnz Ld2a8_player_resources_loop
#d2b8#6b38
#d2b8#6b38
    ; Print AI stats:
#d2b8#6b38318
cd 2d d4 
    call Ld42d_execute_ui_script
#d2bb#6b3b
    ; Script start:
#d2bb#6b3b3
        db CMD_SET_POSITION, #06, #16
#d2be#6b3e2
        db CMD_SET_ATTRIBUTE, #47
#d2c0#6b401
        db CMD_END
#d2c1#6b41
    ; Script end:
#d2c1#6b41311
21 42 fd 
    ld hl, Lfd42_player2_base_factory_counts
#d2c4#6b44318
cd e3 d2 
    call Ld2e3_draw_warbase_factory_counts
#d2c7#6b4718
7e 
    ld a, (hl)
#d2c8#6b48318
cd ec d3 
    call Ld3ec_render_8bit_number_with_leading_zeroes
#d2cb#6b4b
#d2cb#6b4b
    ; Print Player stats:
#d2cb#6b4b318
cd 2d d4 
    call Ld42d_execute_ui_script
#d2ce#6b4e
    ; Script start:
#d2ce#6b4e3
        db CMD_SET_POSITION, #06, #1f
#d2d1#6b511
        db CMD_END
#d2d2#6b52
    ; Script end
#d2d2#6b52311
21 3a fd 
    ld hl, Lfd3a_player1_base_factory_counts
#d2d5#6b55318
cd e3 d2 
    call Ld2e3_draw_warbase_factory_counts
#d2d8#6b58318
cd 2d d4 
    call Ld42d_execute_ui_script
#d2db#6b5b
    ; Script start:
#d2db#6b5b3
        db CMD_SET_POSITION, #0d, #1e
#d2de#6b5e1
        db CMD_END
#d2df#6b5f
    ; Script end
#d2df#6b5f18
7e 
    ld a, (hl)
#d2e0#6b60311
c3 ec d3 
    jp Ld3ec_render_8bit_number_with_leading_zeroes
#d2e3#6b63
#d2e3#6b63
#d2e3#6b63
; --------------------------------
#d2e3#6b63
; Draws the number of warbases and factories of each type a given player owns.
#d2e3#6b63
; Inputs:
#d2e3#6b63
; - hl: counts pointer
#d2e3#6b63
Ld2e3_draw_warbase_factory_counts:
#d2e3#6b6328
06 07 
    ld b, 7
#d2e5#6b65
Ld2e5_draw_warbase_factory_counts_loop:
#d2e5#6b65112
c5 
    push bc
#d2e6#6b6618
7e 
        ld a, (hl)
#d2e7#6b6717
23 
        inc hl
#d2e8#6b6828
c6 30 
        add a, 48
#d2ea#6b6a318
cd 27 d4 
        call Ld427_draw_character_saving_registers
#d2ed#6b6d112
e5 
        push hl
#d2ee#6b6e318
cd 70 d4 
            call Ld470_execute_command_3_next_line
#d2f1#6b71111
e1 
        pop hl
#d2f2#6b72111
c1 
    pop bc
#d2f3#6b73214/9
10 f0 
    djnz Ld2e5_draw_warbase_factory_counts_loop
#d2f5#6b75111
c9 
    ret
#d2f6#6b76
#d2f6#6b76
#d2f6#6b76
; --------------------------------
#d2f6#6b76
; Clears the right-hand-size hud in-game, except for the day and time.
#d2f6#6b76
Ld2f6_clear_in_game_right_hud:
#d2f6#6b76318
cd 2d d4 
    call Ld42d_execute_ui_script
#d2f9#6b79
    ; Script start:
#d2f9#6b793
        db CMD_SET_POSITION, #02, #16
#d2fc#6b7c2
        db CMD_SET_SCALE, #00
#d2fe#6b7e2
        db CMD_SET_ATTRIBUTE, #00
#d300#6b801
        db CMD_END
#d301#6b81
    ; Script end:
#d301#6b8128
06 16 
    ld b, 22  ; Clears 22 lines (everything but the top two, which is the day and time):
#d303#6b83
Ld303_loop:
#d303#6b83318
cd 2d d4 
    call Ld42d_execute_ui_script
#d306#6b86
    ; Script start:
#d306#6b8610
        db "          "
#d310#6b901
        db CMD_NEXT_LINE
#d311#6b911
        db CMD_END
#d312#6b92
    ; Script end:
#d312#6b92214/9
10 ef 
    djnz Ld303_loop
#d314#6b94111
c9 
    ret
#d315#6b95
#d315#6b95
#d315#6b95
; --------------------------------
#d315#6b95
; Input:
#d315#6b95
; - de: video pointer to draw
#d315#6b95
; - hl: sprite ptr in RAM
#d315#6b95
; - b: prite width in bytes
#d315#6b95
; - c: sprite height in pixels
#d315#6b95
Ld315_draw_masked_sprite_bottom_up:
#d315#6b95
Ld315_draw_masked_sprite_x_loop:
#d315#6b95112
c5 
    push bc
#d316#6b96112
d5 
    push de
#d317#6b97
Ld317_draw_masked_sprite_y_loop:
#d317#6b9718
1a 
        ld a, (de)  ; get a pixel from the screen
#d318#6b9818
a6 
        and (hl)  ; and mask (clear some pixels)
#d319#6b9917
23 
        inc hl
#d31a#6b9a18
b6 
        or (hl)  ; or mask (draw pixels)
#d31b#6b9b18
12 
        ld (de), a  ; write back to the screen
#d31c#6b9c17
23 
        inc hl  ; next pixel
#d31d#6b9d17
13 
        inc de
#d31e#6b9e214/9
10 f7 
        djnz Ld317_draw_masked_sprite_y_loop
#d320#6ba0111
d1 
    pop de
#d321#6ba1111
c1 
    pop bc
#d322#6ba2318
cd 39 d3 
    call Ld339_dec_video_ptr_y_de
#d325#6ba515
0d 
    dec c
#d326#6ba6311
c2 15 d3 
    jp nz, Ld315_draw_masked_sprite_x_loop
#d329#6ba9111
c9 
    ret
#d32a#6baa
#d32a#6baa
#d32a#6baa
; --------------------------------
#d32a#6baa
; Move a pointer 1 pixel down in the screen
#d32a#6baa
; hl: video memory pointer as: 010ccaaa bbbxxxxx
#d32a#6baa
;     The y coordinate is ccbbbaaa
#d32a#6baa
Ld32a_inc_video_ptr_y_hl:
#d32a#6baa15
24 
    inc h
#d32b#6bab28
3e 07 
    ld a, #07
#d32d#6bad15
a4 
    and h
#d32e#6bae112/6
c0 
    ret nz
#d32f#6baf15
7d 
    ld a, l
#d330#6bb028
c6 20 
    add a, 32
#d332#6bb215
6f 
    ld l, a
#d333#6bb3112/6
d8 
    ret c
#d334#6bb415
7c 
    ld a, h
#d335#6bb528
d6 08 
    sub 8
#d337#6bb715
67 
    ld h, a
#d338#6bb8111
c9 
    ret
#d339#6bb9
#d339#6bb9
#d339#6bb9
; --------------------------------
#d339#6bb9
; Move a pointer 1 pixel up in the screen
#d339#6bb9
; hl: video memory pointer as: 010ccaaa bbbxxxxx
#d339#6bb9
;     The y coordinate is ccbbbaaa
#d339#6bb9
Ld339_dec_video_ptr_y_de:
#d339#6bb915
7a 
    ld a, d
#d33a#6bba15
15 
    dec d
#d33b#6bbb28
e6 07 
    and #07
#d33d#6bbd112/6
c0 
    ret nz
#d33e#6bbe15
7b 
    ld a, e
#d33f#6bbf28
d6 20 
    sub 32
#d341#6bc115
5f 
    ld e, a
#d342#6bc2112/6
d8 
    ret c
#d343#6bc315
7a 
    ld a, d
#d344#6bc428
c6 08 
    add a, 8
#d346#6bc615
57 
    ld d, a
#d347#6bc7111
c9 
    ret
#d348#6bc8
#d348#6bc8
#d348#6bc8
; --------------------------------
#d348#6bc8
; input:
#d348#6bc8
; - a, hl
#d348#6bc8
; output:
#d348#6bc8
; - hl = (hl + a*2)
#d348#6bc8
Ld348_get_ptr_from_table:
#d348#6bc815
87 
    add a, a
#d349#6bc9318
cd 51 d3 
    call Ld351_add_hl_a
#d34c#6bcc18
7e 
    ld a, (hl)
#d34d#6bcd17
23 
    inc hl
#d34e#6bce18
66 
    ld h, (hl)
#d34f#6bcf15
6f 
    ld l, a
#d350#6bd0111
c9 
    ret
#d351#6bd1
#d351#6bd1
#d351#6bd1
; --------------------------------
#d351#6bd1
; hl = hl + a
#d351#6bd1
Ld351_add_hl_a:
#d351#6bd115
85 
    add a, l
#d352#6bd215
6f 
    ld l, a
#d353#6bd315
7c 
    ld a, h
#d354#6bd428
ce 00 
    adc a, 0
#d356#6bd615
67 
    ld h, a
#d357#6bd7111
c9 
    ret
#d358#6bd8
#d358#6bd8
#d358#6bd8
; --------------------------------
#d358#6bd8
; Random number generation: uses a 4 byte seed buffer in #fd00
#d358#6bd8
; output:
#d358#6bd8
; - a: next random number
#d358#6bd8
; preserves: hl
#d358#6bd8
Ld358_random:
#d358#6bd8112
e5 
    push hl
#d359#6bd9311
21 00 fd 
        ld hl, Lfd00_random_seed
#d35c#6bdc18
7e 
        ld a, (hl)
#d35d#6bdd28
e6 48 
        and 72
#d35f#6bdf28
c6 38 
        add a, 56
#d361#6be115
07 
        rlca
#d362#6be215
07 
        rlca
#d363#6be328
2e 03 
        ld l, 3
#d365#6be5217
cb 16 
        rl (hl)
#d367#6be715
2d 
        dec l
#d368#6be8217
cb 16 
        rl (hl)
#d36a#6bea15
2d 
        dec l
#d36b#6beb217
cb 16 
        rl (hl)
#d36d#6bed15
2d 
        dec l
#d36e#6bee217
cb 16 
        rl (hl)
#d370#6bf0
Ld370_selfmodifying: equ $ + 1
#d370#6bf028
2e 00 
        ld l, 0  ; mdl:self-modifying
#d372#6bf218
7e 
        ld a, (hl)
#d373#6bf328
e6 03 
        and 3
#d375#6bf515
6f 
        ld l, a
#d376#6bf6314
32 71 d3 
        ld (Ld370_selfmodifying), a  ; self-modifying: overwrites the argument of the instruction 
#d379#6bf9
                                       ; marked above.
#d379#6bf918
7e 
        ld a, (hl)
#d37a#6bfa111
e1 
    pop hl
#d37b#6bfb111
c9 
    ret
#d37c#6bfc
#d37c#6bfc
#d37c#6bfc
; --------------------------------
#d37c#6bfc
; Reads the keyboard and joystick input, and stores the state in (Lfd0c_keyboard_state).
#d37c#6bfc
; - If the user presses the pause key, this function is blocked until the user presses it again.
#d37c#6bfc
; Output:
#d37c#6bfc
; - a: keyboard state (also stored in "Lfd0c_keyboard_state")
#d37c#6bfc
Ld37c_read_keyboard_joystick_input:
#d37c#6bfc318
cd 8a d3 
    call Ld38a_read_keyboard_joystick_input_internal
#d37f#6bff15
b7 
    or a
#d380#6c00112/6
f0 
    ret p  ; if pause key was not pressed, return
#d381#6c01
Ld381_pause:
#d381#6c01318
cd 8a d3 
    call Ld38a_read_keyboard_joystick_input_internal
#d384#6c0415
b7 
    or a
#d385#6c05213/8
28 fa 
    jr z, Ld381_pause
#d387#6c07311
fa 81 d3 
    jp m, Ld381_pause
#d38a#6c0a
#d38a#6c0a
Ld38a_read_keyboard_joystick_input_internal:
#d38a#6c0a311
21 cc d3 
    ld hl, Ld3cc_key_pause
#d38d#6c0d28
0e 01 
    ld c, 1  ; set a 1 in the least significant bit, so that when we rotate this 8 times,
#d38f#6c0f
             ; the carry flag is set to indicate end of iteration
#d38f#6c0f
Ld38f_key_loop:
#d38f#6c0f18
7e 
    ld a, (hl)  ; keyboard matrix row to read
#d390#6c1017
23 
    inc hl
#d391#6c11212
db fe 
    in a, (ULA_PORT)  ; a = high byte, ULA_PORT = low byte
#d393#6c1318
a6 
    and (hl)  ; mask to isolate the desired key
#d394#6c1417
23 
    inc hl
#d395#6c1517
23 
    inc hl
#d396#6c16
    ; at this point carry flag is always reset ("inc" does not touch it, and "and" resets it)
#d396#6c16213/8
20 01 
    jr nz, Ld399_key_not_pressed
#d398#6c1815
3f 
    ccf  ; set carry flag
#d399#6c19
Ld399_key_not_pressed:
#d399#6c19210
cb 11 
    rl c  ; add the bit corresponding to one key to "c" (which was in the carry flag)
#d39b#6c1b213/8
30 f2 
    jr nc, Ld38f_key_loop  ; carry flag will be set after 8 loops (checked al 8 keys)
#d39d#6c1d314
3a e4 d3 
    ld a, (Ld3e4_input_type)
#d3a0#6c2028
fe 02 
    cp INPUT_KEMPSTON
#d3a2#6c22213/8
28 07 
    jr z, Ld3ab_read_kempston
#d3a4#6c2428
fe 03 
    cp INPUT_INTERFACE2
#d3a6#6c26213/8
28 0a 
    jr z, Ld3b2_read_interface2
#d3a8#6c2815
af 
    xor a
#d3a9#6c29213
18 1c 
    jr Ld3c7_all_inputs_read
#d3ab#6c2b
Ld3ab_read_kempston:
#d3ab#6c2b15
af 
    xor a
#d3ac#6c2c212
db 1f 
    in a, (KEMPSTON_JOYSTICK_PORT)  ; read the kempston joystick state
#d3ae#6c2e28
e6 1f 
    and #1f
#d3b0#6c30213
18 15 
    jr Ld3c7_all_inputs_read
#d3b2#6c32
Ld3b2_read_interface2:
#d3b2#6c3228
3e ef 
    ld a, INTERFACE2_JOYSTICK_PORT_MSB  ; read the interface2 joystick state.
#d3b4#6c34212
db fe 
    in a, (ULA_PORT)  ; a = high byte, ULA_PORT = low byte
#d3b6#6c3615
2f 
    cpl
#d3b7#6c3728
e6 1f 
    and #1f
#d3b9#6c39
    ; reorder the interface2 bits so they are in the same order as they keyboard ones:
#d3b9#6c3915
47 
    ld b, a
#d3ba#6c3a15
af 
    xor a
#d3bb#6c3b210
cb 38 
    srl b
#d3bd#6c3d15
17 
    rla
#d3be#6c3e210
cb 38 
    srl b
#d3c0#6c4015
17 
    rla
#d3c1#6c41210
cb 38 
    srl b
#d3c3#6c4315
17 
    rla
#d3c4#6c4415
17 
    rla
#d3c5#6c4515
17 
    rla
#d3c6#6c4615
b0 
    or b
#d3c7#6c47
Ld3c7_all_inputs_read:
#d3c7#6c4715
b1 
    or c  ; potentially add joystick inputs over to the keyboard ones
#d3c8#6c48314
32 0c fd 
    ld (Lfd0c_keyboard_state), a
#d3cb#6c4b111
c9 
    ret
#d3cc#6c4c
#d3cc#6c4c
#d3cc#6c4c
; --------------------------------
#d3cc#6c4c
; Array storing the redefined keys:
#d3cc#6c4c
; - first byte is the high byte of the address to read from to get the correct keyboard matrix row.
#d3cc#6c4c
; - the second is the mask we need to apply to the value read from the keyboard matrix to isolate 
#d3cc#6c4c
;   the key.
#d3cc#6c4c
; - third value is the ascii representation of the key.
#d3cc#6c4c
Ld3cc_key_pause:
#d3cc#6c4c3
    db #f7, #01, #31  ; 247,  1, "1"
#d3cf#6c4f
Ld3cf_key_abort:
#d3cf#6c4f3
    db #df, #04, #49  ; 223,  4, "I"
#d3d2#6c52
Ld3d2_key_save:
#d3d2#6c523
    db #f7, #10, #35  ; 247, 16, "5"
#d3d5#6c55
Ld3d5_key_fire:
#d3d5#6c553
    db #7f, #02, #82  ; 127,  2, 130
#d3d8#6c58
Ld3d8_key_up:
#d3d8#6c583
    db #fb, #01, #51  ; 251,  1, "Q"
#d3db#6c5b
Ld3db_key_down:
#d3db#6c5b3
    db #fd, #01, #41  ; 253,  1, "A"
#d3de#6c5e
Ld3de_key_left:
#d3de#6c5e3
    db #df, #02, #4f  ; 223,  2, "O"
#d3e1#6c61
Ld3e1_key_right:
#d3e1#6c613
    db #df, #01, #50  ; 223,  1, "P"
#d3e4#6c64
Ld3e4_input_type:
#d3e4#6c641
    db #01
#d3e5#6c65
#d3e5#6c65
#d3e5#6c65
; --------------------------------
#d3e5#6c65
Ld3e5_render_8bit_number:
#d3e5#6c6515
6f 
    ld l, a
#d3e6#6c6628
26 00 
    ld h, 0
#d3e8#6c6828
1e 20 
    ld e, " "
#d3ea#6c6a213
18 1b 
    jr Ld407_render_16bit_number_2digits
#d3ec#6c6c
#d3ec#6c6c
#d3ec#6c6c
; --------------------------------
#d3ec#6c6c
Ld3ec_render_8bit_number_with_leading_zeroes:
#d3ec#6c6c15
6f 
    ld l, a
#d3ed#6c6d28
26 00 
    ld h, 0
#d3ef#6c6f28
1e 00 
    ld e, 0
#d3f1#6c71213
18 14 
    jr Ld407_render_16bit_number_2digits
#d3f3#6c73
#d3f3#6c73
#d3f3#6c73
; --------------------------------
#d3f3#6c73
; Draws a 16bit number to screen.
#d3f3#6c73
; input:
#d3f3#6c73
; - hl: the number to draw
#d3f3#6c73
Ld3f3_render_16bit_number:
#d3f3#6c73311
01 f0 d8 
    ld bc, -10000
#d3f6#6c7628
1e 20 
    ld e, " "
#d3f8#6c78318
cd 13 d4 
    call Ld413_render_16bit_number_one_digit
#d3fb#6c7b311
01 18 fc 
    ld bc, -1000
#d3fe#6c7e318
cd 13 d4 
    call Ld413_render_16bit_number_one_digit
#d401#6c81
Ld401_render_16bit_number_3digits:
#d401#6c81311
01 9c ff 
    ld bc, -100
#d404#6c84318
cd 13 d4 
    call Ld413_render_16bit_number_one_digit
#d407#6c87
Ld407_render_16bit_number_2digits:
#d407#6c87311
01 f6 ff 
    ld bc, -10
#d40a#6c8a
Ld40a:
#d40a#6c8a318
cd 13 d4 
    call Ld413_render_16bit_number_one_digit
#d40d#6c8d15
7d 
    ld a, l
#d40e#6c8e28
c6 30 
    add a, 48
#d410#6c90311
c3 27 d4 
    jp Ld427_draw_character_saving_registers
#d413#6c93
#d413#6c93
#d413#6c93
; --------------------------------
#d413#6c93
; - hl: number to draw.
#d413#6c93
; - bc: unit to draw (-10 for tenths, -100 for hundreds, -1000 for thousands, etc.).
#d413#6c93
; - e: filler character to use in the left for the leading zeros.
#d413#6c93
Ld413_render_16bit_number_one_digit:
#d413#6c9315
af 
    xor a
#d414#6c94
Ld414_remainder_loop:
#d414#6c94112
09 
    add hl, bc
#d415#6c9515
3c 
    inc a
#d416#6c96213/8
38 fc 
    jr c, Ld414_remainder_loop
#d418#6c98217
ed 42 
    sbc hl, bc
#d41a#6c9a15
3d 
    dec a  ; Here, a = hl / (-bc), and hl = hl % (-bc)
#d41b#6c9b213/8
20 07 
    jr nz, Ld424
#d41d#6c9d15
7b 
    ld a, e
#d41e#6c9e28
fe 20 
    cp 32
#d420#6ca0311
ca 27 d4 
    jp z, Ld427_draw_character_saving_registers
#d423#6ca315
af 
    xor a
#d424#6ca4
Ld424:
#d424#6ca415
1c 
    inc e  ; if the filler character was a space, change it so that the rest of 
#d425#6ca5
           ; empty digits are rendered as zeros.
#d425#6ca528
c6 30 
    add a, 48  ; '0'
#d427#6ca7
Ld427_draw_character_saving_registers:
#d427#6ca715
d9 
    exx
#d428#6ca8318
cd b1 d4 
        call Ld4b1_draw_character
#d42b#6cab15
d9 
    exx
#d42c#6cac111
c9 
    ret
#d42d#6cad
#d42d#6cad
#d42d#6cad
; --------------------------------
#d42d#6cad
; Executes some data-defined scripts (pointer of the script is in the stack):
#d42d#6cad
; Script definition:
#d42d#6cad
; - 0: end of script
#d42d#6cad
; - 1: set screen coordinates
#d42d#6cad
; - 2: set attribute
#d42d#6cad
; - 3: next line
#d42d#6cad
; - 4: set scale
#d42d#6cad
; - default: render a character
#d42d#6cad
; input:
#d42d#6cad
; - address of data to use is in the stack
#d42d#6cad
Ld42d_execute_ui_script:
#d42d#6cad15
d9 
    exx
#d42e#6cae
Ld42e_loop:
#d42e#6cae111
e1 
        pop hl
#d42f#6caf18
7e 
        ld a, (hl)
#d430#6cb017
23 
        inc hl
#d431#6cb1112
e5 
        push hl
#d432#6cb215
b7 
        or a
#d433#6cb3213/8
28 05 
        jr z, Ld43a_done
#d435#6cb5318
cd 3c d4 
        call Ld43c_execute_one_command
#d438#6cb8213
18 f4 
        jr Ld42e_loop
#d43a#6cba
Ld43a_done:
#d43a#6cba15
d9 
    exx
#d43b#6cbb111
c9 
    ret
#d43c#6cbc
#d43c#6cbc
#d43c#6cbc
; --------------------------------
#d43c#6cbc
Ld43c_execute_one_command:
#d43c#6cbc28
fe 01 
    cp 1
#d43e#6cbe213/8
28 21 
    jr z, Ld461_execute_command_1_screen_coordinates
#d440#6cc028
fe 02 
    cp 2
#d442#6cc2213/8
28 13 
    jr z, Ld457_execute_command_2_set_attribute
#d444#6cc428
fe 03 
    cp 3
#d446#6cc6213/8
28 28 
    jr z, Ld470_execute_command_3_next_line
#d448#6cc828
fe 04 
    cp 4
#d44a#6cca213/8
28 30 
    jr z, Ld47c_execute_command_4_set_scale
#d44c#6ccc15
4f 
    ld c, a
#d44d#6ccd314
3a 17 fd 
    ld a, (Lfd17_script_scale_x)
#d450#6cd015
b7 
    or a
#d451#6cd115
79 
    ld a, c
#d452#6cd2213/8
28 5d 
    jr z, Ld4b1_draw_character
#d454#6cd4311
c3 da d4 
    jp Ld4b1_draw_character_scaled
#d457#6cd7
#d457#6cd7
#d457#6cd7
; --------------------------------
#d457#6cd7
Ld457_execute_command_2_set_attribute:
#d457#6cd7111
d1 
    pop de
#d458#6cd8111
e1 
    pop hl
#d459#6cd918
7e 
        ld a, (hl)
#d45a#6cda17
23 
        inc hl
#d45b#6cdb112
e5 
    push hl
#d45c#6cdc112
d5 
    push de
#d45d#6cdd314
32 13 fd 
    ld (Lfd13_script_attribute), a
#d460#6ce0111
c9 
    ret
#d461#6ce1
#d461#6ce1
#d461#6ce1
; --------------------------------
#d461#6ce1
Ld461_execute_command_1_screen_coordinates:
#d461#6ce1111
d1 
    pop de
#d462#6ce2111
e1 
    pop hl
#d463#6ce318
46 
        ld b, (hl)
#d464#6ce417
23 
        inc hl
#d465#6ce518
4e 
        ld c, (hl)
#d466#6ce6422
ed 43 31 fd 
        ld (Lfd31_script_coordinate), bc
#d46a#6cea17
23 
        inc hl
#d46b#6ceb112
e5 
    push hl
#d46c#6cec112
d5 
    push de
#d46d#6ced311
c3 93 d4 
    jp Ld493_compute_videomem_ptrs
#d470#6cf0
#d470#6cf0
#d470#6cf0
; --------------------------------
#d470#6cf0
Ld470_execute_command_3_next_line:
#d470#6cf0422
ed 4b 31 fd 
    ld bc, (Lfd31_script_coordinate)
#d474#6cf415
04 
    inc b
#d475#6cf5422
ed 43 31 fd 
    ld (Lfd31_script_coordinate), bc
#d479#6cf9311
c3 93 d4 
    jp Ld493_compute_videomem_ptrs
#d47c#6cfc
#d47c#6cfc
#d47c#6cfc
; --------------------------------
#d47c#6cfc
; Reads one byte: yyyyxxxx, and sets the scale to draw characters from
#d47c#6cfc
; each of the two nibbles of that byte:
#d47c#6cfc
; - (Lfd16_script_scale_y) = xxxx
#d47c#6cfc
; - (Lfd16_script_scale_y) = yyyy
#d47c#6cfc
; Input:
#d47c#6cfc
; - in the stack: ptr to read a byte from (will be incremented)
#d47c#6cfc
Ld47c_execute_command_4_set_scale:
#d47c#6cfc111
d1 
    pop de
#d47d#6cfd111
e1 
    pop hl
#d47e#6cfe18
7e 
        ld a, (hl)
#d47f#6cff17
23 
        inc hl
#d480#6d00112
e5 
    push hl
#d481#6d01112
d5 
    push de
#d482#6d0215
4f 
    ld c, a
#d483#6d0315
0f 
    rrca
#d484#6d0415
0f 
    rrca
#d485#6d0515
0f 
    rrca
#d486#6d0615
0f 
    rrca
#d487#6d0728
e6 0f 
    and 15
#d489#6d09314
32 16 fd 
    ld (Lfd16_script_scale_y), a
#d48c#6d0c15
79 
    ld a, c
#d48d#6d0d28
e6 0f 
    and 15
#d48f#6d0f314
32 17 fd 
    ld (Lfd17_script_scale_x), a
#d492#6d12111
c9 
    ret
#d493#6d13
#d493#6d13
#d493#6d13
; --------------------------------
#d493#6d13
; Recalculate pattern table and attribute table pointers
#d493#6d13
; input:
#d493#6d13
; - bc: value of Lfd31_script_coordinate
#d493#6d13
; output:
#d493#6d13
; - Lfd04_script_video_pattern_ptr
#d493#6d13
; - Lfd14_script_video_attribute_ptr
#d493#6d13
Ld493_compute_videomem_ptrs:
#d493#6d1315
78 
    ld a, b
#d494#6d1428
e6 f8 
    and 248  ; #f8
#d496#6d1628
c6 40 
    add a, 64
#d498#6d1815
67 
    ld h, a  ; h = (b & #f8) + 64
#d499#6d1915
78 
    ld a, b
#d49a#6d1a28
e6 07 
    and 7
#d49c#6d1c15
0f 
    rrca
#d49d#6d1d15
0f 
    rrca
#d49e#6d1e15
0f 
    rrca
#d49f#6d1f15
81 
    add a, c
#d4a0#6d2015
6f 
    ld l, a  ; l = "high 3 bits of b" + c
#d4a1#6d21317
22 04 fd 
    ld (Lfd04_script_video_pattern_ptr), hl
#d4a4#6d2415
7c 
    ld a, h
#d4a5#6d2515
0f 
    rrca
#d4a6#6d2615
0f 
    rrca
#d4a7#6d2715
0f 
    rrca
#d4a8#6d2828
e6 03 
    and 3
#d4aa#6d2a28
f6 58 
    or 88
#d4ac#6d2c15
67 
    ld h, a
#d4ad#6d2d317
22 14 fd 
    ld (Lfd14_script_video_attribute_ptr), hl
#d4b0#6d30111
c9 
    ret
#d4b1#6d31
#d4b1#6d31
#d4b1#6d31
; --------------------------------
#d4b1#6d31
; input:
#d4b1#6d31
; - a: character to draw
#d4b1#6d31
; - (Lfd04_script_video_pattern_ptr) pointer to draw it to in video memory (will be incremented)
#d4b1#6d31
; - (Lfd14_script_video_attribute_ptr) pointer to set the attributes in video memory (will be 
#d4b1#6d31
;   incremented).
#d4b1#6d31
Ld4b1_draw_character:
#d4b1#6d3128
26 00 
    ld h, 0
#d4b3#6d3315
6f 
    ld l, a
#d4b4#6d34112
29 
    add hl, hl
#d4b5#6d35112
29 
    add hl, hl
#d4b6#6d36112
29 
    add hl, hl
#d4b7#6d37311
11 80 66 
    ld de, L6780_graphic_patterns - 32 * 8  ; there is only data for characters starting at ' ' (32)
#d4ba#6d3a112
19 
    add hl, de  ; hl = a * 8 + #6680 : get ptr to character to draw
#d4bb#6d3b422
ed 5b 04 fd 
    ld de, (Lfd04_script_video_pattern_ptr)
#d4bf#6d3f112
d5 
    push de
#d4c0#6d4028
06 08 
        ld b, 8
#d4c2#6d42
Ld4c2_loop:
#d4c2#6d4218
7e 
        ld a, (hl)
#d4c3#6d4318
12 
        ld (de), a
#d4c4#6d4417
23 
        inc hl
#d4c5#6d4515
14 
        inc d
#d4c6#6d46214/9
10 fa 
        djnz Ld4c2_loop
#d4c8#6d48111
d1 
    pop de
#d4c9#6d4917
13 
    inc de
#d4ca#6d4a422
ed 53 04 fd 
    ld (Lfd04_script_video_pattern_ptr), de
#d4ce#6d4e317
2a 14 fd 
    ld hl, (Lfd14_script_video_attribute_ptr)
#d4d1#6d51314
3a 13 fd 
    ld a, (Lfd13_script_attribute)
#d4d4#6d5418
77 
    ld (hl), a
#d4d5#6d5517
23 
    inc hl
#d4d6#6d56317
22 14 fd 
    ld (Lfd14_script_video_attribute_ptr), hl
#d4d9#6d59111
c9 
    ret
#d4da#6d5a
#d4da#6d5a
#d4da#6d5a
; --------------------------------
#d4da#6d5a
; input:
#d4da#6d5a
; - a: character to draw
#d4da#6d5a
Ld4b1_draw_character_scaled:
#d4da#6d5a28
26 00 
    ld h, 0
#d4dc#6d5c15
6f 
    ld l, a
#d4dd#6d5d112
29 
    add hl, hl
#d4de#6d5e112
29 
    add hl, hl
#d4df#6d5f112
29 
    add hl, hl
#d4e0#6d60311
11 80 66 
    ld de, L6780_graphic_patterns - 32 * 8  ; there is only data for characters starting at ' ' (32)
#d4e3#6d63112
19 
    add hl, de  ; hl = a * 8 + #6680 : get ptr to character to draw
#d4e4#6d64314
3a 17 fd 
    ld a, (Lfd17_script_scale_x)
#d4e7#6d6728
fe 02 
    cp 2
#d4e9#6d69213/8
30 17 
    jr nc, Ld502
#d4eb#6d6b15
eb 
    ex de, hl
#d4ec#6d6c317
2a 04 fd 
    ld hl, (Lfd04_script_video_pattern_ptr)
#d4ef#6d6f28
0e 08 
    ld c, 8
#d4f1#6d71
Ld4f1:
#d4f1#6d71314
3a 16 fd 
    ld a, (Lfd16_script_scale_y)
#d4f4#6d7415
47 
    ld b, a
#d4f5#6d75
Ld4f5:
#d4f5#6d7518
1a 
    ld a, (de)
#d4f6#6d7618
77 
    ld (hl), a
#d4f7#6d77318
cd 2a d3 
    call Ld32a_inc_video_ptr_y_hl
#d4fa#6d7a214/9
10 f9 
    djnz Ld4f5
#d4fc#6d7c17
13 
    inc de
#d4fd#6d7d15
0d 
    dec c
#d4fe#6d7e213/8
20 f1 
    jr nz, Ld4f1
#d500#6d80213
18 30 
    jr Ld532
#d502#6d82
Ld502:
#d502#6d82217
dd e5 
    push ix
#d504#6d84112
e5 
        push hl
#d505#6d85216
dd e1 
        pop ix
#d507#6d87317
2a 04 fd 
        ld hl, (Lfd04_script_video_pattern_ptr)
#d50a#6d8a28
0e 08 
        ld c, 8
#d50c#6d8c
Ld50c:
#d50c#6d8c321
dd 7e 00 
        ld a, (ix)
#d50f#6d8f28
06 08 
        ld b, 8
#d511#6d91
Ld511:
#d511#6d9115
07 
        rlca
#d512#6d92112
f5 
        push af
#d513#6d93210
cb 13 
            rl e
#d515#6d95210
cb 12 
            rl d
#d517#6d97111
f1 
        pop af
#d518#6d98210
cb 13 
        rl e
#d51a#6d9a210
cb 12 
        rl d
#d51c#6d9c214/9
10 f3 
        djnz Ld511
#d51e#6d9e314
3a 16 fd 
        ld a, (Lfd16_script_scale_y)
#d521#6da115
47 
        ld b, a
#d522#6da2
Ld522:
#d522#6da218
72 
        ld (hl), d
#d523#6da315
2c 
        inc l
#d524#6da418
73 
        ld (hl), e
#d525#6da515
2d 
        dec l
#d526#6da6318
cd 2a d3 
        call Ld32a_inc_video_ptr_y_hl
#d529#6da9214/9
10 f7 
        djnz Ld522
#d52b#6dab212
dd 23 
        inc ix
#d52d#6dad15
0d 
        dec c
#d52e#6dae213/8
20 dc 
        jr nz, Ld50c
#d530#6db0216
dd e1 
    pop ix
#d532#6db2
Ld532:
#d532#6db2317
2a 04 fd 
    ld hl, (Lfd04_script_video_pattern_ptr)
#d535#6db5314
3a 17 fd 
    ld a, (Lfd17_script_scale_x)
#d538#6db8318
cd 51 d3 
    call Ld351_add_hl_a
#d53b#6dbb317
22 04 fd 
    ld (Lfd04_script_video_pattern_ptr), hl
#d53e#6dbe317
2a 14 fd 
    ld hl, (Lfd14_script_video_attribute_ptr)
#d541#6dc1112
e5 
    push hl
#d542#6dc2422
ed 4b 16 fd 
        ld bc, (Lfd16_script_scale_y)
#d546#6dc6314
3a 13 fd 
        ld a, (Lfd13_script_attribute)
#d549#6dc915
5f 
        ld e, a
#d54a#6dca
Ld54a:
#d54a#6dca112
e5 
        push hl
#d54b#6dcb112
c5 
        push bc
#d54c#6dcc
Ld54c:
#d54c#6dcc18
73 
            ld (hl), e
#d54d#6dcd17
23 
            inc hl
#d54e#6dce214/9
10 fc 
            djnz Ld54c
#d550#6dd0111
c1 
        pop bc
#d551#6dd1111
e1 
        pop hl
#d552#6dd215
7d 
        ld a, l
#d553#6dd328
c6 20 
        add a, 32
#d555#6dd515
6f 
        ld l, a
#d556#6dd615
7c 
        ld a, h
#d557#6dd728
ce 00 
        adc a, 0
#d559#6dd915
67 
        ld h, a
#d55a#6dda15
0d 
        dec c
#d55b#6ddb213/8
20 ed 
        jr nz, Ld54a
#d55d#6ddd111
e1 
    pop hl
#d55e#6dde15
78 
    ld a, b
#d55f#6ddf318
cd 51 d3 
    call Ld351_add_hl_a
#d562#6de2317
22 14 fd 
    ld (Lfd14_script_video_attribute_ptr), hl
#d565#6de5111
c9 
    ret
#d566#6de6
#d566#6de6
#d566#6de6
; --------------------------------
#d566#6de6
; Interrupt handler routine
#d566#6de6
Ld566_interrupt:
#d566#6de6112
f5 
    push af
#d567#6de7112
c5 
    push bc
#d568#6de8112
d5 
    push de
#d569#6de9112
e5 
    push hl
#d56a#6dea
        ; Increments the # of interrupts counter (for game timing purposes):
#d56a#6dea311
21 34 fd 
        ld hl, Lfd34_n_interrupts_this_came_cycle
#d56d#6ded112
34 
        inc (hl)
#d56e#6dee
        ; Draw the radar (flickering):
#d56e#6dee
        ; Player and enemy robots are drawn to view1 and view2 respectively, and in this way, when 
#d56e#6dee
        ; showing them, they show in different colors.
#d56e#6dee311
21 00 d8 
        ld hl, Ld800_radar_view1
#d571#6df128
0e 4d 
        ld c, COLOR_BRIGHT + COLOR_CYAN + PAPER_COLOR_MULTIPLIER * COLOR_BLUE
#d573#6df3314
3a 1a fd 
        ld a, (Lfd1a_interrupt_parity)
#d576#6df628
ee 01 
        xor 1
#d578#6df8314
32 1a fd 
        ld (Lfd1a_interrupt_parity), a
#d57b#6dfb213/8
28 05 
        jr z, Ld582_radar_flicker
#d57d#6dfd311
21 00 d9 
        ld hl, Ld900_radar_view2
#d580#6e0028
0e 4e 
        ld c, COLOR_BRIGHT + COLOR_YELLOW + PAPER_COLOR_MULTIPLIER * COLOR_BLUE
#d582#6e02
Ld582_radar_flicker:
#d582#6e02318
cd 9e d5 
        call Ld59e_draw_radar
#d585#6e05314
3a 53 fd 
        ld a, (Lfd53_produce_in_game_sound)
#d588#6e0815
b7 
        or a
#d589#6e09213/8
28 0d 
        jr z, Ld598_no_sound
#d58b#6e0b15
3c 
        inc a
#d58c#6e0c28
fe 80 
        cp 128
#d58e#6e0e213/8
20 01 
        jr nz, Ld591_keep_sound
#d590#6e1015
af 
        xor a
#d591#6e11
Ld591_keep_sound:
#d591#6e11314
32 53 fd 
        ld (Lfd53_produce_in_game_sound), a
#d594#6e1415
b7 
        or a
#d595#6e15318/11
c4 c4 d5 
        call nz, Ld5c4_produce_in_game_sound
#d598#6e18
Ld598_no_sound:
#d598#6e18111
e1 
    pop hl
#d599#6e19111
d1 
    pop de
#d59a#6e1a111
c1 
    pop bc
#d59b#6e1b111
f1 
    pop af
#d59c#6e1c
Ld59c_empty_interrupt:
#d59c#6e1c15
fb 
    ei
#d59d#6e1d111
c9 
    ret
#d59e#6e1e
#d59e#6e1e
#d59e#6e1e
; --------------------------------
#d59e#6e1e
; Draws the radar view to video memory
#d59e#6e1e
Ld59e_draw_radar:
#d59e#6e1e
    ; Draw the radar to video memory:
#d59e#6e1e112
c5 
    push bc
#d59f#6e1f28
06 10 
        ld b, 16
#d5a1#6e21311
11 c6 50 
        ld de, L4000_VIDEOMEM_PATTERNS + #10c6  ; pointer to the "radar" view in video memory
#d5a4#6e24
Ld5a4_draw_radar_loop_y:
#d5a4#6e24112
c5 
        push bc
#d5a5#6e25112
d5 
            push de
#d5a6#6e26
                ; Copy a radar row (16 bytes wide)
#d5a6#6e26311
01 10 00 
                ld bc, 16
#d5a9#6e29223/18
ed b0 
                ldir
#d5ab#6e2b111
d1 
            pop de
#d5ac#6e2c15
eb 
            ex de, hl
#d5ad#6e2d318
cd 2a d3 
                call Ld32a_inc_video_ptr_y_hl
#d5b0#6e3015
eb 
            ex de, hl
#d5b1#6e31111
c1 
        pop bc
#d5b2#6e32214/9
10 f0 
        djnz Ld5a4_draw_radar_loop_y
#d5b4#6e34111
c1 
    pop bc
#d5b5#6e35
    ; Set the attributes:
#d5b5#6e35311
21 c6 5a 
    ld hl, L5800_VIDEOMEM_ATTRIBUTES + #02c6  ; pointer to the attributes of the radar
#d5b8#6e38318
cd bd d5 
    call Ld5bd_set_radar_attributes_one_row
#d5bb#6e3b28
2e e6 
    ld l, #e6  ; second line
#d5bd#6e3d
Ld5bd_set_radar_attributes_one_row:
#d5bd#6e3d28
06 10 
    ld b, 16
#d5bf#6e3f
Ld5bf_radar_attributes_loop_x:
#d5bf#6e3f18
71 
    ld (hl), c
#d5c0#6e4017
23 
    inc hl
#d5c1#6e41214/9
10 fc 
    djnz Ld5bf_radar_attributes_loop_x
#d5c3#6e43111
c9 
    ret
#d5c4#6e44
#d5c4#6e44
#d5c4#6e44
; --------------------------------
#d5c4#6e44
; Produces in-game sound based on the value of "a".
#d5c4#6e44
; There are two types of possible sounds:
#d5c4#6e44
; - if a is positive, it'll produce some sound based on reading values from ROM (starting at 0 
#d5c4#6e44
;   address).
#d5c4#6e44
; - if a is negative, it produces sound based on the random number generator.
#d5c4#6e44
; Input:
#d5c4#6e44
; - a: type of sound to produce
#d5c4#6e44
Ld5c4_produce_in_game_sound:
#d5c4#6e44311
fa ec d5 
    jp m, Ld5ec_random_noise
#d5c7#6e47
    ; if "a" is positive, produce a different type of sound: 
#d5c7#6e4715
47 
    ld b, a
#d5c8#6e4815
3c 
    inc a
#d5c9#6e4915
3c 
    inc a
#d5ca#6e4a311
21 f4 01 
    ld hl, 500
#d5cd#6e4d15
5f 
    ld e, a
#d5ce#6e4e28
16 00 
    ld d, 0
#d5d0#6e5028
0e 00 
    ld c, 0
#d5d2#6e5215
af 
    xor a
#d5d3#6e53
Ld5d3:
#d5d3#6e5315
0c 
    inc c
#d5d4#6e54217
ed 52 
    sbc hl, de
#d5d6#6e56213/8
30 fb 
    jr nc, Ld5d3
#d5d8#6e58311
21 00 00 
    ld hl, 0  ; read values from the ROM at this address (which will be noise, but a different type 
#d5db#6e5b
              ; of noise).
#d5db#6e5b
Ld5db:
#d5db#6e5b112
c5 
    push bc
#d5dc#6e5c18
7e 
        ld a, (hl)
#d5dd#6e5d17
23 
        inc hl
#d5de#6e5e28
e6 10 
        and 16
#d5e0#6e60212
d3 fe 
        out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#d5e2#6e62
Ld5e2:
#d5e2#6e62214/9
10 fe 
        djnz Ld5e2
#d5e4#6e64111
c1 
    pop bc
#d5e5#6e6515
0d 
    dec c
#d5e6#6e66213/8
20 f3 
    jr nz, Ld5db
#d5e8#6e6815
af 
    xor a
#d5e9#6e69212
d3 fe 
    out (ULA_PORT), a  ; change MIC/EAR state (sound off)
#d5eb#6e6b111
c9 
    ret
#d5ec#6e6c
#d5ec#6e6c
#d5ec#6e6c
; --------------------------------
#d5ec#6e6c
; Produce random noise for a short period of time:
#d5ec#6e6c
Ld5ec_random_noise:
#d5ec#6e6c28
06 1e 
    ld b, 30
#d5ee#6e6e
Ld5ee_loop:
#d5ee#6e6e318
cd 58 d3 
    call Ld358_random
#d5f1#6e7128
e6 10 
    and 16
#d5f3#6e73212
d3 fe 
    out (ULA_PORT), a  ; change MIC/EAR state (to produce sound)
#d5f5#6e75214/9
10 f7 
    djnz Ld5ee_loop
#d5f7#6e77111
c9 
    ret
#d5f8#6e78
#d5f8#6e78
#d5f8#6e78
; --------------------------------
#d5f8#6e78
; Updates the two radar buffers (Ld800_radar_view1, Ld800_radar_view2) with all the 
#d5f8#6e78
; buildings and robots in the map.
#d5f8#6e78
Ld5f8_update_radar_buffers:
#d5f8#6e78311
21 00 d8 
    ld hl, Ld800_radar_view1
#d5fb#6e7b422
ed 5b 1c fd 
    ld de, (Lfd1c_radar_scroll_x)
#d5ff#6e7f15
7a 
    ld a, d
#d600#6e8028
c6 dd 
    add a, #dd
#d602#6e8215
57 
    ld d, a  ; de now has the pointer to the map buffer (Ldd00_map) corresponding to the radar view
#d603#6e83
    ; Updates the contents of the radar:
#d603#6e83311
01 10 10 
    ld bc, #1010  ; 16, 16
#d606#6e86
Ld606_radar_update_loop_y:
#d606#6e86112
c5 
    push bc
#d607#6e87112
d5 
    push de
#d608#6e88
Ld608_radar_update_loop_x:
#d608#6e88112
c5 
        push bc
#d609#6e8928
06 08 
            ld b, 8
#d60b#6e8b
Ld60b_radar_update_loop_byte:
#d60b#6e8b18
1a 
            ld a, (de)
#d60c#6e8c17
13 
            inc de
#d60d#6e8d28
e6 1f 
            and #1f
#d60f#6e8f28
fe 0f 
            cp #0f
#d611#6e9115
3f 
            ccf  ; carry = 1 if the map has an element > 15 (building)
#d612#6e92217
cb 16 
            rl (hl)  ; this inserts a 0/1 from the left of the byte. Since we iterate this loop 8 
#d614#6e94
                     ; times, it will eventually replace the old value of this byte in the radar 
#d614#6e94
                     ; buffer.
#d614#6e94214/9
10 f5 
            djnz Ld60b_radar_update_loop_byte
#d616#6e9617
23 
            inc hl
#d617#6e97111
c1 
        pop bc
#d618#6e98214/9
10 ee 
        djnz Ld608_radar_update_loop_x
#d61a#6e9a111
d1 
    pop de
#d61b#6e9b111
c1 
    pop bc
#d61c#6e9c
    ; increment "y":
#d61c#6e9c15
14 
    inc d
#d61d#6e9d15
14 
    inc d
#d61e#6e9e15
0d 
    dec c
#d61f#6e9f213/8
20 e5 
    jr nz, Ld606_radar_update_loop_y
#d621#6ea1
#d621#6ea1
    ; Sync both radar views:    
#d621#6ea1311
21 00 d8 
    ld hl, Ld800_radar_view1  ; player and player robots will be drawn to view 1
#d624#6ea4311
11 00 d9 
    ld de, Ld900_radar_view2  ; enemy robots are drawn to view 2
#d627#6ea7311
01 00 01 
    ld bc, 256
#d62a#6eaa223/18
ed b0 
    ldir
#d62c#6eac
#d62c#6eac
    ; Update robots in the radar view:
#d62c#6eac416
fd 21 00 da 
    ld iy, Lda00_player1_robots
#d630#6eb028
06 30 
    ld b, MAX_ROBOTS_PER_PLAYER * 2
#d632#6eb2
Ld632:
#d632#6eb2112
c5 
    push bc
#d633#6eb3321
fd 7e 01 
        ld a, (iy + 1)
#d636#6eb615
b7 
        or a
#d637#6eb7213/8
28 18 
        jr z, Ld651_next_robot  ; If there is no robot in this struct, skip
#d639#6eb9321
fd 6e 02 
        ld l, (iy + ROBOT_STRUCT_X)
#d63c#6ebc321
fd 66 03 
        ld h, (iy + ROBOT_STRUCT_X + 1)
#d63f#6ebf321
fd 4e 04 
        ld c, (iy + ROBOT_STRUCT_Y)
#d642#6ec2321
fd 7e 0a 
        ld a, (iy + ROBOT_STRUCT_CONTROL)
#d645#6ec515
07 
        rlca
#d646#6ec628
e6 01 
        and 1
#d648#6ec815
47 
        ld b, a  ; b = 0 if player robot, and b = 1 if enemy robot.
#d649#6ec9321
fd 7e 0a 
        ld a, (iy + ROBOT_STRUCT_CONTROL)
#d64c#6ecc28
fe 02 
        cp 2
#d64e#6ece318/11
c4 5a d6 
        call nz, Ld65a_flip_2x2_radar_area
#d651#6ed1
Ld651_next_robot:
#d651#6ed1311
11 10 00 
        ld de, ROBOT_STRUCT_SIZE
#d654#6ed4217
fd 19 
        add iy, de
#d656#6ed6111
c1 
    pop bc
#d657#6ed7214/9
10 d9 
    djnz Ld632
#d659#6ed9111
c9 
    ret
#d65a#6eda
#d65a#6eda
#d65a#6eda
; --------------------------------
#d65a#6eda
; Flicker a 2x2 area in the radar view. This function will get the pointer
#d65a#6eda
; in the radar view corresponding to the given coordinates, and then flip
#d65a#6eda
; the bits in a 2x2 area around it.
#d65a#6eda
; Input:
#d65a#6eda
; - hl: x coordinate
#d65a#6eda
; - b: whether to use Ld800_radar_view1 (b == 0), or Ld900_radar_view2 (b == 1)
#d65a#6eda
; - c: y coordinate
#d65a#6eda
Ld65a_flip_2x2_radar_area:
#d65a#6eda318
cd 7d d6 
    call Ld67d_get_radar_view_pointer
#d65d#6edd15
4f 
    ld c, a
#d65e#6ede
    ; Flip the first row of 2 bits:
#d65e#6ede112
e5 
    push hl
#d65f#6edf18
7e 
        ld a, (hl)
#d660#6ee015
a9 
        xor c
#d661#6ee118
77 
        ld (hl), a
#d662#6ee2210
cb 09 
        rrc c
#d664#6ee4213/8
30 01 
        jr nc, Ld667_not_crossing_to_the_next_byte
#d666#6ee617
23 
        inc hl
#d667#6ee7
Ld667_not_crossing_to_the_next_byte:
#d667#6ee718
7e 
        ld a, (hl)
#d668#6ee815
a9 
        xor c
#d669#6ee918
77 
        ld (hl), a
#d66a#6eea111
e1 
    pop hl
#d66b#6eeb
    ; Flip the next row of 2 bits:
#d66b#6eeb15
7d 
    ld a, l
#d66c#6eec28
d6 10 
    sub 16
#d66e#6eee15
6f 
    ld l, a
#d66f#6eef210
cb 01 
    rlc c
#d671#6ef118
7e 
    ld a, (hl)
#d672#6ef215
a9 
    xor c
#d673#6ef318
77 
    ld (hl), a
#d674#6ef4210
cb 09 
    rrc c
#d676#6ef6213/8
30 01 
    jr nc, Ld679_not_crossing_to_the_next_byte
#d678#6ef817
23 
    inc hl
#d679#6ef9
Ld679_not_crossing_to_the_next_byte:
#d679#6ef918
7e 
    ld a, (hl)
#d67a#6efa15
a9 
    xor c
#d67b#6efb18
77 
    ld (hl), a
#d67c#6efc111
c9 
    ret
#d67d#6efd
#d67d#6efd
#d67d#6efd
; --------------------------------
#d67d#6efd
; Get radar view pointer
#d67d#6efd
; input:
#d67d#6efd
; - hl: x coordinate
#d67d#6efd
; - b: whether to use Ld800_radar_view1 (b == 0), or Ld900_radar_view2 (b == 1)
#d67d#6efd
; - c: y coordinate
#d67d#6efd
; output:
#d67d#6efd
; - a: bit (one-hot representation) that corresponds to the given coordinates.
#d67d#6efd
; - hl: byte in the radar view that corresponds to the given coordinates.
#d67d#6efd
Ld67d_get_radar_view_pointer:
#d67d#6efd422
ed 5b 1c fd 
    ld de, (Lfd1c_radar_scroll_x)
#d681#6f0115
af 
    xor a
#d682#6f02217
ed 52 
    sbc hl, de
#d684#6f0415
7c 
    ld a, h
#d685#6f0515
b7 
    or a
#d686#6f06
    ; return if when we subtracted "de" from the x coordinate, we don't get a number between 0 and 
#d686#6f06
    ; 127:
#d686#6f06213/8
20 1e 
    jr nz, Ld6a6_exit
#d688#6f0815
7d 
    ld a, l
#d689#6f0928
fe 7f 
    cp 127
#d68b#6f0b213/8
30 19 
    jr nc, Ld6a6_exit
#d68d#6f0d
#d68d#6f0d
    ; here we know that hl - de is on [0,127]
#d68d#6f0d28
3e d8 
    ld a, Ld800_radar_view1 / 256
#d68f#6f0f15
80 
    add a, b
#d690#6f1015
67 
    ld h, a  ; h = b + #d8
#d691#6f1115
7d 
    ld a, l
#d692#6f1228
e6 07 
    and #07
#d694#6f1415
3c 
    inc a
#d695#6f1515
47 
    ld b, a  ; b = ((hl - de)%8) + 1
#d696#6f1615
7d 
    ld a, l
#d697#6f1715
07 
    rlca  ; a = (hl - de)*2  ->  xxxxxxx0
#d698#6f1828
e6 f0 
    and #f0  ; We keep only the upper 4 bits  ->  xxxx0000
#d69a#6f1a15
b1 
    or c  ; xxxxyyyy
#d69b#6f1b15
07 
    rlca
#d69c#6f1c15
07 
    rlca
#d69d#6f1d15
07 
    rlca
#d69e#6f1e15
07 
    rlca
#d69f#6f1f15
6f 
    ld l, a  ; a = yyyyxxxx. Where yyyy is the y coordinate (in c), and xxxx are bits 3-6 of hl-de
#d6a0#6f2015
af 
    xor a
#d6a1#6f2115
37 
    scf
#d6a2#6f22
Ld6a2_shift_loop:
#d6a2#6f2215
1f 
    rra
#d6a3#6f23214/9
10 fd 
    djnz Ld6a2_shift_loop
#d6a5#6f25
    ; here "a" is a one-hot representation of (hl - de)%8
#d6a5#6f25111
c9 
    ret
#d6a6#6f26
Ld6a6_exit:
#d6a6#6f26111
e1 
    pop hl  ; simulate a ret (so, we return from Ld65a_flip_2x2_radar_area, which is the only 
#d6a7#6f27
            ; caller of this function)
#d6a7#6f27111
c9 
    ret
#d6a8#6f28
#d6a8#6f28
#d6a8#6f28
; --------------------------------
#d6a8#6f28
Ld6a8_diagonal_pattern1:  ; diagonal line (top-left painted, bottom-left empty)
#d6a8#6f2816
    db #ff, #ff, #ff, #fc, #ff, #f0, #ff, #c0, #ff, #00, #fc, #00, #f0, #00, #c0, #00
#d6b8#6f38
Ld6b8_diagonal_pattern2:  ; diagonal line (top-left empty, bottom-left painted)
#d6b8#6f3816
    db #00, #03, #00, #0f, #00, #3f, #00, #ff, #03, #ff, #0f, #ff, #3f, #ff, #ff, #ff
#d6c8#6f48
#d6c8#6f48
#d6c8#6f48
; --------------------------------
#d6c8#6f48
Ld6c8_piece_direction_graphic_indices:
#d6c8#6f48
    ; Index of the graphic to draw for each piece in each of the 4 cardinal directions.
#d6c8#6f48
    ; For example, notice how "nuclear" has the same graphic regardless of the direction.
#d6c8#6f48
    ; To find the specific graphic in the "Ld740_isometric_graphic_pointers" table below,
#d6c8#6f48
    ; multiply the index by 2 (as each graphic is stored twice, one with a precalculated
#d6c8#6f48
    ; offset of 4 pixels).
#d6c8#6f484
    db 2, 2, 3, 3  ; bipod
#d6cc#6f4c4
    db 0, 0, 1, 1  ; tracks
#d6d0#6f504
    db 4, 4, 4, 4  ; antigrav
#d6d4#6f544
    db 5, 6, 7, 8  ; cannon
#d6d8#6f584
    db 9, 9, 10, 10  ; missiles
#d6dc#6f5c4
    db 11, 12, 13, 14  ; phasers
#d6e0#6f604
    db 15, 15, 15, 15  ; nuclear
#d6e4#6f644
    db 16, 17, 18, 19  ; electronics
#d6e8#6f68
#d6e8#6f68
#d6e8#6f68
; --------------------------------
#d6e8#6f68
Ld6e8_additional_isometric_graphic_pointers:  ; 44 pointers
#d6e8#6f682
    dw L8e3a_iso_additional_graphic_0
#d6ea#6f6a2
    dw L8f2c_iso_additional_graphic_1
#d6ec#6f6c2
    dw L901e_iso_additional_graphic_2
#d6ee#6f6e2
    dw L90b0_iso_additional_graphic_3
#d6f0#6f702
    dw L9172_iso_additional_graphic_4
#d6f2#6f722
    dw L9172_iso_additional_graphic_4
#d6f4#6f742
    dw L91f2_iso_additional_graphic_5
#d6f6#6f762
    dw L91f2_iso_additional_graphic_5
#d6f8#6f782
    dw L9278_iso_additional_graphic_6
#d6fa#6f7a2
    dw L9278_iso_additional_graphic_6
#d6fc#6f7c2
    dw L92f8_iso_additional_graphic_7
#d6fe#6f7e2
    dw L92f8_iso_additional_graphic_7
#d700#6f802
    dw L9d9c_iso_additional_graphic_22
#d702#6f822
    dw L9e34_iso_additional_graphic_23
#d704#6f842
    dw L9ef6_iso_additional_graphic_24
#d706#6f862
    dw L9f8e_iso_additional_graphic_25
#d708#6f882
    dw L9372_iso_additional_graphic_8
#d70a#6f8a2
    dw L9372_iso_additional_graphic_8
#d70c#6f8c2
    dw L940a_iso_additional_graphic_9
#d70e#6f8e2
    dw L940a_iso_additional_graphic_9
#d710#6f902
    dw L94a8_iso_additional_graphic_10
#d712#6f922
    dw L94a8_iso_additional_graphic_10
#d714#6f942
    dw L9534_iso_additional_graphic_11
#d716#6f962
    dw L9534_iso_additional_graphic_11
#d718#6f982
    dw L95c6_iso_additional_graphic_12
#d71a#6f9a2
    dw L9640_iso_additional_graphic_13
#d71c#6f9c2
    dw L96ea_iso_additional_graphic_14
#d71e#6f9e2
    dw L9776_iso_additional_graphic_15
#d720#6fa02
    dw L9820_iso_additional_graphic_16
#d722#6fa22
    dw L98ac_iso_additional_graphic_17
#d724#6fa42
    dw L9914_iso_additional_graphic_18
#d726#6fa62
    dw L9a16_iso_additional_graphic_19
#d728#6fa82
    dw L9b18_iso_additional_graphic_20
#d72a#6faa2
    dw L9c5a_iso_additional_graphic_21
#d72c#6fac2
    dw La0e2_iso_additional_graphic_27
#d72e#6fae2
    dw La1e4_iso_additional_graphic_28
#d730#6fb02
    dw La2e6_iso_additional_graphic_29
#d732#6fb22
    dw La428_iso_additional_graphic_30
#d734#6fb42
    dw L8e3a_iso_additional_graphic_0
#d736#6fb62
    dw L8e3a_iso_additional_graphic_0
#d738#6fb82
    dw L8e3a_iso_additional_graphic_0
#d73a#6fba2
    dw L8e3a_iso_additional_graphic_0
#d73c#6fbc2
    dw La050_iso_additional_graphic_26
#d73e#6fbe2
    dw La050_iso_additional_graphic_26
#d740#6fc0
#d740#6fc0
Ld740_isometric_graphic_pointers:  ; 58 pointers
#d740#6fc02
    dw L6980_iso_graphic_0  ; tracks
#d742#6fc22
    dw L6a24_iso_graphic_1
#d744#6fc42
    dw L6afe_iso_graphic_2
#d746#6fc62
    dw L6ba8_iso_graphic_3
#d748#6fc82
    dw L6c8a_iso_graphic_4  ; bipod
#d74a#6fca2
    dw L6d40_iso_graphic_5
#d74c#6fcc2
    dw L6e32_iso_graphic_6
#d74e#6fce2
    dw L6ee2_iso_graphic_7
#d750#6fd02
    dw L6fcc_iso_graphic_8  ; antigrav
#d752#6fd22
    dw L7058_iso_graphic_9
#d754#6fd42
    dw L7112_iso_graphic_10  ; cannon
#d756#6fd62
    dw L71bc_iso_graphic_11
#d758#6fd82
    dw L729e_iso_graphic_12
#d75a#6fda2
    dw L7354_iso_graphic_13
#d75c#6fdc2
    dw L7446_iso_graphic_14
#d75e#6fde2
    dw L74fc_iso_graphic_15
#d760#6fe02
    dw L75ee_iso_graphic_16
#d762#6fe22
    dw L7686_iso_graphic_17
#d764#6fe42
    dw L7750_iso_graphic_18  ; missiles
#d766#6fe62
    dw L77f4_iso_graphic_19
#d768#6fe82
    dw L78ce_iso_graphic_20
#d76a#6fea2
    dw L7978_iso_graphic_21
#d76c#6fec2
    dw L7a5a_iso_graphic_22  ; phaser
#d76e#6fee2
    dw L7b04_iso_graphic_23
#d770#6ff02
    dw L7be6_iso_graphic_24
#d772#6ff22
    dw L7c96_iso_graphic_25
#d774#6ff42
    dw L7d80_iso_graphic_26
#d776#6ff62
    dw L7e30_iso_graphic_27
#d778#6ff82
    dw L7f1a_iso_graphic_28
#d77a#6ffa2
    dw L7fb8_iso_graphic_29
#d77c#6ffc2
    dw L808a_iso_graphic_30  ; nuclear
#d77e#6ffe2
    dw L813a_iso_graphic_31
#d780#70002
    dw L8224_iso_graphic_32
#d782#70022
    dw L82b6_iso_graphic_33
#d784#70042
    dw L8348_iso_graphic_34
#d786#70062
    dw L83da_iso_graphic_35
#d788#70082
    dw L846c_iso_graphic_36
#d78a#700a2
    dw L84fe_iso_graphic_37
#d78c#700c2
    dw L8590_iso_graphic_38
#d78e#700e2
    dw L8622_iso_graphic_39
#d790#70102
    dw L86b4_iso_graphic_40
#d792#70122
    dw L86f8_iso_graphic_41
#d794#70142
    dw L8752_iso_graphic_42
#d796#70162
    dw L8796_iso_graphic_43
#d798#70182
    dw L87f0_iso_graphic_44
#d79a#701a2
    dw L8858_iso_graphic_45
#d79c#701c2
    dw L88e2_iso_graphic_46
#d79e#701e2
    dw L8924_iso_graphic_47
#d7a0#70202
    dw L8966_iso_graphic_48
#d7a2#70222
    dw L89b6_iso_graphic_49
#d7a4#70242
    dw L8a06_iso_graphic_50
#d7a6#70262
    dw L8a8c_iso_graphic_51
#d7a8#70282
    dw L8b3e_iso_graphic_52
#d7aa#702a2
    dw L8bc4_iso_graphic_53
#d7ac#702c2
    dw L8c76_iso_graphic_54
#d7ae#702e2
    dw L8cde_iso_graphic_55
#d7b0#70302
    dw L8d46_iso_graphic_56
#d7b2#70322
    dw L8dc0_iso_graphic_57
#d7b4#7034
#d7b4#7034
#d7b4#7034
; --------------------------------
#d7b4#7034
Ld7b4_piece_heights:
#d7b4#70341
    db 11  ; bipod
#d7b5#70351
    db 7  ; tracks
#d7b6#70361
    db 8  ; antigrav
#d7b7#70371
    db 6  ; cannon
#d7b8#70381
    db 6  ; missiles
#d7b9#70391
    db 7  ; phasers
#d7ba#703a1
    db 7  ; nuclear
#d7bb#703b1
    db 7  ; electronics
#d7bc#703c
#d7bc#703c
Ld7bc_map_piece_heights:  ; 23 elements
#d7bc#703c16
    db #00, #00, #02, #02, #02, #02, #03, #03, #06, #06, #06, #06, #00, #00, #00, #07
#d7cc#704c7
    db #0f, #07, #0f, #00, #00, #63, #00
#d7d3#7053
#d7d3#7053
#d7d3#7053
; --------------------------------
#d7d3#7053
; RAM Variables:
#d7d3#7053
Ld7d3_bullets: equ #d7d3  ; 5 * 9 bytes
#d7d3#7053
Ld800_radar_view1: equ #d800  ; 256 bytes. Player and player robots are drawn here
#d7d3#7053
Ld900_radar_view2: equ #d900  ; 256 bytes. Enemy robots are drawn here
#d7d3#7053
#d7d3#7053
#d7d3#7053
; When saving a game, RAM is stored starting from here:
#d7d3#7053
Ld92b_save_game_start: equ #d92b  ; 213 bytes, buffer where a few things are copied before saving a 
#d7d3#7053
                                  ; game: bullet state (45 bytes), and 168 bytes from 
#d7d3#7053
                                  ; Lff01_building_decorations.
#d7d3#7053
Lda00_player1_robots: equ #da00  ; 384 bytes  (24 robots * 16 bytes per robot)
#d7d3#7053
Ldb80_player2_robots: equ #db80  ; 384 bytes  (24 robots * 16 bytes per robot)
#d7d3#7053
#d7d3#7053
; Each byte of the map is organized as:
#d7d3#7053
; - dcbaaaaa:
#d7d3#7053
;     - aaaaa: element type
#d7d3#7053
;     - b: as elements use a 2x2 position, only the bottom-left corner has this as 0
#d7d3#7053
;     - c: indicates a robot/factory/warbase is here
#d7d3#7053
;     - d: indicates player is here
#d7d3#7053
Ldd00_map: equ #dd00  ; map: 512*16 = 8192 bytes
#d7d3#7053
#d7d3#7053
Lfd00_random_seed: equ #fd00  ; 4 bytes
#d7d3#7053
Lfd04_script_video_pattern_ptr: equ #fd04  ; 2 bytes
#d7d3#7053
Lfd06_scroll_ptr: equ #fd06  ; 2 bytes
#d7d3#7053
Lfd08_stack_ptr_buffer: equ #fd08  ; 2 bytes
#d7d3#7053
Lfd0a_scroll_x: equ #fd0a  ; 2 bytes
#d7d3#7053
Lfd0c_keyboard_state: equ #fd0c  ; 1 byte
#d7d3#7053
Lfd0d_player_y: equ #fd0d  ; 1 byte. Narrow axis of the map.
#d7d3#7053
Lfd0e_player_x: equ #fd0e  ; 2 bytes. Long axis of the map
#d7d3#7053
Lfd10_player_altitude: equ #fd10  ; 1 byte.
#d7d3#7053
Lfd11_player_iso_coordinates_if_deferred: equ #fd11  ; 2 bytes. If rendering of the player is 
#d7d3#7053
                                                     ; sprite is deferred due to an overlapping 
#d7d3#7053
                                                     ; sprite, this will contain the original 
#d7d3#7053
                                                     ; isometric coordinates of the player sprite.
#d7d3#7053
Lfd13_script_attribute: equ #fd13  ; 1 byte
#d7d3#7053
Lfd14_script_video_attribute_ptr: equ #fd14  ; 2 bytes
#d7d3#7053
Lfd16_script_scale_y: equ #fd16  ; 1 byte
#d7d3#7053
Lfd17_script_scale_x: equ #fd17  ; 1 byte
#d7d3#7053
; 2 unused bytes
#d7d3#7053
Lfd1a_interrupt_parity: equ #fd1a  ; 1 byte. Used to determine if we are in an even or odd 
#d7d3#7053
                                   ; interrupt call.
#d7d3#7053
Lfd1b_radar_scroll_x_tile: equ #fd1b  ; 1 byte. Same as the variable below, but at tile resolution.
#d7d3#7053
Lfd1c_radar_scroll_x: equ #fd1c  ; 2 bytes
#d7d3#7053
Lfd1e_player_visible_in_radar: equ #fd1e  ; 1 byte. The least-significant bit of this variable 
#d7d3#7053
                                          ; represents whether to draw the player in the radar or 
#d7d3#7053
                                          ; not. It's used to make the player blink.
#d7d3#7053
Lfd1f_cursor_position: equ #fd1f  ; 2 bytes: x, y
#d7d3#7053
Lfd21_construction_selected_pieces: equ #fd21  ; 1 byte
#d7d3#7053
Lfd22_player1_resource_counts: equ #fd22  ; 7 bytes
#d7d3#7053
Lfd29_resource_counts_buffer: equ #fd29  ; 7 bytes. Used, for example, in the robot construction 
#d7d3#7053
                                         ; screen, to keep track of resources left after the 
#d7d3#7053
                                         ; selected pieces are discounted from the resources.
#d7d3#7053
Lfd30_player_elevate_timer: equ #fd30  ; 1 byte. If this is > 0, player ship elevates 
#d7d3#7053
                                       ; automatically, until this reaches 0 (used when exiting a 
#d7d3#7053
                                       ; robot / warbase, for example).
#d7d3#7053
Lfd31_script_coordinate: equ #fd31  ; 2 bytes
#d7d3#7053
Lfd33_title_color: equ #fd33  ; 1 byte. Used only in the title screen to do title color rotation.
#d7d3#7053
Lfd34_n_interrupts_this_came_cycle: equ #fd34  ; 1 byte
#d7d3#7053
Lfd35_minutes: equ #fd35  ; 1 byte
#d7d3#7053
Lfd36_hours: equ #fd36  ; 1 byte
#d7d3#7053
Lfd37_days: equ #fd37  ; 2 bytes
#d7d3#7053
Lfd39_current_in_game_right_hud: equ #fd39  ; 1 byte. Stores which is the info/menu to display in 
#d7d3#7053
                                            ; the right hud.
#d7d3#7053
Lfd3a_player1_base_factory_counts: equ #fd3a  ; 7 bytes
#d7d3#7053
Lfd41_player1_robot_count: equ #fd41  ; 1 byte
#d7d3#7053
Lfd42_player2_base_factory_counts: equ #fd42  ; 7 bytes
#d7d3#7053
Lfd49_player2_robot_count: equ #fd49  ; 1 byte
#d7d3#7053
Lfd4a_player2_resource_counts: equ #fd4a  ; 7 bytes
#d7d3#7053
Lfd51_current_robot_player_or_enemy: equ #fd51  ; 1 byte. Used to indicate if the robot we are 
#d7d3#7053
                                                ; working with is controlled by the player or the 
#d7d3#7053
                                                ; enemy AI. (0: player, 1: enemy AI).
#d7d3#7053
Lfd52_update_radar_buffer_signal: equ #fd52  ; 1 byte. If this is set to 1, the radar buffer will 
#d7d3#7053
                                             ; be updated this cycle.
#d7d3#7053
Lfd53_produce_in_game_sound: equ #fd53  ; 1 byte. When != 0, it will make the game interrupt 
#d7d3#7053
                                        ; produce some sound, incrementing once per cycle until 
#d7d3#7053
                                        ; reaching 128 or 0, at which point the sound it will stop.
#d7d3#7053
Lfd54_music_channel1_ret_address: equ #fd54  ; 2 bytes
#d7d3#7053
Lfd56_music_channel2_ret_address: equ #fd56  ; 2 bytes
#d7d3#7053
; 24 unused bytes
#d7d3#7053
Lfd70_warbases: equ #fd70
#d7d3#7053
Lfd84_factories: equ Lfd70_warbases + N_WARBASES * BUILDING_STRUCT_SIZE
#d7d3#7053
Lfdfc_save_game_end: equ #fdfc  ; When saving a game, RAM is stored up to here.
#d7d3#7053
#d7d3#7053
#d7d3#7053
Lfdfd_interrupt_jp: equ #fdfd  ; 1 byte
#d7d3#7053
Lfdfe_interrupt_pointer: equ #fdfe  ; 2 bytes
#d7d3#7053
Lfe00_interrupt_vector_table: equ #fe00  ; 257 bytes
#d7d3#7053
Lff01_building_decorations: equ #ff01  ; 56 structs of 3 bytes each: map ptr (2 bytes), type (1 
#d7d3#7053
                                       ; byte)
#d7d3#7053
+ +

Source Code file: netherearth-annotated-data.asm
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddressPosition in BinarySizeTimingAssembledCode
#6780#0000
L6780_graphic_patterns:
#6780#0000
    ; Each block of 8 bytes correspods to a character. So, this includes
#6780#0000
    ; a definition of the font being used, the first character is ' ':
#6780#0000
    ; these tags inside comments are used to visualize the gfx using MDL with the "-mdl-asm+:html" flag.
#6780#00008
    db #00, #00, #00, #00, #00, #00, #00, #00  ; MDL bitmap visualization
#6788#00088
    db #00, #18, #18, #18, #18, #00, #18, #00  ; MDL bitmap visualization
#6790#00108
    db #00, #36, #6c, #00, #00, #00, #00, #00  ; MDL bitmap visualization
#6798#00188
    db #00, #24, #7e, #24, #24, #7e, #24, #00  ; MDL bitmap visualization
#67a0#00208
    db #18, #3e, #78, #3c, #1e, #1e, #7c, #18  ; MDL bitmap visualization
#67a8#00288
    db #00, #00, #66, #4c, #18, #32, #66, #00  ; MDL bitmap visualization
#67b0#00308
    db #38, #44, #4c, #38, #6e, #46, #3b, #00  ; MDL bitmap visualization
#67b8#00388
    db #00, #18, #30, #00, #00, #00, #00, #00  ; MDL bitmap visualization
#67c0#00408
    db #04, #0c, #18, #18, #18, #18, #0c, #04  ; MDL bitmap visualization
#67c8#00488
    db #20, #30, #18, #18, #18, #18, #30, #20  ; MDL bitmap visualization
#67d0#00508
    db #00, #00, #14, #08, #3e, #08, #14, #00  ; MDL bitmap visualization
#67d8#00588
    db #00, #00, #08, #08, #3e, #08, #08, #00  ; MDL bitmap visualization
#67e0#00608
    db #00, #00, #00, #00, #0c, #0c, #0c, #08  ; MDL bitmap visualization
#67e8#00688
    db #00, #00, #00, #00, #3e, #00, #00, #00  ; MDL bitmap visualization
#67f0#00708
    db #00, #00, #00, #00, #00, #18, #18, #00  ; MDL bitmap visualization
#67f8#00788
    db #00, #00, #06, #0c, #18, #30, #60, #00  ; MDL bitmap visualization
#6800#00808
    db #36, #77, #67, #6b, #73, #77, #36, #00  ; MDL bitmap visualization
#6808#00888
    db #0c, #3c, #1c, #1c, #1c, #1c, #1c, #00  ; MDL bitmap visualization
#6810#00908
    db #3c, #76, #36, #04, #08, #7e, #7e, #00  ; MDL bitmap visualization
#6818#00988
    db #34, #76, #06, #04, #26, #76, #34, #00  ; MDL bitmap visualization
#6820#00a08
    db #17, #17, #37, #77, #77, #07, #07, #00  ; MDL bitmap visualization
#6828#00a88
    db #7f, #70, #66, #07, #37, #77, #36, #00  ; MDL bitmap visualization
#6830#00b08
    db #16, #36, #70, #74, #76, #76, #34, #00  ; MDL bitmap visualization
#6838#00b88
    db #7e, #7e, #02, #0c, #1c, #38, #78, #00  ; MDL bitmap visualization
#6840#00c08
    db #36, #77, #77, #36, #77, #77, #36, #00  ; MDL bitmap visualization
#6848#00c88
    db #36, #77, #77, #37, #07, #76, #34, #00  ; MDL bitmap visualization
#6850#00d08
    db #00, #00, #18, #18, #00, #18, #18, #00  ; MDL bitmap visualization
#6858#00d88
    db #00, #00, #18, #18, #00, #18, #18, #10  ; MDL bitmap visualization
#6860#00e08
    db #00, #08, #18, #30, #60, #30, #18, #08  ; MDL bitmap visualization
#6868#00e88
    db #00, #00, #00, #3e, #00, #3e, #00, #00  ; MDL bitmap visualization
#6870#00f08
    db #00, #20, #30, #18, #0c, #18, #30, #20  ; MDL bitmap visualization
#6878#00f88
    db #2c, #6e, #6e, #0c, #00, #0c, #0c, #00  ; MDL bitmap visualization
#6880#01008
    db #3e, #59, #45, #5d, #55, #5d, #3e, #00  ; MDL bitmap visualization
#6888#01088
    db #3e, #77, #77, #77, #7f, #77, #77, #00  ; MDL bitmap visualization
#6890#01108
    db #76, #77, #76, #74, #76, #77, #76, #00  ; MDL bitmap visualization
#6898#01188
    db #17, #33, #71, #70, #71, #33, #17, #00  ; MDL bitmap visualization
#68a0#01208
    db #74, #76, #77, #77, #77, #76, #74, #00  ; MDL bitmap visualization
#68a8#01288
    db #77, #71, #70, #76, #70, #71, #77, #00  ; MDL bitmap visualization
#68b0#01308
    db #77, #71, #70, #76, #70, #70, #70, #00  ; MDL bitmap visualization
#68b8#01388
    db #17, #33, #71, #70, #77, #37, #16, #00  ; MDL bitmap visualization
#68c0#01408
    db #77, #77, #77, #7f, #77, #77, #77, #00  ; MDL bitmap visualization
#68c8#01488
    db #1c, #1c, #1c, #1c, #1c, #1c, #1c, #00  ; MDL bitmap visualization
#68d0#01508
    db #07, #07, #07, #07, #37, #77, #36, #00  ; MDL bitmap visualization
#68d8#01588
    db #77, #76, #74, #70, #74, #76, #77, #00  ; MDL bitmap visualization
#68e0#01608
    db #70, #70, #70, #70, #71, #73, #77, #00  ; MDL bitmap visualization
#68e8#01688
    db #63, #77, #7f, #7f, #77, #77, #77, #00  ; MDL bitmap visualization
#68f0#01708
    db #67, #77, #7f, #7f, #7f, #77, #73, #00  ; MDL bitmap visualization
#68f8#01788
    db #36, #77, #77, #77, #77, #77, #36, #00  ; MDL bitmap visualization
#6900#01808
    db #74, #76, #76, #76, #74, #70, #70, #00  ; MDL bitmap visualization
#6908#01888
    db #36, #77, #77, #77, #77, #7e, #37, #00  ; MDL bitmap visualization
#6910#01908
    db #74, #76, #76, #76, #74, #76, #77, #00  ; MDL bitmap visualization
#6918#01988
    db #37, #79, #7c, #3e, #1f, #4f, #76, #00  ; MDL bitmap visualization
#6920#01a08
    db #7f, #5d, #5d, #1c, #1c, #1c, #1c, #00  ; MDL bitmap visualization
#6928#01a88
    db #77, #77, #77, #77, #77, #77, #36, #00  ; MDL bitmap visualization
#6930#01b08
    db #63, #63, #63, #63, #77, #3e, #1c, #00  ; MDL bitmap visualization
#6938#01b88
    db #6b, #6b, #6b, #6b, #77, #7f, #36, #00  ; MDL bitmap visualization
#6940#01c08
    db #77, #77, #36, #14, #36, #77, #77, #00  ; MDL bitmap visualization
#6948#01c88
    db #77, #77, #36, #3e, #1c, #1c, #1c, #00  ; MDL bitmap visualization
#6950#01d08
    db #77, #4f, #1f, #3e, #7c, #79, #77, #00  ; MDL bitmap visualization
#6958#01d88
    db #00, #0e, #0c, #0c, #0c, #0c, #0e, #00  ; MDL bitmap visualization
#6960#01e08
    db #00, #00, #60, #30, #18, #0c, #06, #00  ; MDL bitmap visualization
#6968#01e88
    db #00, #70, #10, #10, #10, #10, #70, #00  ; MDL bitmap visualization
#6970#01f08
    db #00, #10, #38, #54, #10, #10, #10, #00  ; MDL bitmap visualization
#6978#01f88
    db #00, #00, #00, #00, #00, #00, #00, #ff  ; MDL bitmap visualization
#6980#0200
#6980#0200
L6980_isometric_graphics:
#6980#0200
    ; These are definitions of the different isometric pieces (bipod, cannon, etc.)
#6980#0200
    ; The first two bytes of each graphic are:
#6980#0200
    ; - height (in pixels)
#6980#0200
    ; - width (in bytes)
#6980#0200
    ; The rest of the data shuold be height*width*2 bytes, where each pair of bytes 
#6980#0200
    ; represents 8 pixels. The first is the "and mask", and the second the "or" mask, as
#6980#0200
    ; usual in ZX Spectrum graphics.
#6980#0200
    ; Graphics are stored upside down, since the game renders them starting at the bottom.
#6980#0200
L6980_iso_graphic_0:  ; MDL bitmap visualization
#6980#020016
    db #1b, #03, #ff, #00, #7f, #80, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #fc, #02
#6990#021016
    db #07, #f8, #ff, #00, #fc, #02, #01, #be, #ff, #00, #f8, #05, #00, #9f, #7f, #80
#69a0#022016
    db #f8, #04, #00, #fb, #1f, #e0, #f8, #06, #00, #79, #07, #f8, #f8, #04, #00, #9f
#69b0#023016
    db #01, #be, #f8, #04, #00, #a7, #00, #9f, #fc, #03, #00, #29, #00, #fb, #ef, #10
#69c0#024016
    db #00, #ca, #00, #79, #c3, #3c, #c0, #32, #00, #9f, #80, #5f, #f0, #0c, #00, #a7
#69d0#025016
    db #80, #57, #3c, #c3, #00, #29, #00, #b3, #0f, #f0, #01, #ca, #00, #9f, #03, #7c
#69e0#026016
    db #c1, #32, #00, #cf, #00, #3f, #f3, #0c, #00, #93, #00, #f7, #3f, #c0, #00, #94
#69f0#027016
    db #00, #f3, #1f, #e0, #80, #65, #00, #3f, #1f, #60, #e0, #19, #00, #4f, #1f, #20
#6a00#028016
    db #f8, #06, #00, #53, #1f, #e0, #fe, #01, #00, #94, #1f, #e0, #ff, #00, #80, #65
#6a10#029016
    db #1f, #20, #ff, #00, #e0, #19, #3f, #40, #ff, #00, #f8, #06, #3f, #40, #ff, #00
#6a20#02a04
    db #fe, #01, #7f, #80
#6a24#02a4
L6a24_iso_graphic_1:  ; MDL bitmap visualization
#6a24#02a416
    db #1b, #04, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00
#6a34#02b416
    db #ff, #00, #ff, #00, #c0, #2f, #7f, #80, #ff, #00, #ff, #00, #c0, #2b, #1f, #e0
#6a44#02c416
    db #ff, #00, #ff, #00, #80, #59, #07, #f8, #ff, #00, #ff, #00, #80, #4f, #01, #be
#6a54#02d416
    db #ff, #00, #ff, #00, #80, #67, #00, #9f, #7f, #80, #ff, #00, #80, #49, #00, #fb
#6a64#02e416
    db #1f, #e0, #ff, #00, #80, #4a, #00, #79, #0f, #f0, #ff, #00, #c0, #32, #00, #9f
#6a74#02f416
    db #0f, #b0, #fe, #01, #f0, #0c, #00, #a7, #0f, #90, #fc, #03, #3c, #c3, #00, #29
#6a84#030416
    db #0f, #f0, #f8, #05, #0f, #f0, #00, #ca, #0f, #70, #f8, #05, #03, #7c, #c0, #32
#6a94#031416
    db #0f, #90, #f0, #0b, #00, #3f, #f0, #0c, #1f, #a0, #f0, #09, #00, #f7, #3c, #c3
#6aa4#032416
    db #1f, #20, #f0, #0c, #00, #f3, #0f, #f0, #3f, #c0, #f0, #09, #00, #3f, #03, #7c
#6ab4#033416
    db #ff, #00, #f0, #09, #00, #4f, #01, #3e, #ff, #00, #f8, #06, #00, #53, #01, #f6
#6ac4#034416
    db #ff, #00, #fe, #01, #00, #94, #01, #f2, #ff, #00, #ff, #00, #80, #65, #01, #3e
#6ad4#035416
    db #ff, #00, #ff, #00, #e0, #19, #01, #4e, #ff, #00, #ff, #00, #f8, #06, #01, #52
#6ae4#036416
    db #ff, #00, #ff, #00, #fe, #01, #03, #94, #ff, #00, #ff, #00, #ff, #00, #83, #64
#6af4#037410
    db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00
#6afe#037e
L6afe_iso_graphic_2:  ; MDL bitmap visualization
#6afe#037e16
    db #1c, #03, #ff, #00, #3f, #c0, #ff, #00, #fe, #01, #0f, #b0, #ff, #00, #fe, #01
#6b0e#038e16
    db #03, #cc, #ff, #00, #fc, #02, #03, #b4, #ff, #00, #fc, #02, #03, #cc, #ff, #00
#6b1e#039e16
    db #f8, #07, #03, #34, #cf, #30, #f8, #07, #03, #8c, #83, #6c, #f0, #0a, #03, #64
#6b2e#03ae16
    db #80, #73, #f0, #0b, #07, #18, #00, #ad, #e0, #1c, #07, #c8, #00, #b3, #e0, #1e
#6b3e#03be16
    db #0e, #31, #00, #cd, #c0, #29, #0e, #91, #00, #e3, #c0, #2c, #1c, #62, #00, #99
#6b4e#03ce16
    db #80, #73, #1c, #22, #01, #c6, #80, #78, #38, #c7, #01, #32, #00, #a6, #38, #47
#6b5e#03de16
    db #03, #8c, #00, #b1, #70, #8a, #03, #64, #00, #cc, #70, #8b, #07, #18, #00, #e3
#6b6e#03ee16
    db #e0, #1c, #07, #c8, #00, #99, #e0, #1e, #0f, #30, #01, #c6, #c0, #29, #0f, #90
#6b7e#03fe16
    db #c1, #32, #c0, #2c, #1f, #60, #f3, #0c, #c0, #33, #1f, #20, #ff, #00, #c0, #38
#6b8e#040e16
    db #3f, #c0, #ff, #00, #c0, #26, #3f, #40, #ff, #00, #c0, #31, #7f, #80, #ff, #00
#6b9e#041e10
    db #f0, #0c, #7f, #80, #ff, #00, #fc, #03, #ff, #00
#6ba8#0428
L6ba8_iso_graphic_3:  ; MDL bitmap visualization
#6ba8#042816
    db #1c, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #e0, #1b, #ff, #00
#6bb8#043816
    db #ff, #00, #ff, #00, #e0, #1c, #3f, #c0, #ff, #00, #ff, #00, #c0, #2b, #3f, #40
#6bc8#044816
    db #ff, #00, #ff, #00, #c0, #2c, #3f, #c0, #ff, #00, #ff, #00, #80, #73, #3c, #43
#6bd8#045816
    db #ff, #00, #ff, #00, #80, #78, #38, #c6, #3f, #c0, #ff, #00, #00, #a6, #38, #47
#6be8#046816
    db #0f, #30, #ff, #00, #00, #b1, #70, #8a, #0f, #d0, #fe, #01, #00, #cc, #70, #8b
#6bf8#047816
    db #0f, #30, #fe, #01, #00, #e3, #e0, #1c, #0f, #d0, #fc, #02, #00, #99, #e0, #1e
#6c08#048816
    db #0f, #30, #fc, #02, #01, #c6, #c0, #29, #0f, #90, #f8, #07, #01, #32, #c0, #2c
#6c18#049816
    db #1f, #60, #f8, #07, #03, #8c, #80, #73, #1f, #20, #f0, #0a, #03, #64, #80, #78
#6c28#04a816
    db #3f, #c0, #f0, #0b, #07, #18, #00, #a6, #3f, #40, #f0, #0c, #07, #c8, #00, #b1
#6c38#04b816
    db #7f, #80, #f0, #0e, #0e, #31, #00, #cc, #7f, #80, #f0, #09, #0e, #91, #00, #e3
#6c48#04c816
    db #ff, #00, #f0, #0c, #1c, #62, #00, #99, #ff, #00, #fc, #03, #1c, #22, #01, #c6
#6c58#04d816
    db #ff, #00, #ff, #00, #3c, #c3, #01, #32, #ff, #00, #ff, #00, #fc, #03, #03, #8c
#6c68#04e816
    db #ff, #00, #ff, #00, #fc, #02, #03, #64, #ff, #00, #ff, #00, #fc, #03, #07, #18
#6c78#04f816
    db #ff, #00, #ff, #00, #ff, #00, #07, #c8, #ff, #00, #ff, #00, #ff, #00, #cf, #30
#6c88#05082
    db #ff, #00
#6c8a#050a
L6c8a_iso_graphic_4:  ; MDL bitmap visualization
#6c8a#050a16
    db #1e, #03, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fe, #01
#6c9a#051a16
    db #1f, #60, #ff, #00, #fc, #03, #07, #58, #ff, #00, #fc, #03, #01, #56, #ff, #00
#6caa#052a16
    db #f8, #07, #00, #d5, #7f, #80, #f8, #06, #00, #55, #1f, #60, #f8, #06, #00, #35
#6cba#053a16
    db #07, #58, #f8, #04, #00, #15, #03, #54, #e0, #1e, #00, #0d, #03, #54, #e0, #17
#6cca#054a16
    db #00, #1d, #03, #54, #c0, #35, #00, #98, #03, #fc, #c0, #35, #00, #78, #03, #84
#6cda#055a16
    db #80, #7d, #00, #78, #07, #88, #80, #65, #00, #78, #07, #88, #80, #63, #00, #7c
#6cea#056a16
    db #0f, #f0, #80, #41, #00, #73, #7f, #80, #80, #60, #00, #f0, #3f, #c0, #e0, #11
#6cfa#057a16
    db #00, #a1, #3f, #40, #f0, #09, #00, #b1, #3f, #c0, #f8, #07, #00, #8f, #3f, #40
#6d0a#058a16
    db #fc, #03, #00, #8a, #7f, #80, #fc, #03, #00, #88, #7f, #80, #fc, #03, #00, #cf
#6d1a#059a16
    db #ff, #00, #fc, #03, #07, #38, #ff, #00, #fc, #03, #07, #08, #ff, #00, #fc, #02
#6d2a#05aa16
    db #0f, #10, #ff, #00, #fc, #03, #0f, #10, #ff, #00, #ff, #00, #1f, #e0, #ff, #00
#6d3a#05ba6
    db #ff, #00, #df, #20, #ff, #00
#6d40#05c0
L6d40_iso_graphic_5:  ; MDL bitmap visualization
#6d40#05c016
    db #1e, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00
#6d50#05d016
    db #ff, #00, #ff, #00, #e1, #16, #ff, #00, #ff, #00, #ff, #00, #c0, #35, #7f, #80
#6d60#05e016
    db #ff, #00, #ff, #00, #c0, #35, #1f, #60, #ff, #00, #ff, #00, #80, #7d, #07, #58
#6d70#05f016
    db #ff, #00, #ff, #00, #80, #65, #01, #56, #ff, #00, #ff, #00, #80, #63, #00, #55
#6d80#060016
    db #7f, #80, #ff, #00, #80, #41, #00, #55, #3f, #40, #fe, #01, #00, #e0, #00, #d5
#6d90#061016
    db #3f, #40, #fe, #01, #00, #71, #00, #d5, #3f, #40, #fc, #03, #00, #59, #00, #8f
#6da0#062016
    db #3f, #c0, #fc, #03, #00, #57, #00, #88, #3f, #40, #f8, #07, #00, #d7, #00, #88
#6db0#063016
    db #7f, #80, #f8, #06, #00, #57, #00, #88, #7f, #80, #f8, #06, #00, #37, #00, #cf
#6dc0#064016
    db #ff, #00, #f8, #04, #00, #17, #07, #38, #ff, #00, #f8, #06, #00, #0f, #03, #0c
#6dd0#065016
    db #ff, #00, #fe, #01, #00, #1a, #03, #14, #ff, #00, #ff, #00, #00, #9b, #03, #1c
#6de0#066016
    db #ff, #00, #ff, #00, #80, #78, #03, #f4, #ff, #00, #ff, #00, #c0, #38, #07, #a8
#6df0#067016
    db #ff, #00, #ff, #00, #c0, #38, #07, #88, #ff, #00, #ff, #00, #c0, #3c, #0f, #f0
#6e00#068016
    db #ff, #00, #ff, #00, #c0, #33, #7f, #80, #ff, #00, #ff, #00, #c0, #30, #7f, #80
#6e10#069016
    db #ff, #00, #ff, #00, #c0, #21, #ff, #00, #ff, #00, #ff, #00, #c0, #31, #ff, #00
#6e20#06a016
    db #ff, #00, #ff, #00, #f0, #0e, #ff, #00, #ff, #00, #ff, #00, #fc, #02, #ff, #00
#6e30#06b02
    db #ff, #00
#6e32#06b2
L6e32_iso_graphic_6:  ; MDL bitmap visualization
#6e32#06b216
    db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fe, #01
#6e42#06c216
    db #1f, #60, #ff, #00, #fc, #03, #07, #58, #ff, #00, #fc, #03, #03, #54, #ff, #00
#6e52#06d216
    db #f8, #07, #02, #d5, #7f, #80, #f8, #06, #02, #75, #1f, #60, #f0, #0e, #00, #1f
#6e62#06e216
    db #07, #58, #f0, #0e, #00, #07, #03, #54, #e0, #1e, #00, #07, #03, #d4, #e0, #1c
#6e72#06f216
    db #00, #0e, #03, #74, #c0, #3c, #00, #0e, #03, #1c, #c0, #3f, #00, #0e, #03, #04
#6e82#070216
    db #80, #7c, #00, #de, #03, #04, #80, #7c, #00, #3c, #07, #08, #80, #7c, #00, #1c
#6e92#071216
    db #07, #08, #80, #5c, #00, #1f, #07, #08, #80, #7e, #00, #1c, #0f, #d0, #e0, #19
#6ea2#072216
    db #00, #9c, #0f, #30, #e0, #18, #00, #7c, #0f, #10, #e0, #10, #00, #1c, #0f, #10
#6eb2#073216
    db #e0, #18, #00, #3e, #0f, #10, #f8, #06, #00, #39, #0f, #90, #fe, #01, #20, #d8
#6ec2#074216
    db #0f, #70, #ff, #00, #a0, #50, #0f, #10, #ff, #00, #e0, #18, #1f, #20, #ff, #00
#6ed2#075216
    db #f8, #06, #1f, #20, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #ff, #00, #bf, #40
#6ee2#0762
L6ee2_iso_graphic_7:  ; MDL bitmap visualization
#6ee2#076216
    db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00
#6ef2#077216
    db #ff, #00, #ff, #00, #e1, #16, #ff, #00, #ff, #00, #ff, #00, #c0, #35, #7f, #80
#6f02#078216
    db #ff, #00, #ff, #00, #c0, #35, #3f, #40, #ff, #00, #ff, #00, #80, #7d, #27, #58
#6f12#079216
    db #ff, #00, #ff, #00, #80, #67, #21, #56, #ff, #00, #ff, #00, #00, #e1, #00, #f5
#6f22#07a216
    db #7f, #80, #ff, #00, #00, #e0, #00, #75, #3f, #40, #fe, #01, #00, #e0, #00, #7d
#6f32#07b216
    db #3f, #40, #fe, #01, #00, #c0, #00, #e7, #3f, #40, #fc, #03, #00, #c0, #00, #e1
#6f42#07c216
    db #3f, #c0, #fc, #03, #00, #f0, #00, #e0, #3f, #40, #f8, #07, #00, #cd, #00, #e0
#6f52#07d216
    db #3f, #40, #f8, #07, #00, #c3, #00, #c0, #7f, #80, #f8, #07, #00, #c1, #00, #c0
#6f62#07e216
    db #7f, #80, #f8, #05, #00, #c1, #00, #f0, #7f, #80, #f8, #07, #00, #e1, #00, #cd
#6f72#07f216
    db #ff, #00, #fe, #01, #00, #99, #00, #c3, #ff, #00, #fe, #01, #00, #87, #00, #c1
#6f82#080216
    db #ff, #00, #fe, #01, #00, #01, #00, #c1, #ff, #00, #fe, #01, #00, #83, #00, #e1
#6f92#081216
    db #ff, #00, #ff, #00, #80, #63, #00, #99, #ff, #00, #ff, #00, #e2, #1d, #00, #87
#6fa2#082216
    db #ff, #00, #ff, #00, #fa, #05, #00, #01, #ff, #00, #ff, #00, #fe, #01, #01, #82
#6fb2#083216
    db #ff, #00, #ff, #00, #ff, #00, #81, #62, #ff, #00, #ff, #00, #ff, #00, #e3, #1c
#6fc2#084210
    db #ff, #00, #ff, #00, #ff, #00, #fb, #04, #ff, #00
#6fcc#084c
L6fcc_iso_graphic_8:  ; MDL bitmap visualization
#6fcc#084c16
    db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #ff, #00
#6fdc#085c16
    db #0f, #f0, #ff, #00, #fe, #01, #03, #bc, #ff, #00, #fe, #01, #01, #0e, #ff, #00
#6fec#086c16
    db #fc, #03, #01, #42, #3f, #c0, #fc, #02, #00, #2a, #0f, #f0, #fc, #03, #00, #f5
#6ffc#087c16
    db #03, #bc, #ff, #00, #00, #f5, #01, #0e, #f3, #0c, #c0, #3b, #01, #42, #f0, #0f
#700c#088c16
    db #c0, #32, #01, #2a, #e0, #1b, #00, #cf, #03, #f4, #e0, #10, #00, #c3, #03, #f4
#701c#089c16
    db #c0, #34, #00, #98, #07, #f8, #c0, #22, #00, #a6, #1f, #20, #c0, #3f, #00, #22
#702c#08ac16
    db #3f, #40, #f0, #0f, #00, #42, #1f, #e0, #fc, #02, #00, #64, #1f, #a0, #fc, #03
#703c#08bc16
    db #00, #1d, #1f, #a0, #ff, #00, #00, #c1, #3f, #40, #ff, #00, #c0, #33, #3f, #40
#704c#08cc12
    db #ff, #00, #f0, #0f, #7f, #80, #ff, #00, #fd, #02, #ff, #00
#7058#08d8
L7058_iso_graphic_9:  ; MDL bitmap visualization
#7058#08d816
    db #17, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00
#7068#08e816
    db #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00, #e0, #1b, #3f, #c0
#7078#08f816
    db #ff, #00, #ff, #00, #e0, #10, #1f, #e0, #ff, #00, #ff, #00, #c0, #34, #13, #2c
#7088#090816
    db #ff, #00, #ff, #00, #c0, #22, #00, #af, #ff, #00, #ff, #00, #c0, #3f, #00, #5b
#7098#091816
    db #3f, #c0, #ff, #00, #f0, #0f, #00, #50, #1f, #e0, #ff, #00, #3c, #c3, #00, #b4
#70a8#092816
    db #1f, #20, #ff, #00, #0c, #f3, #00, #22, #1f, #a0, #fe, #01, #00, #bc, #00, #ff
#70b8#093816
    db #3f, #40, #fe, #01, #00, #0c, #00, #3f, #3f, #40, #fc, #03, #00, #49, #00, #8f
#70c8#094816
    db #7f, #80, #fc, #02, #00, #2a, #01, #62, #ff, #00, #fc, #03, #00, #f2, #03, #24
#70d8#095816
    db #ff, #00, #ff, #00, #00, #f4, #01, #2e, #ff, #00, #ff, #00, #c0, #26, #01, #4a
#70e8#096816
    db #ff, #00, #ff, #00, #c0, #31, #01, #da, #ff, #00, #ff, #00, #f0, #0c, #03, #14
#70f8#097816
    db #ff, #00, #ff, #00, #fc, #03, #03, #34, #ff, #00, #ff, #00, #ff, #00, #07, #f8
#7108#098810
    db #ff, #00, #ff, #00, #ff, #00, #df, #20, #ff, #00
#7112#0992
L7112_iso_graphic_10:  ; MDL bitmap visualization
#7112#099216
    db #1c, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01
#7122#09a216
    db #03, #ac, #ff, #00, #fe, #01, #00, #ab, #ff, #00, #fc, #03, #00, #aa, #3f, #c0
#7132#09b216
    db #fc, #02, #00, #aa, #0f, #b0, #f8, #07, #00, #ea, #03, #ac, #f8, #05, #00, #3a
#7142#09c216
    db #00, #ab, #f0, #0f, #00, #0e, #00, #ab, #f0, #0a, #00, #03, #01, #ae, #e0, #1e
#7152#09d216
    db #00, #60, #01, #fa, #e0, #14, #00, #98, #03, #34, #c0, #3c, #00, #86, #03, #14
#7162#09e216
    db #c0, #29, #00, #01, #07, #a8, #80, #79, #00, #01, #07, #28, #80, #52, #00, #01
#7172#09f216
    db #07, #78, #00, #f3, #00, #82, #03, #5c, #00, #a4, #00, #62, #1f, #a0, #00, #e4
#7182#0a0216
    db #00, #1c, #1f, #a0, #00, #c8, #00, #05, #3f, #40, #00, #c8, #00, #09, #3f, #40
#7192#0a1216
    db #00, #8c, #00, #0b, #3f, #c0, #00, #c3, #00, #12, #1f, #e0, #c0, #30, #00, #d5
#71a2#0a2216
    db #ff, #00, #f0, #0c, #01, #27, #ff, #00, #fc, #03, #01, #0a, #ff, #00, #ff, #00
#71b2#0a3210
    db #03, #cc, #ff, #00, #ff, #00, #c7, #38, #ff, #00
#71bc#0a3c
L71bc_iso_graphic_11:  ; MDL bitmap visualization
#71bc#0a3c16
    db #1c, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#71cc#0a4c16
    db #ff, #00, #ff, #00, #e0, #1a, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #0f, #b0
#71dc#0a5c16
    db #ff, #00, #ff, #00, #c0, #3a, #03, #ac, #ff, #00, #ff, #00, #c0, #2a, #00, #ab
#71ec#0a6c16
    db #ff, #00, #ff, #00, #80, #7e, #00, #aa, #3f, #c0, #ff, #00, #80, #53, #00, #aa
#71fc#0a7c16
    db #0f, #b0, #ff, #00, #00, #f0, #00, #ea, #0f, #b0, #ff, #00, #00, #a0, #00, #3a
#720c#0a8c16
    db #1f, #e0, #fe, #01, #00, #e6, #00, #0f, #1f, #a0, #fe, #01, #00, #49, #00, #83
#721c#0a9c16
    db #3f, #40, #fc, #03, #00, #c8, #00, #61, #3f, #40, #fc, #02, #00, #90, #00, #1a
#722c#0aac16
    db #7f, #80, #f8, #07, #00, #90, #00, #12, #7f, #80, #f8, #05, #00, #20, #00, #17
#723c#0abc16
    db #7f, #80, #f0, #0f, #00, #38, #00, #25, #3f, #c0, #f0, #0a, #00, #46, #01, #2a
#724c#0acc16
    db #ff, #00, #f0, #0e, #00, #41, #01, #ca, #ff, #00, #f0, #0c, #00, #80, #03, #54
#725c#0adc16
    db #ff, #00, #f0, #0c, #00, #80, #03, #94, #ff, #00, #f0, #08, #00, #c0, #03, #bc
#726c#0aec16
    db #ff, #00, #f0, #0c, #00, #31, #01, #2e, #ff, #00, #fc, #03, #00, #0d, #0f, #50
#727c#0afc16
    db #ff, #00, #ff, #00, #00, #c2, #1f, #70, #ff, #00, #ff, #00, #c0, #30, #1f, #a0
#728c#0b0c16
    db #ff, #00, #ff, #00, #f0, #0c, #3f, #c0, #ff, #00, #ff, #00, #fc, #03, #7f, #80
#729c#0b1c2
    db #ff, #00
#729e#0b1e
L729e_iso_graphic_12:  ; MDL bitmap visualization
#729e#0b1e16
    db #1e, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01
#72ae#0b2e16
    db #03, #3c, #ff, #00, #fe, #01, #00, #17, #ff, #00, #fc, #02, #00, #1d, #3f, #c0
#72be#0b3e16
    db #fc, #02, #00, #0d, #0f, #70, #f8, #04, #00, #0d, #03, #5c, #e0, #1c, #00, #05
#72ce#0b4e16
    db #00, #57, #f0, #0f, #00, #47, #00, #55, #f0, #09, #00, #c9, #00, #d5, #e0, #14
#72de#0b5e16
    db #00, #48, #00, #75, #e0, #12, #00, #12, #00, #1d, #c0, #21, #00, #15, #00, #87
#72ee#0b6e16
    db #00, #e0, #00, #a4, #00, #61, #80, #7a, #00, #a8, #01, #1a, #80, #4e, #00, #48
#72fe#0b7e16
    db #01, #12, #00, #c2, #00, #50, #03, #14, #00, #f0, #00, #90, #03, #24, #80, #50
#730e#0b8e16
    db #00, #ac, #07, #28, #c0, #29, #00, #23, #07, #48, #c0, #29, #00, #40, #0f, #d0
#731e#0b9e16
    db #e0, #1a, #00, #40, #0f, #90, #e0, #1a, #00, #80, #1f, #a0, #f0, #0c, #00, #e1
#732e#0bae16
    db #1f, #20, #f8, #06, #00, #19, #3f, #40, #fe, #01, #00, #86, #3f, #40, #ff, #00
#733e#0bbe16
    db #80, #62, #7f, #80, #ff, #00, #e0, #18, #7f, #80, #ff, #00, #f8, #07, #ff, #00
#734e#0bce6
    db #ff, #00, #fe, #01, #ff, #00
#7354#0bd4
L7354_iso_graphic_13:  ; MDL bitmap visualization
#7354#0bd416
    db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#7364#0be416
    db #ff, #00, #ff, #00, #e0, #13, #3f, #c0, #ff, #00, #ff, #00, #e0, #11, #0f, #70
#7374#0bf416
    db #ff, #00, #ff, #00, #c0, #21, #03, #dc, #ff, #00, #ff, #00, #c0, #20, #00, #d7
#7384#0c0416
    db #ff, #00, #ff, #00, #80, #40, #00, #d5, #3f, #c0, #fe, #01, #00, #c0, #00, #55
#7394#0c1416
    db #0f, #70, #ff, #00, #00, #f4, #00, #75, #0f, #50, #ff, #00, #00, #9c, #00, #9d
#73a4#0c2416
    db #0f, #50, #fe, #01, #00, #44, #00, #87, #0f, #50, #fe, #01, #00, #21, #00, #21
#73b4#0c3416
    db #0f, #d0, #fc, #02, #00, #11, #00, #58, #0f, #70, #f0, #0e, #00, #0a, #00, #46
#73c4#0c4416
    db #0f, #10, #f8, #07, #00, #aa, #00, #81, #1f, #a0, #f8, #04, #00, #e4, #00, #81
#73d4#0c5416
    db #1f, #20, #f0, #0c, #00, #25, #00, #01, #3f, #40, #f0, #0f, #00, #09, #00, #02
#73e4#0c6416
    db #3f, #40, #f8, #05, #00, #0a, #00, #c2, #7f, #80, #fc, #02, #00, #92, #00, #34
#73f4#0c7416
    db #7f, #80, #fc, #02, #00, #94, #00, #0d, #ff, #00, #fe, #01, #00, #a4, #00, #09
#7404#0c8416
    db #ff, #00, #fe, #01, #00, #a8, #01, #0a, #ff, #00, #ff, #00, #00, #ce, #01, #12
#7414#0c9416
    db #ff, #00, #ff, #00, #80, #61, #03, #94, #ff, #00, #ff, #00, #e0, #18, #03, #64
#7424#0ca416
    db #ff, #00, #ff, #00, #f8, #06, #07, #28, #ff, #00, #ff, #00, #fe, #01, #07, #88
#7434#0cb416
    db #ff, #00, #ff, #00, #ff, #00, #8f, #70, #ff, #00, #ff, #00, #ff, #00, #ef, #10
#7444#0cc42
    db #ff, #00
#7446#0cc6
L7446_iso_graphic_14:  ; MDL bitmap visualization
#7446#0cc616
    db #1e, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01
#7456#0cd616
    db #03, #8c, #ff, #00, #fe, #01, #00, #87, #ff, #00, #fc, #03, #00, #04, #3f, #c0
#7466#0ce616
    db #fc, #03, #00, #09, #0f, #30, #f8, #07, #00, #09, #03, #0c, #f8, #07, #00, #32
#7476#0cf616
    db #00, #0b, #f0, #0a, #00, #32, #00, #11, #f0, #0a, #00, #32, #00, #13, #e0, #1b
#7486#0d0616
    db #00, #04, #00, #63, #e0, #1c, #00, #c4, #01, #62, #c0, #2c, #00, #34, #01, #66
#7496#0d1616
    db #c0, #29, #00, #8c, #01, #06, #80, #69, #00, #63, #01, #06, #80, #72, #00, #18
#74a6#0d2616
    db #03, #c4, #00, #b2, #00, #0e, #03, #34, #00, #a4, #00, #09, #03, #8c, #00, #a4
#74b6#0d3616
    db #00, #10, #07, #48, #00, #c8, #00, #10, #07, #48, #00, #c8, #00, #20, #0f, #90
#74c6#0d4616
    db #00, #98, #00, #20, #0f, #90, #00, #c6, #00, #41, #1f, #20, #c0, #31, #00, #c1
#74d6#0d5616
    db #1f, #20, #f0, #0c, #00, #62, #3f, #40, #fc, #03, #00, #1a, #3f, #40, #ff, #00
#74e6#0d6616
    db #00, #c4, #7f, #80, #ff, #00, #c0, #30, #7f, #80, #ff, #00, #f0, #0d, #ff, #00
#74f6#0d766
    db #ff, #00, #fc, #03, #ff, #00
#74fc#0d7c
L74fc_iso_graphic_15:  ; MDL bitmap visualization
#74fc#0d7c16
    db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#750c#0d8c16
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #70
#751c#0d9c16
    db #ff, #00, #ff, #00, #c0, #30, #03, #4c, #ff, #00, #ff, #00, #c0, #30, #00, #93
#752c#0dac16
    db #ff, #00, #ff, #00, #80, #70, #00, #90, #3f, #c0, #ff, #00, #80, #73, #00, #20
#753c#0dbc16
    db #0f, #b0, #ff, #00, #00, #a3, #00, #21, #0f, #10, #ff, #00, #00, #a3, #00, #21
#754c#0dcc16
    db #0f, #30, #fe, #01, #00, #b0, #00, #46, #0f, #30, #fe, #01, #00, #cc, #00, #46
#755c#0ddc16
    db #1f, #20, #fc, #02, #00, #c3, #00, #46, #1f, #60, #fc, #02, #00, #98, #00, #c0
#756c#0dec16
    db #1f, #60, #f8, #06, #00, #96, #00, #30, #1f, #60, #f8, #07, #00, #21, #00, #8c
#757c#0dfc16
    db #3f, #40, #f0, #0b, #00, #20, #00, #e3, #3f, #40, #f0, #0a, #00, #40, #00, #98
#758c#0e0c16
    db #3f, #c0, #f0, #0a, #00, #41, #00, #04, #7f, #80, #f0, #0c, #00, #81, #00, #04
#759c#0e1c16
    db #7f, #80, #f0, #0c, #00, #82, #00, #09, #ff, #00, #f0, #09, #00, #82, #00, #09
#75ac#0e2c16
    db #ff, #00, #f0, #0c, #00, #64, #01, #12, #ff, #00, #fc, #03, #00, #1c, #01, #12
#75bc#0e3c16
    db #ff, #00, #ff, #00, #00, #c6, #03, #24, #ff, #00, #ff, #00, #c0, #31, #03, #a4
#75cc#0e4c16
    db #ff, #00, #ff, #00, #f0, #0c, #07, #48, #ff, #00, #ff, #00, #fc, #03, #07, #08
#75dc#0e5c16
    db #ff, #00, #ff, #00, #ff, #00, #0f, #d0, #ff, #00, #ff, #00, #ff, #00, #cf, #30
#75ec#0e6c2
    db #ff, #00
#75ee#0e6e
L75ee_iso_graphic_16:  ; MDL bitmap visualization
#75ee#0e6e16
    db #19, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #f0, #ff, #00, #fe, #01
#75fe#0e7e16
    db #03, #fc, #ff, #00, #fe, #01, #00, #ff, #ff, #00, #fc, #02, #00, #df, #3f, #c0
#760e#0e8e16
    db #fc, #02, #00, #f7, #0f, #f0, #f8, #06, #00, #fd, #03, #fc, #f8, #07, #00, #3f
#761e#0e9e16
    db #00, #7f, #f0, #0b, #00, #0f, #00, #df, #f0, #0a, #00, #63, #00, #f7, #e0, #1a
#762e#0eae16
    db #00, #58, #00, #fd, #e0, #1c, #00, #86, #00, #3f, #c0, #2c, #00, #83, #00, #8f
#763e#0ebe16
    db #c0, #29, #00, #04, #00, #63, #80, #69, #00, #04, #01, #12, #80, #72, #00, #08
#764e#0ece16
    db #01, #12, #00, #f1, #00, #88, #03, #24, #00, #cc, #00, #70, #03, #24, #c0, #33
#765e#0ede16
    db #00, #18, #07, #48, #f0, #0e, #00, #c6, #07, #48, #f0, #07, #00, #31, #0f, #90
#766e#0eee16
    db #f1, #04, #00, #cc, #0f, #10, #ff, #00, #e0, #3b, #1f, #20, #ff, #00, #c0, #1d
#767e#0efe8
    db #1f, #e0, #ff, #00, #c0, #13, #7f, #80
#7686#0f06
L7686_iso_graphic_17:  ; MDL bitmap visualization
#7686#0f0616
    db #19, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #ff, #00
#7696#0f1616
    db #ff, #00, #ff, #00, #e0, #1f, #3f, #c0, #ff, #00, #ff, #00, #e0, #1f, #0f, #f0
#76a6#0f2616
    db #ff, #00, #ff, #00, #c0, #2d, #03, #fc, #ff, #00, #ff, #00, #c0, #2f, #00, #7f
#76b6#0f3616
    db #ff, #00, #ff, #00, #80, #6f, #00, #df, #3f, #c0, #ff, #00, #80, #73, #00, #f7
#76c6#0f4616
    db #0f, #f0, #ff, #00, #00, #b0, #00, #fd, #0f, #f0, #ff, #00, #00, #a6, #00, #3f
#76d6#0f5616
    db #0f, #70, #fe, #01, #00, #a5, #00, #8f, #0f, #d0, #fe, #01, #00, #c8, #00, #63
#76e6#0f6616
    db #0f, #f0, #fc, #02, #00, #c8, #00, #38, #0f, #f0, #fc, #02, #00, #90, #00, #46
#76f6#0f7616
    db #0f, #30, #f8, #06, #00, #90, #00, #41, #1f, #20, #f8, #07, #00, #20, #00, #81
#7706#0f8616
    db #1f, #20, #f0, #0f, #00, #18, #00, #82, #3f, #40, #f0, #0c, #00, #c7, #00, #02
#7716#0f9616
    db #3f, #40, #fc, #03, #00, #31, #00, #84, #7f, #80, #ff, #00, #00, #ec, #00, #64
#7726#0fa616
    db #7f, #80, #ff, #00, #00, #73, #00, #19, #ff, #00, #ff, #00, #10, #4c, #00, #c1
#7736#0fb616
    db #ff, #00, #ff, #00, #dc, #03, #01, #b2, #ff, #00, #ff, #00, #fc, #01, #01, #de
#7746#0fc610
    db #ff, #00, #ff, #00, #fc, #01, #07, #38, #ff, #00
#7750#0fd0
L7750_iso_graphic_18:  ; MDL bitmap visualization
#7750#0fd016
    db #1b, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01
#7760#0fe016
    db #ff, #00, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #fc, #02, #0f, #b0, #ff, #00
#7770#0ff016
    db #fc, #02, #03, #8c, #ff, #00, #fc, #03, #00, #03, #ff, #00, #fe, #01, #00, #08
#7780#100016
    db #3f, #c0, #ff, #00, #00, #c8, #0f, #30, #ff, #00, #00, #f0, #03, #8c, #ff, #00
#7790#101016
    db #00, #ec, #01, #82, #fe, #01, #00, #43, #00, #09, #fe, #01, #00, #c0, #00, #c9
#77a0#102016
    db #fc, #02, #00, #b0, #00, #31, #bc, #43, #00, #8c, #31, #4e, #88, #75, #00, #63
#77b0#103016
    db #3f, #40, #00, #af, #00, #18, #7f, #80, #00, #a6, #00, #c6, #7f, #80, #00, #c6
#77c0#104016
    db #00, #31, #ff, #00, #80, #44, #00, #0d, #ff, #00, #c0, #33, #01, #02, #ff, #00
#77d0#105016
    db #f0, #0c, #00, #c3, #ff, #00, #fc, #03, #00, #34, #7f, #80, #ff, #00, #00, #cc
#77e0#106016
    db #3f, #40, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #f0, #0c, #3f, #40, #ff, #00
#77f0#10704
    db #fc, #03, #7f, #80
#77f4#1074
L77f4_iso_graphic_19:  ; MDL bitmap visualization
#77f4#107416
    db #1b, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7804#108416
    db #ff, #00, #ff, #00, #ef, #10, #ff, #00, #ff, #00, #ff, #00, #e3, #1c, #ff, #00
#7814#109416
    db #ff, #00, #ff, #00, #c0, #2b, #ff, #00, #ff, #00, #ff, #00, #c0, #28, #3f, #c0
#7824#10a416
    db #ff, #00, #ff, #00, #c0, #30, #0f, #30, #ff, #00, #ff, #00, #e0, #10, #03, #8c
#7834#10b416
    db #ff, #00, #ff, #00, #f0, #0c, #00, #83, #ff, #00, #ff, #00, #f0, #0f, #00, #08
#7844#10c416
    db #3f, #c0, #ff, #00, #f0, #0e, #00, #c8, #1f, #20, #ff, #00, #e0, #14, #00, #30
#7854#10d416
    db #0f, #90, #ff, #00, #e0, #1c, #00, #0c, #0f, #90, #ff, #00, #c0, #2b, #00, #03
#7864#10e416
    db #0f, #10, #fb, #04, #c0, #38, #03, #c4, #1f, #e0, #f8, #07, #80, #56, #03, #34
#7874#10f416
    db #ff, #00, #f0, #0a, #00, #f1, #07, #88, #ff, #00, #f0, #0a, #00, #6c, #07, #68
#7884#110416
    db #ff, #00, #f0, #0c, #00, #63, #0f, #10, #ff, #00, #f8, #04, #00, #40, #0f, #d0
#7894#111416
    db #ff, #00, #fc, #03, #00, #30, #1f, #20, #ff, #00, #ff, #00, #00, #cc, #0f, #30
#78a4#112416
    db #ff, #00, #ff, #00, #c0, #33, #07, #48, #ff, #00, #ff, #00, #f0, #0c, #03, #c4
#78b4#113416
    db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4
#78c4#114410
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00
#78ce#114e
L78ce_iso_graphic_20:  ; MDL bitmap visualization
#78ce#114e16
    db #1c, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #ff, #00
#78de#115e16
    db #0f, #90, #ff, #00, #ff, #00, #07, #88, #ff, #00, #fe, #01, #07, #88, #ff, #00
#78ee#116e16
    db #fe, #01, #07, #48, #ff, #00, #fc, #02, #03, #3c, #f3, #0c, #fc, #02, #00, #17
#78fe#117e16
    db #e1, #12, #f8, #04, #00, #3d, #20, #d1, #f8, #05, #00, #37, #00, #71, #f0, #08
#790e#118e16
    db #00, #fd, #00, #e9, #f0, #08, #00, #4f, #01, #46, #e0, #10, #00, #93, #01, #c2
#791e#119e16
    db #e0, #14, #00, #94, #03, #e4, #c0, #23, #00, #25, #03, #34, #c0, #21, #00, #29
#792e#11ae16
    db #07, #28, #80, #42, #00, #4a, #07, #28, #80, #52, #00, #52, #0f, #50, #00, #8e
#793e#11be16
    db #00, #94, #0f, #50, #02, #85, #00, #a4, #1f, #a0, #07, #88, #80, #68, #1f, #a0
#794e#11ce16
    db #87, #48, #e0, #19, #3f, #40, #cf, #30, #f0, #0d, #3f, #40, #ff, #00, #e0, #12
#795e#11de16
    db #7f, #80, #ff, #00, #e0, #10, #7f, #80, #ff, #00, #e0, #11, #ff, #00, #ff, #00
#796e#11ee10
    db #f0, #09, #ff, #00, #ff, #00, #f9, #06, #ff, #00
#7978#11f8
L7978_iso_graphic_21:  ; MDL bitmap visualization
#7978#11f816
    db #1c, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #ff, #00
#7988#120816
    db #ff, #00, #ff, #00, #f0, #09, #ff, #00, #ff, #00, #ff, #00, #f0, #08, #7f, #80
#7998#121816
    db #ff, #00, #ff, #00, #e0, #18, #7f, #80, #ff, #00, #ff, #00, #e0, #14, #7f, #80
#79a8#122816
    db #ff, #00, #ff, #00, #c0, #23, #3f, #c0, #3f, #c0, #ff, #00, #c0, #21, #0e, #71
#79b8#123816
    db #1f, #20, #ff, #00, #80, #43, #02, #dd, #0f, #10, #ff, #00, #80, #53, #00, #77
#79c8#124816
    db #0f, #10, #ff, #00, #00, #8f, #00, #de, #0f, #90, #ff, #00, #00, #84, #00, #f4
#79d8#125816
    db #1f, #60, #fe, #01, #00, #09, #00, #3c, #1f, #20, #fe, #01, #00, #49, #00, #4e
#79e8#126816
    db #3f, #40, #fc, #02, #00, #32, #00, #53, #3f, #40, #fc, #02, #00, #12, #00, #92
#79f8#127816
    db #7f, #80, #f8, #04, #00, #24, #00, #a2, #7f, #80, #f8, #05, #00, #25, #00, #25
#7a08#128816
    db #ff, #00, #f0, #08, #00, #e9, #00, #45, #ff, #00, #f0, #08, #20, #5a, #01, #4a
#7a18#129816
    db #ff, #00, #f0, #08, #78, #86, #01, #8a, #ff, #00, #f8, #04, #7e, #81, #03, #94
#7a28#12a816
    db #ff, #00, #fc, #03, #ff, #00, #03, #d4, #ff, #00, #ff, #00, #fe, #01, #07, #28
#7a38#12b816
    db #ff, #00, #ff, #00, #fe, #01, #07, #08, #ff, #00, #ff, #00, #fe, #01, #0f, #10
#7a48#12c816
    db #ff, #00, #ff, #00, #ff, #00, #0f, #90, #ff, #00, #ff, #00, #ff, #00, #9f, #60
#7a58#12d82
    db #ff, #00
#7a5a#12da
L7a5a_iso_graphic_22:  ; MDL bitmap visualization
#7a5a#12da16
    db #1c, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #8f, #70, #ff, #00, #ff, #00
#7a6a#12ea16
    db #03, #8c, #ff, #00, #fe, #01, #00, #03, #ff, #00, #fc, #02, #00, #20, #3f, #c0
#7a7a#12fa16
    db #fc, #02, #00, #a4, #0f, #b0, #f8, #04, #00, #a4, #0f, #90, #f8, #04, #00, #04
#7a8a#130a16
    db #07, #88, #f0, #0a, #00, #70, #07, #88, #f0, #09, #00, #8c, #07, #88, #e0, #16
#7a9a#131a16
    db #00, #03, #0f, #90, #e0, #12, #00, #00, #0f, #90, #c0, #24, #00, #61, #1f, #20
#7aaa#132a16
    db #c0, #34, #00, #19, #1f, #20, #c0, #28, #00, #03, #3f, #c0, #80, #48, #00, #03
#7aba#133a16
    db #0f, #f0, #80, #71, #00, #87, #0f, #70, #80, #50, #00, #65, #0f, #d0, #80, #60
#7aca#134a16
    db #00, #08, #0f, #70, #80, #60, #00, #0c, #0f, #10, #80, #46, #00, #13, #1f, #20
#7ada#135a16
    db #80, #41, #03, #9c, #1f, #e0, #80, #40, #1f, #20, #ff, #00, #c0, #20, #1f, #20
#7aea#136a16
    db #ff, #00, #e0, #10, #3f, #40, #ff, #00, #f0, #0c, #3f, #40, #ff, #00, #fc, #03
#7afa#137a10
    db #7f, #80, #ff, #00, #ff, #00, #7f, #80, #ff, #00
#7b04#1384
L7b04_iso_graphic_23:  ; MDL bitmap visualization
#7b04#138416
    db #1c, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f8, #07, #ff, #00
#7b14#139416
    db #ff, #00, #ff, #00, #f0, #08, #3f, #c0, #ff, #00, #ff, #00, #e0, #10, #0f, #30
#7b24#13a416
    db #ff, #00, #ff, #00, #c0, #22, #03, #0c, #ff, #00, #ff, #00, #c0, #2a, #00, #4b
#7b34#13b416
    db #ff, #00, #ff, #00, #80, #4a, #00, #49, #ff, #00, #ff, #00, #80, #40, #00, #48
#7b44#13c416
    db #7f, #80, #ff, #00, #00, #a7, #00, #08, #7f, #80, #ff, #00, #00, #98, #00, #c8
#7b54#13d416
    db #7f, #80, #fe, #01, #00, #60, #00, #39, #ff, #00, #fe, #01, #00, #20, #00, #09
#7b64#13e416
    db #ff, #00, #fc, #02, #00, #46, #01, #12, #ff, #00, #fc, #03, #00, #41, #01, #92
#7b74#13f416
    db #ff, #00, #fc, #02, #00, #80, #03, #3c, #ff, #00, #f8, #04, #00, #80, #00, #3f
#7b84#140416
    db #ff, #00, #f8, #07, #00, #18, #00, #77, #ff, #00, #f8, #05, #00, #06, #00, #5d
#7b94#141416
    db #ff, #00, #f8, #06, #00, #00, #00, #87, #ff, #00, #f8, #06, #00, #00, #00, #c1
#7ba4#142416
    db #ff, #00, #f8, #04, #00, #61, #01, #32, #ff, #00, #f8, #04, #00, #19, #31, #ce
#7bb4#143416
    db #ff, #00, #f8, #04, #01, #02, #ff, #00, #ff, #00, #fc, #02, #01, #02, #ff, #00
#7bc4#144416
    db #ff, #00, #fe, #01, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4, #ff, #00
#7bd4#145416
    db #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00
#7be4#14642
    db #ff, #00
#7be6#1466
L7be6_iso_graphic_24:  ; MDL bitmap visualization
#7be6#146616
    db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7bf6#147616
    db #ff, #00, #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #c0, #39, #3f, #c0
#7c06#148616
    db #ff, #00, #80, #43, #0f, #30, #ff, #00, #80, #43, #07, #08, #ff, #00, #00, #95
#7c16#149616
    db #07, #48, #f3, #0c, #00, #85, #03, #44, #f0, #0f, #00, #09, #03, #54, #e0, #1f
#7c26#14a616
    db #00, #c9, #03, #14, #e0, #1d, #00, #f1, #03, #c4, #e0, #1f, #00, #72, #03, #34
#7c36#14b616
    db #e0, #1b, #00, #d2, #03, #0c, #e0, #10, #00, #f4, #03, #0c, #e0, #18, #00, #34
#7c46#14c616
    db #03, #04, #f8, #06, #00, #29, #03, #84, #f8, #05, #00, #a8, #03, #64, #fc, #02
#7c56#14d616
    db #00, #d0, #03, #04, #fc, #03, #00, #10, #07, #08, #fe, #01, #00, #26, #07, #08
#7c66#14e616
    db #fe, #01, #00, #21, #0f, #90, #fe, #01, #00, #40, #0f, #10, #fe, #01, #00, #40
#7c76#14f616
    db #1f, #20, #fe, #01, #00, #98, #1f, #20, #fe, #01, #00, #86, #3f, #40, #fe, #01
#7c86#150616
    db #00, #00, #3f, #40, #ff, #00, #00, #e1, #7f, #80, #ff, #00, #e1, #1e, #ff, #00
#7c96#1516
L7c96_iso_graphic_25:  ; MDL bitmap visualization
#7c96#151616
    db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7ca6#152616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #8f, #70
#7cb6#153616
    db #ff, #00, #ff, #00, #fc, #03, #03, #9c, #ff, #00, #ff, #00, #f8, #04, #00, #33
#7cc6#154616
    db #ff, #00, #ff, #00, #f8, #04, #00, #30, #7f, #80, #ff, #00, #f0, #09, #00, #54
#7cd6#155616
    db #7f, #80, #ff, #00, #30, #c8, #00, #54, #3f, #40, #ff, #00, #00, #f0, #00, #95
#7ce6#156616
    db #3f, #40, #fe, #01, #00, #fc, #00, #91, #3f, #40, #fe, #01, #00, #df, #00, #1c
#7cf6#157616
    db #3f, #40, #fe, #01, #00, #f7, #00, #23, #3f, #40, #fe, #01, #00, #bd, #00, #20
#7d06#158616
    db #3f, #c0, #fe, #01, #00, #0f, #00, #40, #3f, #c0, #fe, #01, #00, #83, #00, #40
#7d16#159616
    db #3f, #40, #ff, #00, #80, #62, #00, #98, #3f, #40, #ff, #00, #80, #5a, #00, #86
#7d26#15a616
    db #3f, #40, #ff, #00, #c0, #2d, #00, #00, #3f, #40, #ff, #00, #c0, #31, #00, #00
#7d36#15b616
    db #7f, #80, #ff, #00, #e0, #12, #00, #60, #7f, #80, #ff, #00, #e0, #12, #00, #19
#7d46#15c616
    db #ff, #00, #ff, #00, #e0, #14, #00, #01, #ff, #00, #ff, #00, #e0, #14, #01, #02
#7d56#15d616
    db #ff, #00, #ff, #00, #e0, #19, #01, #82, #ff, #00, #ff, #00, #e0, #18, #03, #64
#7d66#15e616
    db #ff, #00, #ff, #00, #e0, #10, #03, #04, #ff, #00, #ff, #00, #f0, #0e, #07, #18
#7d76#15f610
    db #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00
#7d80#1600
L7d80_iso_graphic_26:  ; MDL bitmap visualization
#7d80#160016
    db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7d90#161016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7da0#162016
    db #ff, #00, #9c, #63, #ff, #00, #fe, #01, #00, #9e, #3f, #c0, #f8, #06, #00, #06
#7db0#163016
    db #3f, #40, #f0, #0c, #00, #4f, #3f, #40, #f0, #0b, #00, #0c, #1f, #e0, #e0, #18
#7dc0#164016
    db #00, #dc, #0f, #90, #e0, #1a, #00, #19, #0f, #10, #c0, #2a, #00, #b9, #0f, #50
#7dd0#165016
    db #c0, #2a, #00, #b2, #0f, #10, #c0, #28, #00, #b2, #0f, #d0, #c0, #2c, #00, #24
#7de0#166016
    db #0f, #30, #c0, #33, #00, #35, #0f, #10, #c0, #30, #00, #cd, #0f, #50, #c0, #22
#7df0#167016
    db #00, #31, #0f, #50, #c0, #22, #00, #0c, #0f, #50, #c0, #24, #00, #23, #0f, #10
#7e00#168016
    db #c0, #24, #00, #20, #0f, #d0, #c0, #20, #00, #42, #0f, #30, #e0, #10, #00, #42
#7e10#169016
    db #1f, #20, #e0, #10, #00, #04, #1f, #20, #f0, #0c, #00, #04, #3f, #40, #fc, #03
#7e20#16a016
    db #00, #00, #3f, #40, #ff, #00, #00, #e1, #7f, #80, #ff, #00, #e1, #1e, #ff, #00
#7e30#16b0
L7e30_iso_graphic_27:  ; MDL bitmap visualization
#7e30#16b016
    db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7e40#16c016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7e50#16d016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #cf, #30
#7e60#16e016
    db #ff, #00, #ff, #00, #e0, #19, #03, #ec, #ff, #00, #ff, #00, #80, #60, #03, #64
#7e70#16f016
    db #ff, #00, #ff, #00, #00, #c4, #03, #f4, #ff, #00, #ff, #00, #00, #b0, #01, #ce
#7e80#170016
    db #ff, #00, #fe, #01, #00, #8d, #00, #c9, #ff, #00, #fe, #01, #00, #a1, #00, #91
#7e90#171016
    db #ff, #00, #fc, #02, #00, #ab, #00, #95, #ff, #00, #fc, #02, #00, #ab, #00, #21
#7ea0#172016
    db #ff, #00, #fc, #02, #00, #8b, #00, #2d, #ff, #00, #fc, #02, #00, #c2, #00, #43
#7eb0#173016
    db #ff, #00, #fc, #03, #00, #33, #00, #51, #ff, #00, #fc, #03, #00, #0c, #00, #d5
#7ec0#174016
    db #ff, #00, #fc, #02, #00, #23, #00, #15, #ff, #00, #fc, #02, #00, #20, #00, #c5
#7ed0#175016
    db #ff, #00, #fc, #02, #00, #42, #00, #31, #ff, #00, #fc, #02, #00, #42, #00, #0d
#7ee0#176016
    db #ff, #00, #fc, #02, #00, #04, #00, #23, #ff, #00, #fe, #01, #00, #04, #01, #22
#7ef0#177016
    db #ff, #00, #fe, #01, #00, #00, #01, #42, #ff, #00, #ff, #00, #00, #c0, #03, #44
#7f00#178016
    db #ff, #00, #ff, #00, #c0, #30, #03, #04, #ff, #00, #ff, #00, #f0, #0e, #07, #18
#7f10#179010
    db #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00
#7f1a#179a
L7f1a_iso_graphic_28:  ; MDL bitmap visualization
#7f1a#179a16
    db #1a, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7f2a#17aa16
    db #8f, #70, #ff, #00, #fe, #01, #03, #8c, #ff, #00, #fc, #02, #00, #03, #ff, #00
#7f3a#17ba16
    db #fc, #02, #00, #20, #3f, #c0, #f8, #05, #00, #24, #0f, #30, #f8, #05, #00, #04
#7f4a#17ca16
    db #07, #08, #f0, #08, #00, #70, #07, #48, #f0, #0d, #00, #8c, #03, #54, #e0, #1a
#7f5a#17da16
    db #00, #03, #03, #14, #e0, #1a, #00, #20, #03, #c4, #c0, #2c, #00, #20, #03, #34
#7f6a#17ea16
    db #e0, #1c, #00, #42, #03, #0c, #e0, #18, #00, #42, #03, #0c, #f0, #0c, #00, #04
#7f7a#17fa16
    db #03, #24, #fc, #03, #00, #04, #03, #24, #fe, #01, #00, #c0, #03, #44, #fe, #01
#7f8a#180a16
    db #00, #f0, #03, #44, #fc, #03, #00, #8c, #07, #08, #fc, #03, #0c, #93, #07, #08
#7f9a#181a16
    db #fc, #03, #0f, #10, #0f, #d0, #fc, #03, #1f, #20, #cf, #30, #fc, #02, #1f, #20
#7faa#182a14
    db #ff, #00, #fc, #03, #3f, #40, #ff, #00, #ff, #00, #3f, #c0, #ff, #00
#7fb8#1838
L7fb8_iso_graphic_29:  ; MDL bitmap visualization
#7fb8#183816
    db #1a, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#7fc8#184816
    db #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #ff, #00, #e0, #18, #3f, #c0
#7fd8#185816
    db #ff, #00, #ff, #00, #c0, #20, #0f, #30, #ff, #00, #ff, #00, #c0, #22, #03, #0c
#7fe8#186816
    db #ff, #00, #ff, #00, #80, #52, #00, #43, #ff, #00, #ff, #00, #80, #50, #00, #40
#7ff8#187816
    db #7f, #80, #ff, #00, #00, #87, #00, #04, #7f, #80, #ff, #00, #00, #d8, #00, #c5
#8008#188816
    db #3f, #40, #fe, #01, #00, #a0, #00, #31, #3f, #40, #fe, #01, #00, #a2, #00, #0c
#8018#189816
    db #3f, #40, #fc, #02, #00, #c2, #00, #03, #3f, #40, #fe, #01, #00, #c4, #00, #20
#8028#18a816
    db #3f, #c0, #fe, #01, #00, #84, #00, #20, #3f, #c0, #ff, #00, #00, #c0, #00, #42
#8038#18b816
    db #3f, #40, #ff, #00, #c0, #30, #00, #42, #3f, #40, #ff, #00, #e0, #1c, #00, #04
#8048#18c816
    db #3f, #40, #ff, #00, #e0, #1f, #00, #04, #3f, #40, #ff, #00, #c0, #38, #00, #c0
#8058#18d816
    db #7f, #80, #ff, #00, #c0, #39, #c0, #30, #7f, #80, #ff, #00, #c0, #31, #f0, #0d
#8068#18e816
    db #ff, #00, #ff, #00, #c1, #32, #fc, #03, #ff, #00, #ff, #00, #c1, #22, #ff, #00
#8078#18f816
    db #ff, #00, #ff, #00, #c3, #34, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00
#8088#19082
    db #ff, #00
#808a#190a
L808a_iso_graphic_30:  ; MDL bitmap visualization
#808a#190a16
    db #1d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#809a#191a16
    db #e3, #1c, #ff, #00, #ff, #00, #00, #fb, #ff, #00, #fc, #03, #00, #f8, #3f, #c0
#80aa#192a16
    db #fc, #03, #00, #da, #0f, #30, #f8, #07, #00, #78, #0f, #10, #f8, #07, #00, #da
#80ba#193a16
    db #0f, #50, #f0, #0b, #00, #78, #07, #18, #f0, #0b, #00, #fc, #07, #58, #e0, #13
#80ca#194a16
    db #00, #e3, #07, #18, #e0, #13, #00, #00, #03, #dc, #c0, #24, #00, #7e, #03, #3c
#80da#195a16
    db #c0, #25, #00, #ff, #03, #9c, #c0, #29, #00, #3f, #03, #dc, #c0, #2a, #00, #1e
#80ea#196a16
    db #03, #cc, #c0, #32, #00, #1c, #03, #6c, #c0, #36, #00, #38, #03, #2c, #c0, #27
#80fa#197a16
    db #00, #ec, #03, #24, #c0, #27, #00, #c4, #07, #68, #c0, #27, #00, #ef, #07, #c8
#810a#198a16
    db #e0, #17, #00, #3f, #0f, #d0, #e0, #12, #00, #0f, #0f, #90, #e0, #13, #00, #0f
#811a#199a16
    db #1f, #a0, #f0, #09, #00, #8f, #1f, #20, #f0, #0c, #00, #7c, #3f, #40, #fc, #03
#812a#19aa16
    db #00, #00, #3f, #c0, #ff, #00, #00, #c7, #ff, #00, #ff, #00, #c7, #38, #ff, #00
#813a#19ba
L813a_iso_graphic_31:  ; MDL bitmap visualization
#813a#19ba16
    db #1d, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#814a#19ca16
    db #ff, #00, #ff, #00, #fe, #01, #3f, #c0, #ff, #00, #ff, #00, #f0, #0f, #0f, #b0
#815a#19da16
    db #ff, #00, #ff, #00, #c0, #3f, #03, #8c, #ff, #00, #ff, #00, #c0, #3d, #00, #a3
#816a#19ea16
    db #ff, #00, #ff, #00, #80, #77, #00, #81, #ff, #00, #ff, #00, #80, #7d, #00, #a5
#817a#19fa16
    db #ff, #00, #ff, #00, #00, #b7, #00, #81, #7f, #80, #ff, #00, #00, #bf, #00, #c5
#818a#1a0a16
    db #7f, #80, #fe, #01, #00, #3e, #00, #31, #7f, #80, #fe, #01, #00, #30, #00, #0d
#819a#1a1a16
    db #3f, #c0, #fc, #02, #00, #47, #00, #e3, #3f, #c0, #fc, #02, #00, #5f, #00, #f9
#81aa#1a2a16
    db #3f, #c0, #fc, #02, #00, #93, #00, #fd, #3f, #c0, #fc, #02, #00, #a1, #00, #ec
#81ba#1a3a16
    db #3f, #c0, #fc, #03, #00, #21, #00, #c6, #3f, #c0, #fc, #03, #00, #63, #00, #82
#81ca#1a4a16
    db #3f, #c0, #fc, #02, #00, #7e, #00, #c2, #3f, #40, #fc, #02, #00, #7c, #00, #46
#81da#1a5a16
    db #7f, #80, #fc, #02, #00, #7e, #00, #fc, #7f, #80, #fe, #01, #00, #73, #00, #fd
#81ea#1a6a16
    db #ff, #00, #fe, #01, #00, #20, #00, #f9, #ff, #00, #fe, #01, #00, #30, #01, #fa
#81fa#1a7a16
    db #ff, #00, #ff, #00, #00, #98, #01, #f2, #ff, #00, #ff, #00, #00, #c7, #03, #c4
#820a#1a8a16
    db #ff, #00, #ff, #00, #c0, #30, #03, #0c, #ff, #00, #ff, #00, #f0, #0c, #0f, #70
#821a#1a9a10
    db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00
#8224#1aa4
L8224_iso_graphic_32:  ; MDL bitmap visualization
#8224#1aa416
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8234#1ab416
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8244#1ac416
    db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6
#8254#1ad416
    db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01
#8264#1ae416
    db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20
#8274#1af416
    db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #18
#8284#1b0416
    db #3f, #40, #f0, #0c, #00, #3c, #3f, #40, #f0, #0c, #00, #7c, #7f, #80, #f0, #08
#8294#1b1416
    db #00, #6c, #7f, #80, #f0, #0c, #00, #5f, #ff, #00, #fc, #03, #00, #7d, #7f, #80
#82a4#1b2416
    db #ff, #00, #01, #fa, #ff, #00, #ff, #00, #81, #72, #ff, #00, #ff, #00, #e3, #1c
#82b4#1b342
    db #ff, #00
#82b6#1b36
L82b6_iso_graphic_33:  ; MDL bitmap visualization
#82b6#1b3616
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#82c6#1b4616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#82d6#1b5616
    db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c
#82e6#1b6616
    db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00
#82f6#1b7616
    db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62
#8306#1b8616
    db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a1
#8316#1b9616
    db #03, #84, #ff, #00, #00, #c3, #03, #c4, #ff, #00, #00, #c7, #07, #c8, #ff, #00
#8326#1ba616
    db #00, #86, #07, #c8, #ff, #00, #00, #c5, #0f, #f0, #ff, #00, #c0, #37, #07, #d8
#8336#1bb616
    db #ff, #00, #f0, #0f, #1f, #a0, #ff, #00, #f8, #07, #1f, #20, #ff, #00, #fe, #01
#8346#1bc62
    db #3f, #c0
#8348#1bc8
L8348_iso_graphic_34:  ; MDL bitmap visualization
#8348#1bc816
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8358#1bd816
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8368#1be816
    db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6
#8378#1bf816
    db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01
#8388#1c0816
    db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20
#8398#1c1816
    db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #18
#83a8#1c2816
    db #3f, #40, #f0, #0c, #00, #2c, #3f, #40, #f0, #0d, #00, #8e, #7f, #80, #f0, #08
#83b8#1c3816
    db #00, #6e, #7f, #80, #f0, #0c, #00, #1f, #ff, #00, #fc, #03, #00, #4d, #ff, #00
#83c8#1c4816
    db #ff, #00, #01, #de, #ff, #00, #ff, #00, #81, #5a, #ff, #00, #ff, #00, #c3, #34
#83d8#1c582
    db #ff, #00
#83da#1c5a
L83da_iso_graphic_35:  ; MDL bitmap visualization
#83da#1c5a16
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#83ea#1c6a16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#83fa#1c7a16
    db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c
#840a#1c8a16
    db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00
#841a#1c9a16
    db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62
#842a#1caa16
    db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a1
#843a#1cba16
    db #03, #84, #ff, #00, #00, #c2, #03, #c4, #ff, #00, #00, #d8, #07, #e8, #ff, #00
#844a#1cca16
    db #00, #86, #07, #e8, #ff, #00, #00, #c1, #0f, #f0, #ff, #00, #c0, #34, #0f, #d0
#845a#1cda16
    db #ff, #00, #f0, #0d, #1f, #e0, #ff, #00, #f8, #05, #1f, #a0, #ff, #00, #fc, #03
#846a#1cea2
    db #3f, #40
#846c#1cec
L846c_iso_graphic_36:  ; MDL bitmap visualization
#846c#1cec16
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#847c#1cfc16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#848c#1d0c16
    db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6
#849c#1d1c16
    db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01
#84ac#1d2c16
    db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20
#84bc#1d3c16
    db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #00, #1f, #60, #f0, #0a, #00, #3c
#84cc#1d4c16
    db #3f, #40, #f0, #0c, #00, #64, #3f, #40, #f0, #0c, #00, #ca, #7f, #80, #f0, #08
#84dc#1d5c16
    db #00, #da, #7f, #80, #f0, #0c, #00, #d3, #ff, #00, #fc, #03, #00, #c3, #ff, #00
#84ec#1d6c16
    db #ff, #00, #01, #e6, #ff, #00, #ff, #00, #c1, #3a, #ff, #00, #ff, #00, #f3, #0c
#84fc#1d7c2
    db #ff, #00
#84fe#1d7e
L84fe_iso_graphic_37:  ; MDL bitmap visualization
#84fe#1d7e16
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#850e#1d8e16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#851e#1d9e16
    db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c
#852e#1dae16
    db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00
#853e#1dbe16
    db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62
#854e#1dce16
    db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #60, #01, #06, #ff, #00, #00, #a3
#855e#1dde16
    db #03, #c4, #ff, #00, #00, #c6, #03, #44, #ff, #00, #00, #cc, #07, #a8, #ff, #00
#856e#1dee16
    db #00, #8d, #07, #a8, #ff, #00, #00, #cd, #0f, #30, #ff, #00, #c0, #3c, #0f, #30
#857e#1dfe16
    db #ff, #00, #f0, #0e, #1f, #60, #ff, #00, #fc, #03, #1f, #a0, #ff, #00, #ff, #00
#858e#1e0e2
    db #3f, #c0
#8590#1e10
L8590_iso_graphic_38:  ; MDL bitmap visualization
#8590#1e1016
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#85a0#1e2016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#85b0#1e3016
    db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00, #01, #c6
#85c0#1e4016
    db #ff, #00, #ff, #00, #00, #d9, #7f, #80, #fe, #01, #00, #5e, #1f, #60, #fe, #01
#85d0#1e5016
    db #00, #e7, #1f, #a0, #fc, #02, #00, #99, #1f, #a0, #fc, #03, #00, #06, #1f, #20
#85e0#1e6016
    db #f8, #05, #00, #01, #1f, #a0, #f8, #06, #00, #1c, #1f, #60, #f0, #0a, #00, #3e
#85f0#1e7016
    db #3f, #40, #f0, #0c, #00, #76, #3f, #40, #f0, #0c, #00, #7a, #7f, #80, #f0, #08
#8600#1e8016
    db #00, #7e, #7f, #80, #f0, #0c, #00, #7f, #ff, #00, #fc, #03, #00, #3d, #ff, #00
#8610#1e9016
    db #ff, #00, #01, #da, #ff, #00, #ff, #00, #81, #72, #ff, #00, #ff, #00, #f3, #0c
#8620#1ea02
    db #ff, #00
#8622#1ea2
L8622_iso_graphic_39:  ; MDL bitmap visualization
#8622#1ea216
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8632#1eb216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8642#1ec216
    db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #f8, #05, #7f, #80, #ff, #00, #f0, #0c
#8652#1ed216
    db #1f, #60, #ff, #00, #f0, #0d, #07, #98, #ff, #00, #e0, #15, #01, #e6, #ff, #00
#8662#1ee216
    db #e0, #1e, #01, #7a, #ff, #00, #c0, #29, #01, #9a, #ff, #00, #c0, #30, #01, #62
#8672#1ef216
    db #ff, #00, #80, #50, #01, #1a, #ff, #00, #80, #61, #01, #c6, #ff, #00, #00, #a3
#8682#1f0216
    db #03, #e4, #ff, #00, #00, #c7, #03, #64, #ff, #00, #00, #c7, #07, #a8, #ff, #00
#8692#1f1216
    db #00, #87, #07, #e8, #ff, #00, #00, #c7, #0f, #f0, #ff, #00, #c0, #33, #0f, #d0
#86a2#1f2216
    db #ff, #00, #f0, #0d, #1f, #a0, #ff, #00, #f8, #07, #1f, #20, #ff, #00, #ff, #00
#86b2#1f322
    db #3f, #c0
#86b4#1f34
L86b4_iso_graphic_40:  ; MDL bitmap visualization
#86b4#1f3416
    db #0b, #03, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #e3, #1c, #ff, #00, #ff, #00
#86c4#1f4416
    db #f7, #08, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #f1, #0e, #ff, #00
#86d4#1f5416
    db #ff, #00, #f0, #09, #3f, #c0, #ff, #00, #f0, #0f, #1f, #20, #ff, #00, #f0, #0f
#86e4#1f6416
    db #1f, #e0, #ff, #00, #f0, #09, #1f, #e0, #ff, #00, #f0, #0f, #1f, #20, #ff, #00
#86f4#1f744
    db #fe, #01, #1f, #e0
#86f8#1f78
L86f8_iso_graphic_41:  ; MDL bitmap visualization
#86f8#1f7816
    db #0b, #04, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #3f, #c0
#8708#1f8816
    db #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#8718#1f9816
    db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #ff, #00, #03, #9c
#8728#1fa816
    db #ff, #00, #ff, #00, #ff, #00, #01, #f2, #ff, #00, #ff, #00, #ff, #00, #01, #fe
#8738#1fb816
    db #ff, #00, #ff, #00, #ff, #00, #01, #9e, #ff, #00, #ff, #00, #ff, #00, #01, #f2
#8748#1fc810
    db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00
#8752#1fd2
L8752_iso_graphic_42:  ; MDL bitmap visualization
#8752#1fd216
    db #0b, #03, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #e3, #1c, #ff, #00, #ff, #00
#8762#1fe216
    db #f7, #08, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #f1, #0e, #ff, #00
#8772#1ff216
    db #ff, #00, #f0, #0d, #3f, #c0, #ff, #00, #f0, #0a, #1f, #a0, #ff, #00, #f0, #0d
#8782#200216
    db #1f, #60, #ff, #00, #f0, #0a, #1f, #a0, #ff, #00, #f0, #0f, #1f, #60, #ff, #00
#8792#20124
    db #fe, #01, #1f, #e0
#8796#2016
L8796_iso_graphic_43:  ; MDL bitmap visualization
#8796#201616
    db #0b, #04, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #3f, #c0
#87a6#202616
    db #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#87b6#203616
    db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #ff, #00, #03, #dc
#87c6#204616
    db #ff, #00, #ff, #00, #ff, #00, #01, #aa, #ff, #00, #ff, #00, #ff, #00, #01, #d6
#87d6#205616
    db #ff, #00, #ff, #00, #ff, #00, #01, #aa, #ff, #00, #ff, #00, #ff, #00, #01, #f6
#87e6#206610
    db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00
#87f0#2070
L87f0_iso_graphic_44:  ; MDL bitmap visualization
#87f0#207016
    db #11, #03, #ff, #00, #9f, #60, #ff, #00, #ff, #00, #87, #58, #ff, #00, #ff, #00
#8800#208016
    db #01, #86, #ff, #00, #ff, #00, #00, #b1, #7f, #80, #fe, #01, #00, #38, #1f, #60
#8810#209016
    db #fe, #01, #00, #79, #07, #18, #fc, #02, #00, #71, #07, #c8, #fc, #02, #00, #fb
#8820#20a016
    db #0f, #d0, #f8, #04, #00, #ff, #0f, #90, #f8, #05, #00, #ef, #1f, #a0, #f0, #09
#8830#20b016
    db #00, #c7, #1f, #20, #f0, #0c, #00, #4f, #3f, #40, #fc, #03, #00, #0e, #3f, #40
#8840#20c016
    db #ff, #00, #00, #c6, #7f, #80, #ff, #00, #c0, #30, #7f, #80, #ff, #00, #f0, #0d
#8850#20d08
    db #ff, #00, #ff, #00, #fc, #03, #ff, #00
#8858#20d8
L8858_iso_graphic_45:  ; MDL bitmap visualization
#8858#20d816
    db #11, #04, #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #f8, #05, #7f, #80
#8868#20e816
    db #ff, #00, #ff, #00, #f0, #08, #1f, #60, #ff, #00, #ff, #00, #f0, #0b, #07, #18
#8878#20f816
    db #ff, #00, #ff, #00, #e0, #13, #01, #86, #ff, #00, #ff, #00, #e0, #17, #00, #91
#8888#210816
    db #7f, #80, #ff, #00, #c0, #27, #00, #1c, #7f, #80, #ff, #00, #c0, #2f, #00, #bd
#8898#211816
    db #ff, #00, #ff, #00, #80, #4f, #00, #f9, #ff, #00, #ff, #00, #80, #5e, #01, #fa
#88a8#212816
    db #ff, #00, #ff, #00, #00, #9c, #01, #72, #ff, #00, #ff, #00, #00, #c4, #03, #f4
#88b8#213816
    db #ff, #00, #ff, #00, #c0, #30, #03, #e4, #ff, #00, #ff, #00, #f0, #0c, #07, #68
#88c8#214816
    db #ff, #00, #ff, #00, #fc, #03, #07, #08, #ff, #00, #ff, #00, #ff, #00, #0f, #d0
#88d8#215810
    db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00
#88e2#2162
L88e2_iso_graphic_46:  ; MDL bitmap visualization
#88e2#216216
    db #10, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#88f2#217216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03
#8902#218216
    db #3f, #c0, #fe, #01, #1f, #e0, #ff, #00, #0f, #f0, #ff, #00, #ff, #00, #ff, #00
#8912#219216
    db #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00, #f0, #0f, #ff, #00, #f8, #07
#8922#21a22
    db #7f, #80
#8924#21a4
L8924_iso_graphic_47:  ; MDL bitmap visualization
#8924#21a416
    db #10, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8934#21b416
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8944#21c416
    db #c3, #3c, #ff, #00, #e1, #1e, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00
#8954#21d416
    db #ff, #00, #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #0f, #f0, #ff, #00
#8964#21e42
    db #87, #78
#8966#21e6
L8966_iso_graphic_48:  ; MDL bitmap visualization
#8966#21e616
    db #0d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8976#21f616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00
#8986#220616
    db #ff, #00, #e7, #18, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #c7, #38
#8996#221616
    db #df, #20, #ff, #00, #cf, #30, #9f, #60, #ff, #00, #df, #20, #1f, #e0, #ff, #00
#89a6#222616
    db #ff, #00, #1f, #e0, #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #7f, #80
#89b6#2236
L89b6_iso_graphic_49:  ; MDL bitmap visualization
#89b6#223616
    db #0d, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#89c6#224616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#89d6#225616
    db #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #fc, #03
#89e6#226616
    db #7d, #82, #ff, #00, #fc, #03, #f9, #06, #ff, #00, #fd, #02, #f1, #0e, #ff, #00
#89f6#227616
    db #ff, #00, #f1, #0e, #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #f7, #08
#8a06#2286
L8a06_iso_graphic_50:  ; MDL bitmap visualization
#8a06#228616
    db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8a16#229616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00
#8a26#22a616
    db #ff, #00, #0f, #f0, #ff, #00, #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #f0, #0f
#8a36#22b616
    db #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #0f, #f0, #ff, #00
#8a46#22c616
    db #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00
#8a56#22d616
    db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00, #ff, #00, #e1, #1e, #ff, #00
#8a66#22e616
    db #ff, #00, #f8, #07, #7f, #80, #ff, #00, #fe, #01, #1f, #e0, #ff, #00, #ff, #00
#8a76#22f616
    db #87, #78, #ff, #00, #ff, #00, #e1, #1e, #ff, #00, #ff, #00, #f8, #07, #7f, #80
#8a86#23066
    db #ff, #00, #fe, #01, #7f, #80
#8a8c#230c
L8a8c_iso_graphic_51:  ; MDL bitmap visualization
#8a8c#230c16
    db #16, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8a9c#231c16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8aac#232c16
    db #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #ff, #00
#8abc#233c16
    db #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #f0
#8acc#234c16
    db #ff, #00, #ff, #00, #ff, #00, #c3, #3c, #ff, #00, #ff, #00, #ff, #00, #f0, #0f
#8adc#235c16
    db #ff, #00, #ff, #00, #ff, #00, #fc, #03, #3f, #c0, #ff, #00, #ff, #00, #ff, #00
#8aec#236c16
    db #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8afc#237c16
    db #ff, #00, #fe, #01, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #1f, #e0, #ff, #00
#8b0c#238c16
    db #ff, #00, #ff, #00, #87, #78, #ff, #00, #ff, #00, #ff, #00, #e1, #1e, #ff, #00
#8b1c#239c16
    db #ff, #00, #ff, #00, #f8, #07, #7f, #80, #ff, #00, #ff, #00, #fe, #01, #1f, #e0
#8b2c#23ac16
    db #ff, #00, #ff, #00, #ff, #00, #87, #78, #ff, #00, #ff, #00, #ff, #00, #e7, #18
#8b3c#23bc2
    db #ff, #00
#8b3e#23be
L8b3e_iso_graphic_52:  ; MDL bitmap visualization
#8b3e#23be16
    db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8b4e#23ce16
    db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #cf, #30, #ff, #00
#8b5e#23de16
    db #ff, #00, #9f, #60, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #ff, #00, #3f, #c0
#8b6e#23ee16
    db #ff, #00, #ff, #00, #3f, #c0, #f3, #0c, #fe, #01, #7f, #80, #f3, #0c, #fe, #01
#8b7e#23fe16
    db #7f, #80, #e7, #18, #fc, #03, #ff, #00, #e7, #18, #fc, #03, #ff, #00, #cf, #30
#8b8e#240e16
    db #f9, #06, #ff, #00, #cf, #30, #f9, #06, #ff, #00, #9f, #60, #f3, #0c, #ff, #00
#8b9e#241e16
    db #9f, #60, #f3, #0c, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #3f, #c0, #ff, #00
#8bae#242e16
    db #fe, #01, #7f, #80, #ff, #00, #fe, #01, #7f, #80, #ff, #00, #fc, #03, #ff, #00
#8bbe#243e6
    db #ff, #00, #fc, #03, #ff, #00
#8bc4#2444
L8bc4_iso_graphic_53:  ; MDL bitmap visualization
#8bc4#244416
    db #16, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8bd4#245416
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03, #ff, #00
#8be4#246416
    db #ff, #00, #ff, #00, #fc, #03, #ff, #00, #ff, #00, #ff, #00, #f9, #06, #ff, #00
#8bf4#247416
    db #ff, #00, #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #f3, #0c, #ff, #00
#8c04#248416
    db #ff, #00, #ff, #00, #f3, #0c, #ff, #00, #3f, #c0, #ff, #00, #e7, #18, #ff, #00
#8c14#249416
    db #3f, #c0, #ff, #00, #e7, #18, #fe, #01, #7f, #80, #ff, #00, #cf, #30, #fe, #01
#8c24#24a416
    db #7f, #80, #ff, #00, #cf, #30, #fc, #03, #ff, #00, #ff, #00, #9f, #60, #fc, #03
#8c34#24b416
    db #ff, #00, #ff, #00, #9f, #60, #f9, #06, #ff, #00, #ff, #00, #3f, #c0, #f9, #06
#8c44#24c416
    db #ff, #00, #ff, #00, #3f, #c0, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f3, #0c
#8c54#24d416
    db #ff, #00, #ff, #00, #ff, #00, #e7, #18, #ff, #00, #ff, #00, #ff, #00, #e7, #18
#8c64#24e416
    db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00, #cf, #30
#8c74#24f42
    db #ff, #00
#8c76#24f6
L8c76_iso_graphic_54:  ; MDL bitmap visualization
#8c76#24f616
    db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8c86#250616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8c96#251616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #ff, #00
#8ca6#252616
    db #ff, #00, #fb, #04, #bf, #40, #ff, #00, #fd, #02, #ef, #10, #ff, #00, #ff, #00
#8cb6#253616
    db #3b, #c4, #ff, #00, #fd, #02, #de, #21, #ff, #00, #ff, #00, #73, #8c, #bf, #40
#8cc6#254616
    db #ff, #00, #dd, #22, #ef, #10, #ff, #00, #f7, #08, #3f, #c0, #ff, #00, #fd, #02
#8cd6#25568
    db #df, #20, #ff, #00, #ff, #00, #7f, #80
#8cde#255e
L8cde_iso_graphic_55:  ; MDL bitmap visualization
#8cde#255e16
    db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8cee#256e16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8cfe#257e16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ef, #10
#8d0e#258e16
    db #ff, #00, #ff, #00, #bb, #44, #ff, #00, #ff, #00, #de, #21, #ff, #00, #ff, #00
#8d1e#259e16
    db #f3, #0c, #bf, #40, #ff, #00, #dd, #22, #ef, #10, #ff, #00, #f7, #08, #3b, #c4
#8d2e#25ae16
    db #ff, #00, #fd, #02, #de, #21, #ff, #00, #ff, #00, #73, #8c, #ff, #00, #ff, #00
#8d3e#25be8
    db #dd, #22, #ff, #00, #ff, #00, #f7, #08
#8d46#25c6
L8d46_iso_graphic_56:  ; MDL bitmap visualization
#8d46#25c616
    db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8d56#25d616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8d66#25e616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #fe, #01
#8d76#25f616
    db #bf, #40, #ff, #00, #f5, #0a, #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00
#8d86#260616
    db #eb, #14, #ff, #00, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #d7, #28, #ff, #00
#8d96#261616
    db #ff, #00, #fd, #02, #ff, #00, #ff, #00, #af, #50, #ff, #00, #ff, #00, #eb, #14
#8da6#262616
    db #ff, #00, #ff, #00, #5f, #a0, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #fe, #01
#8db6#263610
    db #bf, #40, #ff, #00, #ff, #00, #af, #50, #ff, #00
#8dc0#2640
L8dc0_iso_graphic_57:  ; MDL bitmap visualization
#8dc0#264016
    db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8dd0#265016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#8de0#266016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #af, #50, #ff, #00, #ff, #00
#8df0#267016
    db #eb, #14, #ff, #00, #ff, #00, #5f, #a0, #ff, #00, #ff, #00, #f7, #08, #ff, #00
#8e00#268016
    db #fe, #01, #bf, #40, #ff, #00, #ff, #00, #af, #50, #ff, #00, #fd, #02, #7f, #80
#8e10#269016
    db #ff, #00, #ff, #00, #df, #20, #ff, #00, #fa, #05, #ff, #00, #ff, #00, #fe, #01
#8e20#26a016
    db #bf, #40, #ff, #00, #f5, #0a, #ff, #00, #ff, #00, #ff, #00, #7f, #80, #ff, #00
#8e30#26b010
    db #eb, #14, #ff, #00, #ff, #00, #fa, #05, #ff, #00
#8e3a#26ba
#8e3a#26ba
    
#8e3a#26ba
L8e3a_iso_additional_graphic_0:  ; MDL bitmap visualization
#8e3a#26ba16
    db #1e, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00
#8e4a#26ca16
    db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #01, #a2, #ff, #00
#8e5a#26da16
    db #ff, #00, #fc, #03, #01, #8a, #ff, #00, #ff, #00, #fc, #03, #00, #c3, #cf, #30
#8e6a#26ea16
    db #ff, #00, #f8, #07, #00, #32, #43, #ac, #ff, #00, #f8, #07, #00, #0e, #00, #63
#8e7a#26fa16
    db #ff, #00, #f8, #06, #00, #02, #00, #68, #7f, #80, #f8, #06, #00, #04, #00, #62
#8e8a#270a16
    db #7f, #80, #e0, #1c, #00, #06, #00, #70, #7f, #80, #e0, #16, #00, #31, #00, #cc
#8e9a#271a16
    db #7f, #80, #c0, #37, #00, #2c, #00, #43, #7f, #80, #c0, #37, #00, #73, #00, #00
#8eaa#272a16
    db #7f, #80, #80, #76, #00, #4c, #00, #c1, #ff, #00, #80, #7e, #00, #c3, #00, #21
#8eba#273a16
    db #ff, #00, #00, #e4, #00, #80, #01, #e2, #ff, #00, #00, #e1, #00, #80, #01, #32
#8eca#274a16
    db #ff, #00, #00, #c1, #00, #08, #03, #5c, #ff, #00, #00, #c3, #00, #1c, #0b, #74
#8eda#275a16
    db #ff, #00, #00, #82, #00, #08, #0f, #b0, #ff, #00, #00, #c3, #00, #08, #0f, #d0
#8eea#276a16
    db #ff, #00, #c0, #31, #00, #c9, #0f, #70, #ff, #00, #f1, #0e, #c0, #29, #0f, #10
#8efa#277a16
    db #ff, #00, #fd, #02, #c0, #2a, #1f, #20, #ff, #00, #ff, #00, #c0, #2a, #1f, #20
#8f0a#278a16
    db #ff, #00, #ff, #00, #c0, #28, #3f, #40, #ff, #00, #ff, #00, #e0, #08, #3f, #40
#8f1a#279a16
    db #ff, #00, #ff, #00, #e0, #0b, #7f, #80, #ff, #00, #ff, #00, #e3, #08, #7f, #80
#8f2a#27aa2
    db #ff, #00
#8f2c#27ac
L8f2c_iso_additional_graphic_1:  ; MDL bitmap visualization
#8f2c#27ac16
    db #1e, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#8f3c#27bc16
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #1f, #20
#8f4c#27cc16
    db #ff, #00, #ff, #00, #c0, #38, #1f, #a0, #ff, #00, #ff, #00, #c0, #3c, #0c, #33
#8f5c#27dc16
    db #ff, #00, #ff, #00, #80, #73, #04, #2a, #3f, #c0, #ff, #00, #80, #70, #00, #e6
#8f6c#27ec16
    db #0f, #30, #ff, #00, #80, #60, #00, #26, #07, #88, #ff, #00, #80, #60, #00, #46
#8f7c#27fc16
    db #07, #28, #fe, #01, #00, #c0, #00, #67, #07, #08, #fe, #01, #00, #63, #00, #1c
#8f8c#280c16
    db #07, #c8, #fc, #03, #00, #72, #00, #c4, #07, #38, #fc, #03, #00, #77, #00, #30
#8f9c#281c16
    db #07, #08, #f8, #07, #00, #64, #00, #cc, #0f, #10, #f8, #07, #00, #ec, #00, #32
#8fac#282c16
    db #0f, #10, #f0, #0e, #00, #48, #00, #0e, #1f, #20, #f0, #0e, #00, #18, #00, #03
#8fbc#283c16
    db #1f, #20, #f0, #0c, #00, #10, #00, #85, #3f, #c0, #f0, #0c, #00, #31, #00, #c7
#8fcc#284c16
    db #bf, #40, #f0, #08, #00, #20, #00, #8b, #ff, #00, #f0, #0c, #00, #30, #00, #8d
#8fdc#285c16
    db #ff, #00, #fc, #03, #00, #1c, #00, #97, #ff, #00, #ff, #00, #1c, #e2, #00, #91
#8fec#286c16
    db #ff, #00, #ff, #00, #dc, #22, #01, #a2, #ff, #00, #ff, #00, #fc, #02, #01, #a2
#8ffc#287c16
    db #ff, #00, #ff, #00, #fc, #02, #03, #84, #ff, #00, #ff, #00, #fe, #00, #03, #84
#900c#288c16
    db #ff, #00, #ff, #00, #fe, #00, #07, #b8, #ff, #00, #ff, #00, #fe, #00, #37, #88
#901c#289c2
    db #ff, #00
#901e#289e
L901e_iso_additional_graphic_2:  ; MDL bitmap visualization
#901e#289e16
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #bf, #40, #ff, #00, #ff, #00
#902e#28ae16
    db #0f, #f0, #ff, #00, #ff, #00, #03, #fc, #ff, #00, #fe, #01, #03, #fc, #ff, #00
#903e#28be16
    db #fe, #01, #03, #fc, #ff, #00, #fc, #03, #01, #fe, #ef, #10, #fe, #01, #00, #ff
#904e#28ce16
    db #43, #bc, #ff, #00, #00, #ff, #00, #ff, #ff, #00, #00, #ff, #00, #ff, #f6, #09
#905e#28de16
    db #00, #ff, #01, #fe, #f2, #0d, #00, #ff, #01, #fe, #e0, #1f, #00, #ff, #03, #fc
#906e#28ee16
    db #e0, #1f, #00, #ff, #13, #ec, #c0, #3f, #00, #ff, #3f, #c0, #c0, #3f, #00, #ff
#907e#28fe16
    db #3f, #c0, #c0, #3f, #00, #ff, #7f, #80, #f0, #0f, #80, #7f, #3f, #c0, #fd, #02
#908e#290e16
    db #e0, #1f, #1f, #e0, #ff, #00, #f0, #0f, #1f, #e0, #ff, #00, #f0, #0f, #3f, #c0
#909e#291e16
    db #ff, #00, #f0, #0f, #3f, #c0, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00
#90ae#292e2
    db #7f, #80
#90b0#2930
L90b0_iso_additional_graphic_3:  ; MDL bitmap visualization
#90b0#293016
    db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fb, #04, #ff, #00
#90c0#294016
    db #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0
#90d0#295016
    db #ff, #00, #ff, #00, #e0, #1f, #3f, #c0, #ff, #00, #ff, #00, #e0, #1f, #3f, #c0
#90e0#296016
    db #ff, #00, #ff, #00, #c0, #3f, #1e, #e1, #ff, #00, #ff, #00, #e0, #1f, #04, #fb
#90f0#297016
    db #3f, #c0, #ff, #00, #f0, #0f, #00, #ff, #0f, #f0, #ff, #00, #f0, #0f, #00, #ff
#9100#298016
    db #0f, #f0, #ff, #00, #60, #9f, #00, #ff, #1f, #e0, #ff, #00, #20, #df, #00, #ff
#9110#299016
    db #1f, #e0, #fe, #01, #00, #ff, #00, #ff, #3f, #c0, #fe, #01, #00, #ff, #01, #fe
#9120#29a016
    db #3f, #c0, #fc, #03, #00, #ff, #03, #fc, #ff, #00, #fc, #03, #00, #ff, #03, #fc
#9130#29b016
    db #ff, #00, #fc, #03, #00, #ff, #07, #f8, #ff, #00, #ff, #00, #08, #f7, #03, #fc
#9140#29c016
    db #ff, #00, #ff, #00, #de, #21, #01, #fe, #ff, #00, #ff, #00, #ff, #00, #01, #fe
#9150#29d016
    db #ff, #00, #ff, #00, #ff, #00, #03, #fc, #ff, #00, #ff, #00, #ff, #00, #03, #fc
#9160#29e016
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#9170#29f02
    db #ff, #00
#9172#29f2
L9172_iso_additional_graphic_4:  ; MDL bitmap visualization
#9172#29f216
    db #15, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9182#2a0216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #bc, #43, #ff, #00
#9192#2a1216
    db #ff, #00, #7d, #82, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#91a2#2a2216
    db #ff, #00, #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #f7, #08, #bf, #40, #fe, #01
#91b2#2a3216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#91c2#2a4216
    db #ff, #00, #ff, #00, #bf, #40, #ff, #00, #b7, #48, #ff, #00, #ff, #00, #cf, #30
#91d2#2a5216
    db #ff, #00, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#91e2#2a6216
    db #fc, #03, #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ef, #10, #ff, #00
#91f2#2a72
L91f2_iso_additional_graphic_5:  ; MDL bitmap visualization
#91f2#2a7216
    db #16, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9202#2a8216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #c0, #ff, #00
#9212#2a9216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fe, #01, #ff, #00, #ff, #00, #ff, #00
#9222#2aa216
    db #ff, #00, #ff, #00, #97, #68, #d7, #28, #ff, #00, #cf, #30, #e7, #18, #fd, #02
#9232#2ab216
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9242#2ac216
    db #ff, #00, #ff, #00, #1f, #e0, #ff, #00, #cf, #30, #bf, #40, #ff, #00, #ff, #00
#9252#2ad216
    db #ff, #00, #f4, #0b, #ff, #00, #ff, #00, #fd, #02, #f9, #06, #7f, #80, #ff, #00
#9262#2ae216
    db #fd, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9272#2af26
    db #ff, #00, #f7, #08, #ff, #00
#9278#2af8
L9278_iso_additional_graphic_6:  ; MDL bitmap visualization
#9278#2af816
    db #15, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9288#2b0816
    db #9f, #60, #ff, #00, #ff, #00, #bf, #40, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9298#2b1816
    db #ff, #00, #ff, #00, #bf, #40, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00
#92a8#2b2816
    db #ff, #00, #ff, #00, #fa, #05, #ff, #00, #f7, #08, #f9, #06, #f7, #08, #fe, #01
#92b8#2b3816
    db #bf, #40, #ff, #00, #ff, #00, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #bf, #40
#92c8#2b4816
    db #f9, #06, #f5, #0a, #ff, #00, #fd, #02, #f9, #06, #ff, #00, #ff, #00, #ff, #00
#92d8#2b5816
    db #ff, #00, #ff, #00, #ff, #00, #cf, #30, #f7, #08, #bf, #40, #ff, #00, #ff, #00
#92e8#2b6816
    db #ff, #00, #ff, #00, #ff, #00, #fb, #04, #7f, #80, #ff, #00, #fc, #03, #ff, #00
#92f8#2b78
L92f8_iso_additional_graphic_7:  ; MDL bitmap visualization
#92f8#2b7816
    db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9308#2b8816
    db #ff, #00, #ff, #00, #ff, #00, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9318#2b9816
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #9f, #60, #ff, #00, #f8, #07, #fe, #01
#9328#2ba816
    db #7f, #80, #fd, #02, #fe, #01, #f7, #08, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9338#2bb816
    db #ff, #00, #ff, #00, #ff, #00, #d7, #28, #ff, #00, #fd, #02, #ef, #10, #9f, #60
#9348#2bc816
    db #ff, #00, #ff, #00, #df, #20, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9358#2bd816
    db #ff, #00, #fc, #03, #7f, #80, #ff, #00, #fe, #01, #f7, #08, #ff, #00, #ff, #00
#9368#2be810
    db #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #7f, #80
#9372#2bf2
L9372_iso_additional_graphic_8:  ; MDL bitmap visualization
#9372#2bf216
    db #19, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #3f, #00, #ff, #00, #ff, #00
#9382#2c0216
    db #0f, #00, #ff, #00, #fe, #00, #03, #00, #ff, #00, #fe, #00, #00, #44, #ff, #00
#9392#2c1216
    db #fe, #00, #00, #48, #7f, #80, #fe, #01, #00, #21, #6f, #00, #fe, #01, #00, #02
#93a2#2c2216
    db #07, #10, #fe, #01, #00, #12, #03, #20, #ff, #00, #00, #a4, #03, #a4, #ff, #00
#93b2#2c3216
    db #00, #88, #07, #88, #e3, #08, #80, #4a, #0f, #50, #e0, #05, #c2, #31, #5f, #a0
#93c2#2c4216
    db #c1, #12, #c3, #04, #c7, #00, #81, #48, #c0, #29, #c7, #28, #80, #51, #81, #12
#93d2#2c5216
    db #ef, #10, #c1, #26, #01, #4c, #ff, #00, #c7, #28, #00, #80, #3f, #40, #ef, #10
#93e2#2c6216
    db #80, #48, #3f, #80, #ff, #00, #c0, #25, #1f, #20, #ff, #00, #e0, #11, #3f, #40
#93f2#2c7216
    db #ff, #00, #e0, #12, #3f, #40, #ff, #00, #f0, #08, #7f, #80, #ff, #00, #f0, #0b
#9402#2c828
    db #ff, #00, #ff, #00, #fb, #04, #ff, #00
#940a#2c8a
L940a_iso_additional_graphic_9:  ; MDL bitmap visualization
#940a#2c8a16
    db #1a, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#941a#2c9a16
    db #ff, #00, #ff, #00, #ff, #00, #df, #00, #ff, #00, #ff, #00, #83, #20, #ff, #00
#942a#2caa16
    db #ff, #00, #80, #10, #ff, #00, #ff, #00, #00, #11, #1f, #00, #ff, #00, #00, #52
#943a#2cba16
    db #07, #08, #f8, #01, #00, #28, #0f, #10, #f0, #00, #00, #84, #1f, #60, #f0, #0a
#944a#2cca16
    db #00, #83, #1f, #80, #f8, #04, #00, #4c, #1f, #20, #fc, #00, #00, #30, #0f, #c0
#945a#2cda16
    db #c8, #02, #00, #03, #07, #08, #c0, #21, #00, #84, #07, #50, #e0, #10, #00, #78
#946a#2cea16
    db #0f, #20, #e0, #14, #00, #01, #0f, #00, #f0, #09, #00, #06, #1f, #20, #f0, #08
#947a#2cfa16
    db #00, #a8, #1f, #a0, #f0, #08, #00, #90, #3f, #40, #f8, #04, #00, #51, #ff, #00
#948a#2d0a16
    db #f8, #05, #01, #22, #ff, #00, #f8, #05, #03, #04, #ff, #00, #f8, #04, #03, #84
#949a#2d1a14
    db #ff, #00, #fc, #03, #87, #68, #ff, #00, #ff, #00, #ef, #10, #ff, #00
#94a8#2d28
L94a8_iso_additional_graphic_10:  ; MDL bitmap visualization
#94a8#2d2816
    db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#94b8#2d3816
    db #0f, #90, #ff, #00, #ff, #00, #03, #48, #ff, #00, #fe, #00, #00, #48, #ff, #00
#94c8#2d4816
    db #fc, #02, #00, #48, #3f, #80, #fc, #01, #00, #21, #1f, #20, #f8, #05, #00, #20
#94d8#2d5816
    db #1f, #40, #f8, #04, #00, #21, #0f, #80, #fc, #02, #00, #12, #07, #08, #fc, #02
#94e8#2d6816
    db #00, #4c, #00, #31, #fe, #01, #00, #22, #01, #42, #e4, #10, #00, #c5, #03, #8c
#94f8#2d7816
    db #f0, #0a, #00, #03, #07, #10, #f0, #09, #00, #29, #03, #04, #f8, #06, #00, #49
#9508#2d8816
    db #07, #18, #fc, #02, #00, #45, #0f, #60, #fe, #01, #00, #92, #1f, #80, #fe, #01
#9518#2d9816
    db #00, #08, #1f, #20, #fe, #01, #00, #23, #3f, #40, #ff, #00, #03, #ac, #7f, #80
#9528#2da812
    db #ff, #00, #8f, #50, #ff, #00, #ff, #00, #9f, #60, #ff, #00
#9534#2db4
L9534_iso_additional_graphic_11:  ; MDL bitmap visualization
#9534#2db416
    db #18, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #cf, #10, #ff, #00, #ff, #00
#9544#2dc416
    db #87, #28, #ff, #00, #ff, #00, #e0, #19, #ff, #00, #ff, #00, #b9, #06, #ff, #00
#9554#2dd416
    db #fc, #00, #07, #90, #8f, #40, #fc, #00, #03, #50, #c3, #24, #f8, #04, #01, #42
#9564#2de416
    db #c0, #29, #f8, #03, #00, #44, #c1, #22, #f0, #00, #00, #a4, #63, #94, #f0, #06
#9574#2df416
    db #00, #61, #e3, #14, #fe, #01, #00, #11, #f7, #08, #df, #20, #01, #92, #ff, #00
#9584#2e0416
    db #c1, #12, #83, #74, #83, #44, #80, #49, #e7, #18, #07, #28, #c0, #28, #fe, #01
#9594#2e1416
    db #07, #28, #c0, #24, #0f, #20, #0f, #90, #c0, #24, #03, #c4, #8f, #50, #e0, #11
#95a4#2e2416
    db #07, #18, #9f, #20, #e0, #10, #1a, #20, #3f, #80, #f0, #08, #30, #c3, #1f, #20
#95b4#2e3416
    db #f0, #09, #f0, #09, #3f, #40, #f9, #06, #f8, #04, #3f, #40, #ff, #00, #fc, #03
#95c4#2e442
    db #7f, #80
#95c6#2e46
L95c6_iso_additional_graphic_12:  ; MDL bitmap visualization
#95c6#2e4616
    db #14, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#95d6#2e5616
    db #f3, #0c, #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0
#95e6#2e6616
    db #ff, #00, #e0, #1f, #2f, #d0, #ff, #00, #c0, #3f, #27, #d8, #ff, #00, #c0, #3f
#95f6#2e7616
    db #2f, #d0, #ff, #00, #c0, #3f, #af, #50, #ff, #00, #c0, #3f, #9f, #60, #ff, #00
#9606#2e8616
    db #80, #7f, #9f, #60, #ff, #00, #82, #7d, #bf, #40, #ff, #00, #82, #7d, #7f, #80
#9616#2e9616
    db #ff, #00, #02, #fd, #7f, #80, #ff, #00, #2a, #d5, #ff, #00, #ff, #00, #29, #d6
#9626#2ea616
    db #ff, #00, #ff, #00, #29, #d6, #ff, #00, #ff, #00, #ab, #54, #ff, #00, #ff, #00
#9636#2eb610
    db #c3, #3c, #ff, #00, #ff, #00, #ef, #10, #ff, #00
#9640#2ec0
L9640_iso_additional_graphic_13:  ; MDL bitmap visualization
#9640#2ec016
    db #15, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9650#2ed016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9660#2ee016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9670#2ef016
    db #ff, #00, #ff, #00, #f8, #07, #7f, #80, #ff, #00, #ff, #00, #f0, #0f, #1f, #e0
#9680#2f0016
    db #ff, #00, #ff, #00, #e0, #1f, #07, #f8, #ff, #00, #ff, #00, #e0, #1f, #03, #fc
#9690#2f1016
    db #ff, #00, #ff, #00, #c8, #37, #00, #ff, #ff, #00, #ff, #00, #a8, #57, #00, #ff
#96a0#2f2016
    db #3f, #c0, #ff, #00, #aa, #55, #00, #ff, #1f, #e0, #ff, #00, #ca, #35, #00, #ff
#96b0#2f3016
    db #1f, #e0, #ff, #00, #f2, #0d, #40, #bf, #3f, #c0, #ff, #00, #fa, #05, #48, #b7
#96c0#2f4016
    db #3f, #c0, #ff, #00, #fc, #03, #4a, #b5, #7f, #80, #ff, #00, #ff, #00, #4a, #b5
#96d0#2f5016
    db #7f, #80, #ff, #00, #ff, #00, #8a, #75, #ff, #00, #ff, #00, #ff, #00, #f2, #0d
#96e0#2f6010
    db #ff, #00, #ff, #00, #ff, #00, #fd, #02, #ff, #00
#96ea#2f6a
L96ea_iso_additional_graphic_14:  ; MDL bitmap visualization
#96ea#2f6a16
    db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#96fa#2f7a16
    db #f3, #0c, #ff, #00, #ff, #00, #f0, #0f, #ff, #00, #ff, #00, #f0, #0f, #3f, #c0
#970a#2f8a16
    db #ff, #00, #e0, #1f, #2f, #d0, #ff, #00, #c0, #3f, #27, #d8, #ff, #00, #80, #7f
#971a#2f9a16
    db #2f, #d0, #ff, #00, #80, #7f, #2f, #d0, #ff, #00, #00, #ff, #1f, #e0, #ff, #00
#972a#2faa16
    db #00, #ff, #3f, #c0, #ff, #00, #00, #ff, #bf, #40, #ff, #00, #00, #ff, #bf, #40
#973a#2fba16
    db #fe, #01, #02, #fd, #bf, #40, #fc, #03, #02, #fd, #bf, #40, #fc, #03, #02, #fd
#974a#2fca16
    db #7f, #80, #f8, #07, #02, #fd, #ff, #00, #f8, #07, #09, #f6, #ff, #00, #f0, #0f
#975a#2fda16
    db #09, #f6, #ff, #00, #fc, #03, #09, #f6, #ff, #00, #ff, #00, #0b, #f4, #ff, #00
#976a#2fea12
    db #ff, #00, #c7, #38, #ff, #00, #ff, #00, #f7, #08, #ff, #00
#9776#2ff6
L9776_iso_additional_graphic_15:  ; MDL bitmap visualization
#9776#2ff616
    db #15, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9786#300616
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9796#301616
    db #ff, #00, #ff, #00, #cf, #30, #ff, #00, #ff, #00, #ff, #00, #c3, #3c, #ff, #00
#97a6#302616
    db #ff, #00, #ff, #00, #81, #7e, #ff, #00, #ff, #00, #ff, #00, #80, #7f, #1f, #e0
#97b6#303616
    db #ff, #00, #ff, #00, #00, #ff, #07, #f8, #ff, #00, #ff, #00, #00, #ff, #01, #fe
#97c6#304616
    db #ff, #00, #fe, #01, #40, #bf, #00, #ff, #ff, #00, #fe, #01, #50, #af, #00, #ff
#97d6#305616
    db #7f, #80, #fc, #03, #51, #ae, #00, #ff, #1f, #e0, #ff, #00, #51, #ae, #00, #ff
#97e6#306616
    db #1f, #e0, #ff, #00, #91, #6e, #40, #bf, #3f, #c0, #ff, #00, #e1, #1e, #50, #af
#97f6#307616
    db #3f, #c0, #ff, #00, #fe, #01, #52, #ad, #7f, #80, #ff, #00, #ff, #00, #52, #ad
#9806#308616
    db #ff, #00, #ff, #00, #ff, #00, #92, #6d, #ff, #00, #ff, #00, #ff, #00, #e2, #1d
#9816#309610
    db #ff, #00, #ff, #00, #ff, #00, #fd, #02, #ff, #00
#9820#30a0
L9820_iso_additional_graphic_16:  ; MDL bitmap visualization
#9820#30a016
    db #17, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9830#30b016
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9840#30c016
    db #ff, #00, #fc, #03, #ff, #00, #ff, #00, #f8, #07, #3f, #c0, #ff, #00, #f0, #0f
#9850#30d016
    db #1f, #e0, #ff, #00, #f0, #0f, #2f, #d0, #ff, #00, #c0, #3f, #af, #50, #ff, #00
#9860#30e016
    db #80, #7f, #9f, #60, #ff, #00, #00, #ff, #9f, #60, #ff, #00, #00, #ff, #bf, #40
#9870#30f016
    db #fe, #01, #02, #fd, #7f, #80, #fc, #03, #02, #fd, #7f, #80, #fc, #03, #02, #fd
#9880#310016
    db #7f, #80, #f8, #07, #02, #fd, #ff, #00, #f8, #07, #01, #fe, #ff, #00, #f0, #0f
#9890#311016
    db #09, #f6, #ff, #00, #fc, #03, #0b, #f4, #ff, #00, #ff, #00, #0b, #f4, #ff, #00
#98a0#312012
    db #ff, #00, #cb, #34, #ff, #00, #ff, #00, #f7, #08, #ff, #00
#98ac#312c
L98ac_iso_additional_graphic_17:  ; MDL bitmap visualization
#98ac#312c16
    db #11, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#98bc#313c16
    db #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #cf, #30, #ff, #00
#98cc#314c16
    db #ff, #00, #c1, #3e, #ff, #00, #ff, #00, #80, #7f, #ff, #00, #ff, #00, #80, #7f
#98dc#315c16
    db #3f, #c0, #ff, #00, #00, #ff, #07, #f8, #ff, #00, #80, #7f, #03, #fc, #fe, #01
#98ec#316c16
    db #a0, #5f, #03, #fc, #fe, #01, #a8, #57, #01, #fe, #fc, #03, #a9, #56, #0a, #f5
#98fc#317c16
    db #ff, #00, #29, #d6, #2a, #d5, #ff, #00, #c9, #36, #29, #d6, #ff, #00, #f1, #0e
#990c#318c8
    db #09, #f6, #ff, #00, #fe, #01, #73, #8c
#9914#3194
L9914_iso_additional_graphic_18:  ; MDL bitmap visualization
#9914#319416
    db #20, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00
#9924#31a416
    db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #83, #ff, #00
#9934#31b416
    db #ff, #00, #fc, #02, #00, #80, #3f, #c0, #ff, #00, #fc, #02, #00, #8c, #0f, #30
#9944#31c416
    db #ff, #00, #f8, #06, #00, #8c, #03, #0c, #ff, #00, #f8, #06, #00, #c0, #00, #c3
#9954#31d416
    db #ff, #00, #f0, #0b, #00, #30, #00, #c0, #7f, #80, #f0, #0b, #00, #0c, #00, #0c
#9964#31e416
    db #7f, #80, #e0, #1a, #00, #03, #00, #0c, #7f, #80, #e0, #1a, #00, #00, #00, #c0
#9974#31f416
    db #7f, #80, #c0, #2c, #00, #00, #00, #30, #7f, #80, #c0, #2c, #00, #00, #00, #0c
#9984#320416
    db #7f, #80, #80, #68, #00, #00, #00, #03, #7f, #80, #80, #68, #00, #00, #00, #00
#9994#321416
    db #7f, #80, #00, #b0, #00, #00, #00, #01, #ff, #00, #00, #b0, #00, #00, #00, #01
#99a4#322416
    db #ff, #00, #00, #a0, #00, #00, #01, #02, #ff, #00, #00, #a0, #00, #00, #01, #02
#99b4#323416
    db #ff, #00, #00, #c0, #00, #00, #03, #04, #ff, #00, #00, #c0, #00, #00, #03, #04
#99c4#324416
    db #ff, #00, #00, #80, #00, #00, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08
#99d4#325416
    db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10
#99e4#326416
    db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20
#99f4#327416
    db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40
#9a04#328416
    db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#9a14#32942
    db #ff, #00
#9a16#3296
L9a16_iso_additional_graphic_19:  ; MDL bitmap visualization
#9a16#329616
    db #20, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#9a26#32a616
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #30
#9a36#32b616
    db #ff, #00, #ff, #00, #c0, #28, #03, #0c, #ff, #00, #ff, #00, #c0, #28, #00, #c3
#9a46#32c616
    db #ff, #00, #ff, #00, #80, #68, #00, #c0, #3f, #c0, #ff, #00, #80, #6c, #00, #0c
#9a56#32d616
    db #0f, #30, #ff, #00, #00, #b3, #00, #0c, #07, #08, #ff, #00, #00, #b0, #00, #c0
#9a66#32e616
    db #07, #c8, #fe, #01, #00, #a0, #00, #30, #07, #c8, #fe, #01, #00, #a0, #00, #0c
#9a76#32f616
    db #07, #08, #fc, #02, #00, #c0, #00, #03, #07, #08, #fc, #02, #00, #c0, #00, #00
#9a86#330616
    db #07, #c8, #f8, #06, #00, #80, #00, #00, #07, #38, #f8, #06, #00, #80, #00, #00
#9a96#331616
    db #07, #08, #f0, #0b, #00, #00, #00, #00, #0f, #10, #f0, #0b, #00, #00, #00, #00
#9aa6#332616
    db #0f, #10, #f0, #0a, #00, #00, #00, #00, #1f, #20, #f0, #0a, #00, #00, #00, #00
#9ab6#333616
    db #1f, #20, #f0, #0c, #00, #00, #00, #00, #3f, #40, #f0, #0c, #00, #00, #00, #00
#9ac6#334616
    db #3f, #40, #f0, #08, #00, #00, #00, #00, #7f, #80, #f0, #0c, #00, #00, #00, #00
#9ad6#335616
    db #7f, #80, #fc, #03, #00, #00, #00, #01, #ff, #00, #ff, #00, #00, #c0, #00, #01
#9ae6#336616
    db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02
#9af6#337616
    db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4
#9b06#338616
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#9b16#33962
    db #ff, #00
#9b18#3398
L9b18_iso_additional_graphic_20:  ; MDL bitmap visualization
#9b18#339816
    db #28, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00
#9b28#33a816
    db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #03, #84, #ff, #00
#9b38#33b816
    db #ff, #00, #fc, #02, #03, #84, #ff, #00, #ff, #00, #fc, #02, #03, #84, #ef, #10
#9b48#33c816
    db #ff, #00, #f8, #06, #03, #84, #e3, #1c, #ff, #00, #f8, #06, #01, #86, #c0, #33
#9b58#33d816
    db #ff, #00, #f0, #0a, #00, #87, #40, #b0, #7f, #80, #f0, #0a, #00, #87, #00, #d0
#9b68#33e816
    db #7f, #80, #e0, #1a, #00, #83, #00, #d0, #7f, #80, #e0, #1a, #00, #90, #00, #d0
#9b78#33f816
    db #7f, #80, #c0, #2a, #00, #84, #00, #30, #7f, #80, #c0, #2a, #00, #91, #00, #00
#9b88#340816
    db #7f, #80, #80, #6a, #00, #84, #00, #40, #7f, #80, #80, #6a, #00, #c1, #00, #10
#9b98#341816
    db #7f, #80, #00, #ab, #00, #30, #00, #44, #7f, #80, #00, #ab, #00, #0c, #00, #10
#9ba8#342816
    db #7f, #80, #00, #aa, #00, #03, #00, #04, #7f, #80, #00, #aa, #00, #00, #00, #c0
#9bb8#343816
    db #7f, #80, #00, #ac, #00, #00, #00, #30, #7f, #80, #00, #ac, #00, #00, #00, #0c
#9bc8#344816
    db #7f, #80, #00, #a8, #00, #00, #00, #03, #7f, #80, #00, #a8, #00, #00, #00, #00
#9bd8#345816
    db #7f, #80, #00, #b0, #00, #00, #00, #01, #ff, #00, #00, #b0, #00, #00, #00, #01
#9be8#346816
    db #ff, #00, #00, #a0, #00, #00, #01, #02, #ff, #00, #00, #a0, #00, #00, #01, #02
#9bf8#347816
    db #ff, #00, #00, #c0, #00, #00, #03, #04, #ff, #00, #00, #c0, #00, #00, #03, #04
#9c08#348816
    db #ff, #00, #00, #80, #00, #00, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08
#9c18#349816
    db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10
#9c28#34a816
    db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20
#9c38#34b816
    db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40
#9c48#34c816
    db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#9c58#34d82
    db #ff, #00
#9c5a#34da
L9c5a_iso_additional_graphic_21:  ; MDL bitmap visualization
#9c5a#34da16
    db #28, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#9c6a#34ea16
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #3f, #40
#9c7a#34fa16
    db #ff, #00, #ff, #00, #c0, #28, #3f, #40, #ff, #00, #ff, #00, #c0, #28, #3e, #41
#9c8a#350a16
    db #ff, #00, #ff, #00, #80, #68, #3e, #41, #3f, #c0, #ff, #00, #80, #68, #1c, #63
#9c9a#351a16
    db #0f, #30, #ff, #00, #00, #a8, #04, #7b, #07, #08, #ff, #00, #00, #a8, #00, #7d
#9caa#352a16
    db #07, #08, #fe, #01, #00, #a8, #00, #3d, #07, #08, #fe, #01, #00, #a9, #00, #0d
#9cba#353a16
    db #07, #08, #fc, #02, #00, #a8, #00, #43, #07, #08, #fc, #02, #00, #a9, #00, #10
#9cca#354a16
    db #07, #08, #f8, #06, #00, #a8, #00, #44, #07, #08, #f8, #06, #00, #ac, #00, #11
#9cda#355a16
    db #07, #08, #f0, #0a, #00, #b3, #00, #04, #07, #48, #f0, #0a, #00, #b0, #00, #c1
#9cea#356a16
    db #07, #08, #f0, #0a, #00, #a0, #00, #30, #07, #48, #f0, #0a, #00, #a0, #00, #0c
#9cfa#357a16
    db #07, #08, #f0, #0a, #00, #c0, #00, #03, #07, #08, #f0, #0a, #00, #c0, #00, #00
#9d0a#358a16
    db #07, #c8, #f0, #0a, #00, #80, #00, #00, #07, #38, #f0, #0a, #00, #80, #00, #00
#9d1a#359a16
    db #07, #08, #f0, #0b, #00, #00, #00, #00, #0f, #10, #f0, #0b, #00, #00, #00, #00
#9d2a#35aa16
    db #0f, #10, #f0, #0a, #00, #00, #00, #00, #1f, #20, #f0, #0a, #00, #00, #00, #00
#9d3a#35ba16
    db #1f, #20, #f0, #0c, #00, #00, #00, #00, #3f, #40, #f0, #0c, #00, #00, #00, #00
#9d4a#35ca16
    db #3f, #40, #f0, #08, #00, #00, #00, #00, #7f, #80, #f0, #0c, #00, #00, #00, #00
#9d5a#35da16
    db #7f, #80, #fc, #03, #00, #00, #00, #01, #ff, #00, #ff, #00, #00, #c0, #00, #01
#9d6a#35ea16
    db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02
#9d7a#35fa16
    db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4
#9d8a#360a16
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#9d9a#361a2
    db #ff, #00
#9d9c#361c
L9d9c_iso_additional_graphic_22:  ; MDL bitmap visualization
#9d9c#361c16
    db #19, #03, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #0f, #b0, #ff, #00, #fe, #01
#9dac#362c16
    db #0b, #d4, #ff, #00, #fe, #01, #08, #77, #ff, #00, #ff, #00, #18, #a4, #7f, #80
#9dbc#363c16
    db #ff, #00, #bc, #43, #cf, #30, #f8, #07, #cf, #30, #c3, #2c, #f8, #05, #82, #4d
#9dcc#364c16
    db #81, #56, #f1, #0a, #83, #74, #81, #7a, #f1, #0a, #03, #9c, #c9, #36, #e1, #16
#9ddc#365c16
    db #0e, #d1, #7f, #80, #e3, #1c, #df, #20, #23, #dc, #ff, #00, #fb, #04, #e1, #16
#9dec#366c16
    db #c7, #38, #39, #c6, #c1, #2a, #87, #48, #90, #6f, #e1, #16, #8c, #73, #f0, #09
#9dfc#367c16
    db #e7, #18, #88, #56, #61, #96, #bf, #40, #c8, #35, #21, #5a, #ff, #00, #f8, #06
#9e0c#368c16
    db #73, #8c, #17, #e8, #fc, #03, #7e, #81, #0f, #30, #ff, #00, #ff, #00, #0f, #d0
#9e1c#369c16
    db #ff, #00, #c9, #36, #9f, #60, #ff, #00, #c0, #2d, #df, #20, #ff, #00, #e1, #12
#9e2c#36ac8
    db #ff, #00, #ff, #00, #f3, #0c, #ff, #00
#9e34#36b4
L9e34_iso_additional_graphic_23:  ; MDL bitmap visualization
#9e34#36b416
    db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#9e44#36c416
    db #ff, #00, #ff, #00, #f8, #07, #ff, #00, #ff, #00, #ff, #00, #f0, #0a, #3f, #c0
#9e54#36d416
    db #ff, #00, #ff, #00, #f8, #05, #33, #4c, #ff, #00, #ff, #00, #f8, #06, #61, #92
#9e64#36e416
    db #ff, #00, #ff, #00, #dc, #23, #f1, #0a, #ff, #00, #ff, #00, #ff, #00, #db, #24
#9e74#36f416
    db #9f, #60, #ff, #00, #f3, #0c, #ff, #00, #07, #d8, #ff, #00, #39, #c6, #8f, #70
#9e84#370416
    db #07, #a8, #fe, #01, #1f, #20, #87, #58, #8f, #50, #ff, #00, #33, #cc, #84, #4b
#9e94#371416
    db #df, #20, #ff, #00, #f0, #0b, #cc, #32, #7f, #80, #fc, #03, #60, #9d, #fe, #01
#9ea4#372416
    db #7f, #80, #f8, #04, #60, #97, #ff, #00, #ff, #00, #f8, #07, #e1, #1a, #e3, #1c
#9eb4#373416
    db #ff, #00, #f8, #05, #f9, #06, #c1, #2a, #ff, #00, #fd, #02, #ef, #10, #c3, #24
#9ec4#374416
    db #ff, #00, #ff, #00, #3f, #c0, #87, #58, #ff, #00, #ff, #00, #d8, #27, #9f, #60
#9ed4#375416
    db #ff, #00, #ff, #00, #fd, #02, #f9, #06, #ff, #00, #ff, #00, #ff, #00, #fd, #02
#9ee4#376416
    db #ff, #00, #ff, #00, #ff, #00, #a7, #58, #ff, #00, #ff, #00, #ff, #00, #cf, #30
#9ef4#37742
    db #ff, #00
#9ef6#3776
L9ef6_iso_additional_graphic_24:  ; MDL bitmap visualization
#9ef6#377616
    db #19, #03, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #6f, #90, #ff, #00, #ff, #00
#9f06#378616
    db #f7, #08, #ff, #00, #fe, #01, #5f, #a0, #ff, #00, #fc, #02, #47, #b8, #3f, #c0
#9f16#379616
    db #fc, #03, #c2, #2d, #3f, #40, #ff, #00, #82, #55, #6f, #90, #fd, #02, #c7, #28
#9f26#37a616
    db #fc, #03, #fc, #03, #66, #99, #3e, #c1, #f8, #04, #3f, #40, #73, #8c, #f8, #05
#9f36#37b616
    db #3f, #40, #e0, #1b, #f9, #06, #31, #ce, #e0, #15, #cf, #30, #e0, #15, #f1, #0a
#9f46#37c616
    db #ec, #13, #f0, #0b, #9b, #64, #fc, #02, #39, #c6, #8f, #50, #98, #67, #3f, #40
#9f56#37d616
    db #0f, #90, #88, #54, #3f, #c0, #1f, #a0, #9c, #62, #71, #8e, #bf, #40, #fe, #01
#9f66#37e616
    db #f0, #0b, #ff, #00, #ff, #00, #99, #66, #cf, #30, #ff, #00, #0f, #d0, #df, #20
#9f76#37f616
    db #ff, #00, #8e, #51, #7f, #80, #ff, #00, #dc, #22, #3f, #40, #ff, #00, #fc, #03
#9f86#38068
    db #3f, #40, #ff, #00, #ff, #00, #7f, #80
#9f8e#380e
L9f8e_iso_additional_graphic_25:  ; MDL bitmap visualization
#9f8e#380e16
    db #18, #04, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #fc, #03, #ff, #00
#9f9e#381e16
    db #ff, #00, #ff, #00, #fc, #02, #3f, #c0, #ff, #00, #ff, #00, #f8, #04, #7f, #80
#9fae#382e16
    db #ff, #00, #ff, #00, #f8, #07, #e3, #1c, #ff, #00, #ff, #00, #fb, #04, #c1, #2a
#9fbe#383e16
    db #ff, #00, #ff, #00, #8e, #71, #c1, #2a, #ff, #00, #ff, #00, #87, #58, #e3, #14
#9fce#384e16
    db #ff, #00, #ff, #00, #df, #20, #37, #c8, #8f, #70, #ff, #00, #ff, #00, #0e, #b1
#9fde#385e16
    db #0f, #90, #fe, #01, #79, #86, #87, #48, #9f, #60, #fe, #01, #30, #49, #cf, #30
#9fee#386e16
    db #ff, #00, #fc, #02, #11, #ae, #fc, #03, #7f, #80, #fe, #01, #3b, #44, #0c, #f2
#9ffe#387e16
    db #7f, #80, #fe, #01, #7f, #80, #0e, #91, #ff, #00, #fb, #04, #e3, #1c, #9f, #60
#a00e#388e16
    db #ff, #00, #ff, #00, #c1, #22, #b3, #4c, #ff, #00, #ff, #00, #61, #9a, #fd, #02
#a01e#389e16
    db #ff, #00, #ff, #00, #fb, #04, #ef, #10, #ff, #00, #ff, #00, #ff, #00, #c3, #2c
#a02e#38ae16
    db #ff, #00, #ff, #00, #fe, #01, #41, #b6, #ff, #00, #ff, #00, #ff, #00, #41, #aa
#a03e#38be16
    db #ff, #00, #ff, #00, #ff, #00, #c3, #34, #ff, #00, #ff, #00, #ff, #00, #e7, #18
#a04e#38ce2
    db #ff, #00
#a050#38d0
La050_iso_additional_graphic_26:  ; MDL bitmap visualization
#a050#38d016
    db #24, #02, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00, #ff, #00
#a060#38e016
    db #ff, #00, #ff, #00, #3f, #c0, #ff, #00, #0f, #f0, #fe, #01, #03, #ac, #fe, #01
#a070#38f016
    db #00, #d7, #fc, #02, #00, #ab, #fc, #03, #00, #d5, #f8, #06, #00, #ab, #f8, #05
#a080#390016
    db #00, #d5, #f8, #06, #00, #ab, #f8, #05, #00, #d5, #f8, #07, #00, #3b, #f8, #05
#a090#391016
    db #00, #0d, #f8, #06, #00, #63, #f8, #06, #01, #5a, #f8, #04, #01, #ea, #f8, #06
#a0a0#392016
    db #03, #dc, #fe, #01, #03, #ec, #ff, #00, #07, #d8, #ff, #00, #07, #e8, #ff, #00
#a0b0#393016
    db #07, #d8, #ff, #00, #07, #e8, #ff, #00, #07, #f8, #ff, #00, #07, #b8, #ff, #00
#a0c0#394016
    db #0f, #f0, #ff, #00, #cf, #30, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00
#a0d0#395016
    db #df, #20, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00, #df, #20, #ff, #00
#a0e0#39602
    db #df, #20
#a0e2#3962
La0e2_iso_additional_graphic_27:  ; MDL bitmap visualization
#a0e2#396216
    db #20, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00
#a0f2#397216
    db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #a3, #ff, #00
#a102#398216
    db #ff, #00, #fc, #03, #00, #a8, #3f, #c0, #ff, #00, #fc, #03, #00, #aa, #0f, #30
#a112#399216
    db #ff, #00, #f8, #07, #00, #8a, #03, #8c, #ff, #00, #f8, #07, #00, #c2, #00, #a3
#a122#39a216
    db #ff, #00, #f0, #0f, #00, #30, #00, #a8, #7f, #80, #f0, #0f, #00, #0c, #00, #2a
#a132#39b216
    db #7f, #80, #e0, #1e, #00, #03, #00, #0a, #7f, #80, #e0, #1e, #00, #00, #00, #c2
#a142#39c216
    db #7f, #80, #c0, #3c, #00, #00, #00, #30, #7f, #80, #c0, #3c, #00, #00, #00, #0c
#a152#39d216
    db #7f, #80, #80, #78, #00, #00, #00, #03, #7f, #80, #80, #78, #00, #10, #00, #00
#a162#39e216
    db #7f, #80, #00, #f0, #00, #10, #00, #01, #ff, #00, #00, #f0, #00, #21, #00, #01
#a172#39f216
    db #ff, #00, #00, #e0, #00, #21, #01, #02, #ff, #00, #00, #e0, #00, #42, #01, #02
#a182#3a0216
    db #ff, #00, #00, #c0, #00, #42, #03, #04, #ff, #00, #00, #c0, #00, #04, #03, #04
#a192#3a1216
    db #ff, #00, #00, #80, #00, #04, #07, #08, #ff, #00, #00, #c0, #00, #00, #07, #08
#a1a2#3a2216
    db #ff, #00, #c0, #30, #00, #00, #0f, #10, #ff, #00, #f0, #0c, #00, #00, #0f, #10
#a1b2#3a3216
    db #ff, #00, #fc, #03, #00, #00, #1f, #20, #ff, #00, #ff, #00, #00, #c0, #1f, #20
#a1c2#3a4216
    db #ff, #00, #ff, #00, #c0, #30, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40
#a1d2#3a5216
    db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#a1e2#3a622
    db #ff, #00
#a1e4#3a64
La1e4_iso_additional_graphic_28:  ; MDL bitmap visualization
#a1e4#3a6416
    db #20, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#a1f4#3a7416
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #1a, #0f, #30
#a204#3a8416
    db #ff, #00, #ff, #00, #c0, #28, #03, #8c, #ff, #00, #ff, #00, #c0, #2a, #00, #23
#a214#3a9416
    db #ff, #00, #ff, #00, #80, #68, #00, #88, #3f, #c0, #ff, #00, #80, #6c, #00, #22
#a224#3aa416
    db #0f, #30, #ff, #00, #00, #b3, #00, #08, #07, #88, #ff, #00, #00, #b0, #00, #c2
#a234#3ab416
    db #07, #28, #fe, #01, #00, #a0, #00, #30, #07, #88, #fe, #01, #00, #a0, #00, #0c
#a244#3ac416
    db #07, #28, #fc, #02, #00, #c0, #00, #03, #07, #08, #fc, #02, #00, #c3, #00, #00
#a254#3ad416
    db #07, #c8, #f8, #06, #03, #84, #00, #c0, #07, #38, #f8, #06, #03, #84, #c0, #30
#a264#3ae416
    db #07, #08, #f0, #0b, #01, #0a, #e0, #1c, #0f, #10, #f0, #0b, #00, #0d, #60, #9e
#a274#3af416
    db #0f, #10, #f0, #0a, #00, #1a, #00, #fc, #1f, #20, #f0, #0a, #00, #15, #00, #7c
#a284#3b0416
    db #1f, #20, #f0, #0c, #00, #2a, #00, #b8, #3f, #40, #f0, #0c, #00, #35, #00, #78
#a294#3b1416
    db #3f, #40, #f0, #08, #00, #0e, #00, #b0, #7f, #80, #f0, #0c, #00, #03, #00, #70
#a2a4#3b2416
    db #7f, #80, #fc, #03, #00, #00, #00, #e1, #ff, #00, #ff, #00, #00, #c0, #00, #21
#a2b4#3b3416
    db #ff, #00, #ff, #00, #c0, #30, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02
#a2c4#3b4416
    db #ff, #00, #ff, #00, #fc, #03, #03, #04, #ff, #00, #ff, #00, #ff, #00, #03, #c4
#a2d4#3b5416
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#a2e4#3b642
    db #ff, #00
#a2e6#3b66
La2e6_iso_additional_graphic_29:  ; MDL bitmap visualization
#a2e6#3b6616
    db #28, #04, #ff, #00, #3f, #c0, #ff, #00, #ff, #00, #ff, #00, #0f, #b0, #ff, #00
#a2f6#3b7616
    db #ff, #00, #fe, #01, #03, #8c, #ff, #00, #ff, #00, #fe, #01, #00, #a3, #ff, #00
#a306#3b8616
    db #ff, #00, #fc, #02, #00, #a8, #3f, #c0, #ff, #00, #fc, #02, #00, #aa, #0f, #30
#a316#3b9616
    db #ff, #00, #f8, #04, #00, #aa, #03, #8c, #ff, #00, #f8, #04, #00, #ae, #00, #a3
#a326#3ba616
    db #ff, #00, #f0, #08, #00, #a9, #00, #a8, #7f, #80, #f0, #0a, #00, #a8, #00, #6a
#a336#3bb616
    db #7f, #80, #e0, #12, #00, #a8, #00, #1a, #7f, #80, #e0, #12, #00, #a8, #00, #0a
#a346#3bc616
    db #7f, #80, #c0, #22, #00, #ac, #00, #1a, #7f, #80, #c0, #2a, #00, #ab, #00, #3a
#a356#3bd616
    db #7f, #80, #80, #4a, #00, #8a, #00, #fa, #7f, #80, #80, #48, #00, #c2, #00, #ba
#a366#3be616
    db #7f, #80, #00, #89, #00, #30, #00, #aa, #7f, #80, #00, #a9, #00, #0c, #00, #2a
#a376#3bf616
    db #7f, #80, #00, #aa, #00, #43, #00, #0a, #7f, #80, #00, #a2, #00, #10, #00, #c2
#a386#3c0616
    db #7f, #80, #00, #a4, #00, #84, #00, #30, #7f, #80, #00, #a4, #00, #21, #00, #0c
#a396#3c1616
    db #7f, #80, #00, #a9, #00, #08, #00, #43, #7f, #80, #00, #88, #00, #42, #00, #10
#a3a6#3c2616
    db #7f, #80, #00, #92, #00, #10, #00, #85, #ff, #00, #00, #90, #00, #84, #00, #21
#a3b6#3c3616
    db #ff, #00, #00, #a4, #00, #21, #01, #0a, #ff, #00, #00, #a1, #00, #08, #01, #42
#a3c6#3c4616
    db #ff, #00, #00, #c8, #00, #42, #03, #14, #ff, #00, #00, #c2, #00, #10, #03, #84
#a3d6#3c5616
    db #ff, #00, #00, #90, #00, #84, #07, #28, #ff, #00, #00, #c4, #00, #21, #07, #08
#a3e6#3c6616
    db #ff, #00, #c0, #31, #00, #08, #0f, #50, #ff, #00, #f0, #0c, #00, #42, #0f, #10
#a3f6#3c7616
    db #ff, #00, #fc, #03, #00, #10, #1f, #a0, #ff, #00, #ff, #00, #00, #c4, #1f, #20
#a406#3c8616
    db #ff, #00, #ff, #00, #c0, #31, #3f, #40, #ff, #00, #ff, #00, #f0, #0c, #3f, #40
#a416#3c9616
    db #ff, #00, #ff, #00, #fc, #03, #7f, #80, #ff, #00, #ff, #00, #ff, #00, #7f, #80
#a426#3ca62
    db #ff, #00
#a428#3ca8
La428_iso_additional_graphic_30:  ; MDL bitmap visualization
#a428#3ca816
    db #28, #04, #ff, #00, #f3, #0c, #ff, #00, #ff, #00, #ff, #00, #f0, #0b, #ff, #00
#a438#3cb816
    db #ff, #00, #ff, #00, #e0, #18, #3f, #c0, #ff, #00, #ff, #00, #e0, #18, #0f, #30
#a448#3cc816
    db #ff, #00, #ff, #00, #c0, #2a, #03, #0c, #ff, #00, #ff, #00, #c0, #28, #00, #83
#a458#3cd816
    db #ff, #00, #ff, #00, #80, #4a, #00, #08, #3f, #c0, #ff, #00, #80, #58, #00, #a8
#a468#3ce816
    db #0f, #30, #ff, #00, #00, #d8, #00, #28, #07, #08, #ff, #00, #00, #c8, #00, #22
#a478#3cf816
    db #07, #88, #fe, #01, #00, #ca, #00, #0a, #07, #28, #fe, #01, #00, #c8, #00, #aa
#a488#3d0816
    db #07, #88, #fc, #03, #00, #ca, #00, #28, #07, #28, #fc, #03, #00, #88, #00, #a2
#a498#3d1816
    db #07, #08, #f8, #05, #00, #a8, #00, #0a, #07, #08, #f8, #05, #00, #0c, #00, #0a
#a4a8#3d2816
    db #07, #88, #f0, #09, #00, #53, #00, #08, #07, #28, #f0, #08, #00, #10, #00, #c0
#a4b8#3d3816
    db #07, #88, #f0, #08, #00, #a4, #00, #30, #07, #28, #f0, #0c, #00, #20, #00, #0c
#a4c8#3d4816
    db #07, #08, #f0, #0d, #00, #40, #00, #43, #07, #08, #f0, #08, #00, #42, #00, #00
#a4d8#3d5816
    db #07, #c8, #f0, #0a, #00, #90, #00, #04, #07, #38, #f0, #08, #00, #80, #00, #00
#a4e8#3d6816
    db #07, #08, #f0, #09, #00, #01, #00, #00, #0f, #50, #f0, #09, #00, #00, #00, #02
#a4f8#3d7816
    db #0f, #10, #f0, #0a, #00, #42, #00, #10, #1f, #20, #f0, #0a, #00, #00, #00, #00
#a508#3d8816
    db #1f, #20, #f0, #0c, #00, #04, #00, #21, #3f, #40, #f0, #0c, #00, #20, #00, #00
#a518#3d9816
    db #3f, #40, #f0, #09, #00, #00, #00, #40, #7f, #80, #f0, #0c, #00, #00, #00, #00
#a528#3da816
    db #7f, #80, #fc, #03, #00, #10, #00, #05, #ff, #00, #ff, #00, #00, #c0, #00, #21
#a538#3db816
    db #ff, #00, #ff, #00, #c0, #31, #01, #02, #ff, #00, #ff, #00, #f0, #0c, #01, #02
#a548#3dc816
    db #ff, #00, #ff, #00, #fc, #03, #03, #14, #ff, #00, #ff, #00, #ff, #00, #03, #c4
#a558#3dd816
    db #ff, #00, #ff, #00, #ff, #00, #c7, #38, #ff, #00, #ff, #00, #ff, #00, #f7, #08
#a568#3de82
    db #ff, #00
+ + diff --git a/netherearth-annotated.html-assets/img0.png b/netherearth-annotated.html-assets/img0.png new file mode 100644 index 0000000..7a99359 Binary files /dev/null and b/netherearth-annotated.html-assets/img0.png differ diff --git a/netherearth-annotated.html-assets/img1.png b/netherearth-annotated.html-assets/img1.png new file mode 100644 index 0000000..1e18fa2 Binary files /dev/null and b/netherearth-annotated.html-assets/img1.png differ diff --git a/netherearth-annotated.html-assets/img10.png b/netherearth-annotated.html-assets/img10.png new file mode 100644 index 0000000..2f209a4 Binary files /dev/null and b/netherearth-annotated.html-assets/img10.png differ diff --git a/netherearth-annotated.html-assets/img100.png b/netherearth-annotated.html-assets/img100.png new file mode 100644 index 0000000..1750eff Binary files /dev/null and b/netherearth-annotated.html-assets/img100.png differ diff --git a/netherearth-annotated.html-assets/img101.png b/netherearth-annotated.html-assets/img101.png new file mode 100644 index 0000000..bc96bce Binary files /dev/null and b/netherearth-annotated.html-assets/img101.png differ diff --git a/netherearth-annotated.html-assets/img102.png b/netherearth-annotated.html-assets/img102.png new file mode 100644 index 0000000..b842385 Binary files /dev/null and b/netherearth-annotated.html-assets/img102.png differ diff --git a/netherearth-annotated.html-assets/img103.png b/netherearth-annotated.html-assets/img103.png new file mode 100644 index 0000000..3c3aebf Binary files /dev/null and b/netherearth-annotated.html-assets/img103.png differ diff --git a/netherearth-annotated.html-assets/img104.png b/netherearth-annotated.html-assets/img104.png new file mode 100644 index 0000000..37f99ea Binary files /dev/null and b/netherearth-annotated.html-assets/img104.png differ diff --git a/netherearth-annotated.html-assets/img105.png b/netherearth-annotated.html-assets/img105.png new file mode 100644 index 0000000..1d8bb9b Binary files /dev/null and b/netherearth-annotated.html-assets/img105.png differ diff --git a/netherearth-annotated.html-assets/img106.png b/netherearth-annotated.html-assets/img106.png new file mode 100644 index 0000000..79e573a Binary files /dev/null and b/netherearth-annotated.html-assets/img106.png differ diff --git a/netherearth-annotated.html-assets/img107.png b/netherearth-annotated.html-assets/img107.png new file mode 100644 index 0000000..6a94160 Binary files /dev/null and b/netherearth-annotated.html-assets/img107.png differ diff --git a/netherearth-annotated.html-assets/img108.png b/netherearth-annotated.html-assets/img108.png new file mode 100644 index 0000000..35732fc Binary files /dev/null and b/netherearth-annotated.html-assets/img108.png differ diff --git a/netherearth-annotated.html-assets/img109.png b/netherearth-annotated.html-assets/img109.png new file mode 100644 index 0000000..dd9dd58 Binary files /dev/null and b/netherearth-annotated.html-assets/img109.png differ diff --git a/netherearth-annotated.html-assets/img11.png b/netherearth-annotated.html-assets/img11.png new file mode 100644 index 0000000..e67d413 Binary files /dev/null and b/netherearth-annotated.html-assets/img11.png differ diff --git a/netherearth-annotated.html-assets/img110.png b/netherearth-annotated.html-assets/img110.png new file mode 100644 index 0000000..a7acd96 Binary files /dev/null and b/netherearth-annotated.html-assets/img110.png differ diff --git a/netherearth-annotated.html-assets/img111.png b/netherearth-annotated.html-assets/img111.png new file mode 100644 index 0000000..1835e34 Binary files /dev/null and b/netherearth-annotated.html-assets/img111.png differ diff --git a/netherearth-annotated.html-assets/img112.png b/netherearth-annotated.html-assets/img112.png new file mode 100644 index 0000000..860a698 Binary files /dev/null and b/netherearth-annotated.html-assets/img112.png differ diff --git a/netherearth-annotated.html-assets/img113.png b/netherearth-annotated.html-assets/img113.png new file mode 100644 index 0000000..d63872f Binary files /dev/null and b/netherearth-annotated.html-assets/img113.png differ diff --git a/netherearth-annotated.html-assets/img114.png b/netherearth-annotated.html-assets/img114.png new file mode 100644 index 0000000..193da95 Binary files /dev/null and b/netherearth-annotated.html-assets/img114.png differ diff --git a/netherearth-annotated.html-assets/img115.png b/netherearth-annotated.html-assets/img115.png new file mode 100644 index 0000000..566d5c3 Binary files /dev/null and b/netherearth-annotated.html-assets/img115.png differ diff --git a/netherearth-annotated.html-assets/img116.png b/netherearth-annotated.html-assets/img116.png new file mode 100644 index 0000000..4a80e96 Binary files /dev/null and b/netherearth-annotated.html-assets/img116.png differ diff --git a/netherearth-annotated.html-assets/img117.png b/netherearth-annotated.html-assets/img117.png new file mode 100644 index 0000000..e70be6e Binary files /dev/null and b/netherearth-annotated.html-assets/img117.png differ diff --git a/netherearth-annotated.html-assets/img118.png b/netherearth-annotated.html-assets/img118.png new file mode 100644 index 0000000..dcdf81b Binary files /dev/null and b/netherearth-annotated.html-assets/img118.png differ diff --git a/netherearth-annotated.html-assets/img119.png b/netherearth-annotated.html-assets/img119.png new file mode 100644 index 0000000..3844ec8 Binary files /dev/null and b/netherearth-annotated.html-assets/img119.png differ diff --git a/netherearth-annotated.html-assets/img12.png b/netherearth-annotated.html-assets/img12.png new file mode 100644 index 0000000..2b3f260 Binary files /dev/null and b/netherearth-annotated.html-assets/img12.png differ diff --git a/netherearth-annotated.html-assets/img120.png b/netherearth-annotated.html-assets/img120.png new file mode 100644 index 0000000..ad068ff Binary files /dev/null and b/netherearth-annotated.html-assets/img120.png differ diff --git a/netherearth-annotated.html-assets/img121.png b/netherearth-annotated.html-assets/img121.png new file mode 100644 index 0000000..2e34683 Binary files /dev/null and b/netherearth-annotated.html-assets/img121.png differ diff --git a/netherearth-annotated.html-assets/img122.png b/netherearth-annotated.html-assets/img122.png new file mode 100644 index 0000000..e3c4bd1 Binary files /dev/null and b/netherearth-annotated.html-assets/img122.png differ diff --git a/netherearth-annotated.html-assets/img123.png b/netherearth-annotated.html-assets/img123.png new file mode 100644 index 0000000..ba1a7cc Binary files /dev/null and b/netherearth-annotated.html-assets/img123.png differ diff --git a/netherearth-annotated.html-assets/img124.png b/netherearth-annotated.html-assets/img124.png new file mode 100644 index 0000000..5122624 Binary files /dev/null and b/netherearth-annotated.html-assets/img124.png differ diff --git a/netherearth-annotated.html-assets/img125.png b/netherearth-annotated.html-assets/img125.png new file mode 100644 index 0000000..d3e09aa Binary files /dev/null and b/netherearth-annotated.html-assets/img125.png differ diff --git a/netherearth-annotated.html-assets/img126.png b/netherearth-annotated.html-assets/img126.png new file mode 100644 index 0000000..09f33ca Binary files /dev/null and b/netherearth-annotated.html-assets/img126.png differ diff --git a/netherearth-annotated.html-assets/img127.png b/netherearth-annotated.html-assets/img127.png new file mode 100644 index 0000000..d46deaf Binary files /dev/null and b/netherearth-annotated.html-assets/img127.png differ diff --git a/netherearth-annotated.html-assets/img128.png b/netherearth-annotated.html-assets/img128.png new file mode 100644 index 0000000..725c4b8 Binary files /dev/null and b/netherearth-annotated.html-assets/img128.png differ diff --git a/netherearth-annotated.html-assets/img129.png b/netherearth-annotated.html-assets/img129.png new file mode 100644 index 0000000..2eb6d52 Binary files /dev/null and b/netherearth-annotated.html-assets/img129.png differ diff --git a/netherearth-annotated.html-assets/img13.png b/netherearth-annotated.html-assets/img13.png new file mode 100644 index 0000000..02326c4 Binary files /dev/null and b/netherearth-annotated.html-assets/img13.png differ diff --git a/netherearth-annotated.html-assets/img130.png b/netherearth-annotated.html-assets/img130.png new file mode 100644 index 0000000..5acc0fc Binary files /dev/null and b/netherearth-annotated.html-assets/img130.png differ diff --git a/netherearth-annotated.html-assets/img131.png b/netherearth-annotated.html-assets/img131.png new file mode 100644 index 0000000..86658fd Binary files /dev/null and b/netherearth-annotated.html-assets/img131.png differ diff --git a/netherearth-annotated.html-assets/img132.png b/netherearth-annotated.html-assets/img132.png new file mode 100644 index 0000000..6edf3f4 Binary files /dev/null and b/netherearth-annotated.html-assets/img132.png differ diff --git a/netherearth-annotated.html-assets/img133.png b/netherearth-annotated.html-assets/img133.png new file mode 100644 index 0000000..383a6b3 Binary files /dev/null and b/netherearth-annotated.html-assets/img133.png differ diff --git a/netherearth-annotated.html-assets/img134.png b/netherearth-annotated.html-assets/img134.png new file mode 100644 index 0000000..1830e84 Binary files /dev/null and b/netherearth-annotated.html-assets/img134.png differ diff --git a/netherearth-annotated.html-assets/img135.png b/netherearth-annotated.html-assets/img135.png new file mode 100644 index 0000000..82471ed Binary files /dev/null and b/netherearth-annotated.html-assets/img135.png differ diff --git a/netherearth-annotated.html-assets/img136.png b/netherearth-annotated.html-assets/img136.png new file mode 100644 index 0000000..5e269df Binary files /dev/null and b/netherearth-annotated.html-assets/img136.png differ diff --git a/netherearth-annotated.html-assets/img137.png b/netherearth-annotated.html-assets/img137.png new file mode 100644 index 0000000..eb530cf Binary files /dev/null and b/netherearth-annotated.html-assets/img137.png differ diff --git a/netherearth-annotated.html-assets/img138.png b/netherearth-annotated.html-assets/img138.png new file mode 100644 index 0000000..a93be99 Binary files /dev/null and b/netherearth-annotated.html-assets/img138.png differ diff --git a/netherearth-annotated.html-assets/img139.png b/netherearth-annotated.html-assets/img139.png new file mode 100644 index 0000000..d3473b1 Binary files /dev/null and b/netherearth-annotated.html-assets/img139.png differ diff --git a/netherearth-annotated.html-assets/img14.png b/netherearth-annotated.html-assets/img14.png new file mode 100644 index 0000000..8960d2c Binary files /dev/null and b/netherearth-annotated.html-assets/img14.png differ diff --git a/netherearth-annotated.html-assets/img140.png b/netherearth-annotated.html-assets/img140.png new file mode 100644 index 0000000..9defe12 Binary files /dev/null and b/netherearth-annotated.html-assets/img140.png differ diff --git a/netherearth-annotated.html-assets/img141.png b/netherearth-annotated.html-assets/img141.png new file mode 100644 index 0000000..21aa5b0 Binary files /dev/null and b/netherearth-annotated.html-assets/img141.png differ diff --git a/netherearth-annotated.html-assets/img142.png b/netherearth-annotated.html-assets/img142.png new file mode 100644 index 0000000..de812d9 Binary files /dev/null and b/netherearth-annotated.html-assets/img142.png differ diff --git a/netherearth-annotated.html-assets/img143.png b/netherearth-annotated.html-assets/img143.png new file mode 100644 index 0000000..bb56bd7 Binary files /dev/null and b/netherearth-annotated.html-assets/img143.png differ diff --git a/netherearth-annotated.html-assets/img144.png b/netherearth-annotated.html-assets/img144.png new file mode 100644 index 0000000..2ba14ee Binary files /dev/null and b/netherearth-annotated.html-assets/img144.png differ diff --git a/netherearth-annotated.html-assets/img145.png b/netherearth-annotated.html-assets/img145.png new file mode 100644 index 0000000..b4e71e1 Binary files /dev/null and b/netherearth-annotated.html-assets/img145.png differ diff --git a/netherearth-annotated.html-assets/img146.png b/netherearth-annotated.html-assets/img146.png new file mode 100644 index 0000000..f5cc901 Binary files /dev/null and b/netherearth-annotated.html-assets/img146.png differ diff --git a/netherearth-annotated.html-assets/img147.png b/netherearth-annotated.html-assets/img147.png new file mode 100644 index 0000000..4651907 Binary files /dev/null and b/netherearth-annotated.html-assets/img147.png differ diff --git a/netherearth-annotated.html-assets/img148.png b/netherearth-annotated.html-assets/img148.png new file mode 100644 index 0000000..9bb9788 Binary files /dev/null and b/netherearth-annotated.html-assets/img148.png differ diff --git a/netherearth-annotated.html-assets/img149.png b/netherearth-annotated.html-assets/img149.png new file mode 100644 index 0000000..1d021cb Binary files /dev/null and b/netherearth-annotated.html-assets/img149.png differ diff --git a/netherearth-annotated.html-assets/img15.png b/netherearth-annotated.html-assets/img15.png new file mode 100644 index 0000000..b72ceb9 Binary files /dev/null and b/netherearth-annotated.html-assets/img15.png differ diff --git a/netherearth-annotated.html-assets/img150.png b/netherearth-annotated.html-assets/img150.png new file mode 100644 index 0000000..d79a95d Binary files /dev/null and b/netherearth-annotated.html-assets/img150.png differ diff --git a/netherearth-annotated.html-assets/img151.png b/netherearth-annotated.html-assets/img151.png new file mode 100644 index 0000000..9a135b0 Binary files /dev/null and b/netherearth-annotated.html-assets/img151.png differ diff --git a/netherearth-annotated.html-assets/img152.png b/netherearth-annotated.html-assets/img152.png new file mode 100644 index 0000000..8e767fc Binary files /dev/null and b/netherearth-annotated.html-assets/img152.png differ diff --git a/netherearth-annotated.html-assets/img153.png b/netherearth-annotated.html-assets/img153.png new file mode 100644 index 0000000..048cf62 Binary files /dev/null and b/netherearth-annotated.html-assets/img153.png differ diff --git a/netherearth-annotated.html-assets/img16.png b/netherearth-annotated.html-assets/img16.png new file mode 100644 index 0000000..e2401c5 Binary files /dev/null and b/netherearth-annotated.html-assets/img16.png differ diff --git a/netherearth-annotated.html-assets/img17.png b/netherearth-annotated.html-assets/img17.png new file mode 100644 index 0000000..745f0db Binary files /dev/null and b/netherearth-annotated.html-assets/img17.png differ diff --git a/netherearth-annotated.html-assets/img18.png b/netherearth-annotated.html-assets/img18.png new file mode 100644 index 0000000..b33072b Binary files /dev/null and b/netherearth-annotated.html-assets/img18.png differ diff --git a/netherearth-annotated.html-assets/img19.png b/netherearth-annotated.html-assets/img19.png new file mode 100644 index 0000000..c8bb7c2 Binary files /dev/null and b/netherearth-annotated.html-assets/img19.png differ diff --git a/netherearth-annotated.html-assets/img2.png b/netherearth-annotated.html-assets/img2.png new file mode 100644 index 0000000..05d9e9c Binary files /dev/null and b/netherearth-annotated.html-assets/img2.png differ diff --git a/netherearth-annotated.html-assets/img20.png b/netherearth-annotated.html-assets/img20.png new file mode 100644 index 0000000..fc20dc4 Binary files /dev/null and b/netherearth-annotated.html-assets/img20.png differ diff --git a/netherearth-annotated.html-assets/img21.png b/netherearth-annotated.html-assets/img21.png new file mode 100644 index 0000000..7e05e9e Binary files /dev/null and b/netherearth-annotated.html-assets/img21.png differ diff --git a/netherearth-annotated.html-assets/img22.png b/netherearth-annotated.html-assets/img22.png new file mode 100644 index 0000000..fd820e2 Binary files /dev/null and b/netherearth-annotated.html-assets/img22.png differ diff --git a/netherearth-annotated.html-assets/img23.png b/netherearth-annotated.html-assets/img23.png new file mode 100644 index 0000000..b8238dc Binary files /dev/null and b/netherearth-annotated.html-assets/img23.png differ diff --git a/netherearth-annotated.html-assets/img24.png b/netherearth-annotated.html-assets/img24.png new file mode 100644 index 0000000..bf1dd60 Binary files /dev/null and b/netherearth-annotated.html-assets/img24.png differ diff --git a/netherearth-annotated.html-assets/img25.png b/netherearth-annotated.html-assets/img25.png new file mode 100644 index 0000000..92bdfb9 Binary files /dev/null and b/netherearth-annotated.html-assets/img25.png differ diff --git a/netherearth-annotated.html-assets/img26.png b/netherearth-annotated.html-assets/img26.png new file mode 100644 index 0000000..d4c23e0 Binary files /dev/null and b/netherearth-annotated.html-assets/img26.png differ diff --git a/netherearth-annotated.html-assets/img27.png b/netherearth-annotated.html-assets/img27.png new file mode 100644 index 0000000..1052813 Binary files /dev/null and b/netherearth-annotated.html-assets/img27.png differ diff --git a/netherearth-annotated.html-assets/img28.png b/netherearth-annotated.html-assets/img28.png new file mode 100644 index 0000000..48b1bd2 Binary files /dev/null and b/netherearth-annotated.html-assets/img28.png differ diff --git a/netherearth-annotated.html-assets/img29.png b/netherearth-annotated.html-assets/img29.png new file mode 100644 index 0000000..6db0108 Binary files /dev/null and b/netherearth-annotated.html-assets/img29.png differ diff --git a/netherearth-annotated.html-assets/img3.png b/netherearth-annotated.html-assets/img3.png new file mode 100644 index 0000000..4047330 Binary files /dev/null and b/netherearth-annotated.html-assets/img3.png differ diff --git a/netherearth-annotated.html-assets/img30.png b/netherearth-annotated.html-assets/img30.png new file mode 100644 index 0000000..e8485f7 Binary files /dev/null and b/netherearth-annotated.html-assets/img30.png differ diff --git a/netherearth-annotated.html-assets/img31.png b/netherearth-annotated.html-assets/img31.png new file mode 100644 index 0000000..e8755a8 Binary files /dev/null and b/netherearth-annotated.html-assets/img31.png differ diff --git a/netherearth-annotated.html-assets/img32.png b/netherearth-annotated.html-assets/img32.png new file mode 100644 index 0000000..4406584 Binary files /dev/null and b/netherearth-annotated.html-assets/img32.png differ diff --git a/netherearth-annotated.html-assets/img33.png b/netherearth-annotated.html-assets/img33.png new file mode 100644 index 0000000..d28f87f Binary files /dev/null and b/netherearth-annotated.html-assets/img33.png differ diff --git a/netherearth-annotated.html-assets/img34.png b/netherearth-annotated.html-assets/img34.png new file mode 100644 index 0000000..91e7cfa Binary files /dev/null and b/netherearth-annotated.html-assets/img34.png differ diff --git a/netherearth-annotated.html-assets/img35.png b/netherearth-annotated.html-assets/img35.png new file mode 100644 index 0000000..4c0c852 Binary files /dev/null and b/netherearth-annotated.html-assets/img35.png differ diff --git a/netherearth-annotated.html-assets/img36.png b/netherearth-annotated.html-assets/img36.png new file mode 100644 index 0000000..04bce30 Binary files /dev/null and b/netherearth-annotated.html-assets/img36.png differ diff --git a/netherearth-annotated.html-assets/img37.png b/netherearth-annotated.html-assets/img37.png new file mode 100644 index 0000000..4a84bd7 Binary files /dev/null and b/netherearth-annotated.html-assets/img37.png differ diff --git a/netherearth-annotated.html-assets/img38.png b/netherearth-annotated.html-assets/img38.png new file mode 100644 index 0000000..5a67d4e Binary files /dev/null and b/netherearth-annotated.html-assets/img38.png differ diff --git a/netherearth-annotated.html-assets/img39.png b/netherearth-annotated.html-assets/img39.png new file mode 100644 index 0000000..4c267f0 Binary files /dev/null and b/netherearth-annotated.html-assets/img39.png differ diff --git a/netherearth-annotated.html-assets/img4.png b/netherearth-annotated.html-assets/img4.png new file mode 100644 index 0000000..d1b31be Binary files /dev/null and b/netherearth-annotated.html-assets/img4.png differ diff --git a/netherearth-annotated.html-assets/img40.png b/netherearth-annotated.html-assets/img40.png new file mode 100644 index 0000000..55eecc3 Binary files /dev/null and b/netherearth-annotated.html-assets/img40.png differ diff --git a/netherearth-annotated.html-assets/img41.png b/netherearth-annotated.html-assets/img41.png new file mode 100644 index 0000000..7d316cb Binary files /dev/null and b/netherearth-annotated.html-assets/img41.png differ diff --git a/netherearth-annotated.html-assets/img42.png b/netherearth-annotated.html-assets/img42.png new file mode 100644 index 0000000..5436d78 Binary files /dev/null and b/netherearth-annotated.html-assets/img42.png differ diff --git a/netherearth-annotated.html-assets/img43.png b/netherearth-annotated.html-assets/img43.png new file mode 100644 index 0000000..f8f634f Binary files /dev/null and b/netherearth-annotated.html-assets/img43.png differ diff --git a/netherearth-annotated.html-assets/img44.png b/netherearth-annotated.html-assets/img44.png new file mode 100644 index 0000000..0a1f0c2 Binary files /dev/null and b/netherearth-annotated.html-assets/img44.png differ diff --git a/netherearth-annotated.html-assets/img45.png b/netherearth-annotated.html-assets/img45.png new file mode 100644 index 0000000..abaa842 Binary files /dev/null and b/netherearth-annotated.html-assets/img45.png differ diff --git a/netherearth-annotated.html-assets/img46.png b/netherearth-annotated.html-assets/img46.png new file mode 100644 index 0000000..07ba3b1 Binary files /dev/null and b/netherearth-annotated.html-assets/img46.png differ diff --git a/netherearth-annotated.html-assets/img47.png b/netherearth-annotated.html-assets/img47.png new file mode 100644 index 0000000..90687b8 Binary files /dev/null and b/netherearth-annotated.html-assets/img47.png differ diff --git a/netherearth-annotated.html-assets/img48.png b/netherearth-annotated.html-assets/img48.png new file mode 100644 index 0000000..0f98b8e Binary files /dev/null and b/netherearth-annotated.html-assets/img48.png differ diff --git a/netherearth-annotated.html-assets/img49.png b/netherearth-annotated.html-assets/img49.png new file mode 100644 index 0000000..7e3654d Binary files /dev/null and b/netherearth-annotated.html-assets/img49.png differ diff --git a/netherearth-annotated.html-assets/img5.png b/netherearth-annotated.html-assets/img5.png new file mode 100644 index 0000000..2ab8dbe Binary files /dev/null and b/netherearth-annotated.html-assets/img5.png differ diff --git a/netherearth-annotated.html-assets/img50.png b/netherearth-annotated.html-assets/img50.png new file mode 100644 index 0000000..edab63b Binary files /dev/null and b/netherearth-annotated.html-assets/img50.png differ diff --git a/netherearth-annotated.html-assets/img51.png b/netherearth-annotated.html-assets/img51.png new file mode 100644 index 0000000..1b3f41b Binary files /dev/null and b/netherearth-annotated.html-assets/img51.png differ diff --git a/netherearth-annotated.html-assets/img52.png b/netherearth-annotated.html-assets/img52.png new file mode 100644 index 0000000..fbce76d Binary files /dev/null and b/netherearth-annotated.html-assets/img52.png differ diff --git a/netherearth-annotated.html-assets/img53.png b/netherearth-annotated.html-assets/img53.png new file mode 100644 index 0000000..4a9025b Binary files /dev/null and b/netherearth-annotated.html-assets/img53.png differ diff --git a/netherearth-annotated.html-assets/img54.png b/netherearth-annotated.html-assets/img54.png new file mode 100644 index 0000000..de8e283 Binary files /dev/null and b/netherearth-annotated.html-assets/img54.png differ diff --git a/netherearth-annotated.html-assets/img55.png b/netherearth-annotated.html-assets/img55.png new file mode 100644 index 0000000..dcac464 Binary files /dev/null and b/netherearth-annotated.html-assets/img55.png differ diff --git a/netherearth-annotated.html-assets/img56.png b/netherearth-annotated.html-assets/img56.png new file mode 100644 index 0000000..a99acc6 Binary files /dev/null and b/netherearth-annotated.html-assets/img56.png differ diff --git a/netherearth-annotated.html-assets/img57.png b/netherearth-annotated.html-assets/img57.png new file mode 100644 index 0000000..ba37a5c Binary files /dev/null and b/netherearth-annotated.html-assets/img57.png differ diff --git a/netherearth-annotated.html-assets/img58.png b/netherearth-annotated.html-assets/img58.png new file mode 100644 index 0000000..c5c81c0 Binary files /dev/null and b/netherearth-annotated.html-assets/img58.png differ diff --git a/netherearth-annotated.html-assets/img59.png b/netherearth-annotated.html-assets/img59.png new file mode 100644 index 0000000..eb30a10 Binary files /dev/null and b/netherearth-annotated.html-assets/img59.png differ diff --git a/netherearth-annotated.html-assets/img6.png b/netherearth-annotated.html-assets/img6.png new file mode 100644 index 0000000..6b59c07 Binary files /dev/null and b/netherearth-annotated.html-assets/img6.png differ diff --git a/netherearth-annotated.html-assets/img60.png b/netherearth-annotated.html-assets/img60.png new file mode 100644 index 0000000..7d9d175 Binary files /dev/null and b/netherearth-annotated.html-assets/img60.png differ diff --git a/netherearth-annotated.html-assets/img61.png b/netherearth-annotated.html-assets/img61.png new file mode 100644 index 0000000..76f4bfe Binary files /dev/null and b/netherearth-annotated.html-assets/img61.png differ diff --git a/netherearth-annotated.html-assets/img62.png b/netherearth-annotated.html-assets/img62.png new file mode 100644 index 0000000..50afb5d Binary files /dev/null and b/netherearth-annotated.html-assets/img62.png differ diff --git a/netherearth-annotated.html-assets/img63.png b/netherearth-annotated.html-assets/img63.png new file mode 100644 index 0000000..7836430 Binary files /dev/null and b/netherearth-annotated.html-assets/img63.png differ diff --git a/netherearth-annotated.html-assets/img64.png b/netherearth-annotated.html-assets/img64.png new file mode 100644 index 0000000..aed1030 Binary files /dev/null and b/netherearth-annotated.html-assets/img64.png differ diff --git a/netherearth-annotated.html-assets/img65.png b/netherearth-annotated.html-assets/img65.png new file mode 100644 index 0000000..2359c4b Binary files /dev/null and b/netherearth-annotated.html-assets/img65.png differ diff --git a/netherearth-annotated.html-assets/img66.png b/netherearth-annotated.html-assets/img66.png new file mode 100644 index 0000000..7fdf122 Binary files /dev/null and b/netherearth-annotated.html-assets/img66.png differ diff --git a/netherearth-annotated.html-assets/img67.png b/netherearth-annotated.html-assets/img67.png new file mode 100644 index 0000000..08da8c2 Binary files /dev/null and b/netherearth-annotated.html-assets/img67.png differ diff --git a/netherearth-annotated.html-assets/img68.png b/netherearth-annotated.html-assets/img68.png new file mode 100644 index 0000000..5dc0568 Binary files /dev/null and b/netherearth-annotated.html-assets/img68.png differ diff --git a/netherearth-annotated.html-assets/img69.png b/netherearth-annotated.html-assets/img69.png new file mode 100644 index 0000000..bfd6d03 Binary files /dev/null and b/netherearth-annotated.html-assets/img69.png differ diff --git a/netherearth-annotated.html-assets/img7.png b/netherearth-annotated.html-assets/img7.png new file mode 100644 index 0000000..608821f Binary files /dev/null and b/netherearth-annotated.html-assets/img7.png differ diff --git a/netherearth-annotated.html-assets/img70.png b/netherearth-annotated.html-assets/img70.png new file mode 100644 index 0000000..21078e3 Binary files /dev/null and b/netherearth-annotated.html-assets/img70.png differ diff --git a/netherearth-annotated.html-assets/img71.png b/netherearth-annotated.html-assets/img71.png new file mode 100644 index 0000000..d72b9b7 Binary files /dev/null and b/netherearth-annotated.html-assets/img71.png differ diff --git a/netherearth-annotated.html-assets/img72.png b/netherearth-annotated.html-assets/img72.png new file mode 100644 index 0000000..9d0bb4d Binary files /dev/null and b/netherearth-annotated.html-assets/img72.png differ diff --git a/netherearth-annotated.html-assets/img73.png b/netherearth-annotated.html-assets/img73.png new file mode 100644 index 0000000..3b3fd81 Binary files /dev/null and b/netherearth-annotated.html-assets/img73.png differ diff --git a/netherearth-annotated.html-assets/img74.png b/netherearth-annotated.html-assets/img74.png new file mode 100644 index 0000000..dbcf9b8 Binary files /dev/null and b/netherearth-annotated.html-assets/img74.png differ diff --git a/netherearth-annotated.html-assets/img75.png b/netherearth-annotated.html-assets/img75.png new file mode 100644 index 0000000..129ebb7 Binary files /dev/null and b/netherearth-annotated.html-assets/img75.png differ diff --git a/netherearth-annotated.html-assets/img76.png b/netherearth-annotated.html-assets/img76.png new file mode 100644 index 0000000..807a316 Binary files /dev/null and b/netherearth-annotated.html-assets/img76.png differ diff --git a/netherearth-annotated.html-assets/img77.png b/netherearth-annotated.html-assets/img77.png new file mode 100644 index 0000000..4ec632e Binary files /dev/null and b/netherearth-annotated.html-assets/img77.png differ diff --git a/netherearth-annotated.html-assets/img78.png b/netherearth-annotated.html-assets/img78.png new file mode 100644 index 0000000..92279c9 Binary files /dev/null and b/netherearth-annotated.html-assets/img78.png differ diff --git a/netherearth-annotated.html-assets/img79.png b/netherearth-annotated.html-assets/img79.png new file mode 100644 index 0000000..29c5fbe Binary files /dev/null and b/netherearth-annotated.html-assets/img79.png differ diff --git a/netherearth-annotated.html-assets/img8.png b/netherearth-annotated.html-assets/img8.png new file mode 100644 index 0000000..ab881c3 Binary files /dev/null and b/netherearth-annotated.html-assets/img8.png differ diff --git a/netherearth-annotated.html-assets/img80.png b/netherearth-annotated.html-assets/img80.png new file mode 100644 index 0000000..ee228fb Binary files /dev/null and b/netherearth-annotated.html-assets/img80.png differ diff --git a/netherearth-annotated.html-assets/img81.png b/netherearth-annotated.html-assets/img81.png new file mode 100644 index 0000000..1cdd63b Binary files /dev/null and b/netherearth-annotated.html-assets/img81.png differ diff --git a/netherearth-annotated.html-assets/img82.png b/netherearth-annotated.html-assets/img82.png new file mode 100644 index 0000000..2a588b5 Binary files /dev/null and b/netherearth-annotated.html-assets/img82.png differ diff --git a/netherearth-annotated.html-assets/img83.png b/netherearth-annotated.html-assets/img83.png new file mode 100644 index 0000000..a24d746 Binary files /dev/null and b/netherearth-annotated.html-assets/img83.png differ diff --git a/netherearth-annotated.html-assets/img84.png b/netherearth-annotated.html-assets/img84.png new file mode 100644 index 0000000..2dcb203 Binary files /dev/null and b/netherearth-annotated.html-assets/img84.png differ diff --git a/netherearth-annotated.html-assets/img85.png b/netherearth-annotated.html-assets/img85.png new file mode 100644 index 0000000..d8b5408 Binary files /dev/null and b/netherearth-annotated.html-assets/img85.png differ diff --git a/netherearth-annotated.html-assets/img86.png b/netherearth-annotated.html-assets/img86.png new file mode 100644 index 0000000..150b5d4 Binary files /dev/null and b/netherearth-annotated.html-assets/img86.png differ diff --git a/netherearth-annotated.html-assets/img87.png b/netherearth-annotated.html-assets/img87.png new file mode 100644 index 0000000..1f857f1 Binary files /dev/null and b/netherearth-annotated.html-assets/img87.png differ diff --git a/netherearth-annotated.html-assets/img88.png b/netherearth-annotated.html-assets/img88.png new file mode 100644 index 0000000..a573267 Binary files /dev/null and b/netherearth-annotated.html-assets/img88.png differ diff --git a/netherearth-annotated.html-assets/img89.png b/netherearth-annotated.html-assets/img89.png new file mode 100644 index 0000000..0af57f9 Binary files /dev/null and b/netherearth-annotated.html-assets/img89.png differ diff --git a/netherearth-annotated.html-assets/img9.png b/netherearth-annotated.html-assets/img9.png new file mode 100644 index 0000000..fe2fde1 Binary files /dev/null and b/netherearth-annotated.html-assets/img9.png differ diff --git a/netherearth-annotated.html-assets/img90.png b/netherearth-annotated.html-assets/img90.png new file mode 100644 index 0000000..ae5a670 Binary files /dev/null and b/netherearth-annotated.html-assets/img90.png differ diff --git a/netherearth-annotated.html-assets/img91.png b/netherearth-annotated.html-assets/img91.png new file mode 100644 index 0000000..e33126a Binary files /dev/null and b/netherearth-annotated.html-assets/img91.png differ diff --git a/netherearth-annotated.html-assets/img92.png b/netherearth-annotated.html-assets/img92.png new file mode 100644 index 0000000..e02d47d Binary files /dev/null and b/netherearth-annotated.html-assets/img92.png differ diff --git a/netherearth-annotated.html-assets/img93.png b/netherearth-annotated.html-assets/img93.png new file mode 100644 index 0000000..9b085ac Binary files /dev/null and b/netherearth-annotated.html-assets/img93.png differ diff --git a/netherearth-annotated.html-assets/img94.png b/netherearth-annotated.html-assets/img94.png new file mode 100644 index 0000000..7d9cb5a Binary files /dev/null and b/netherearth-annotated.html-assets/img94.png differ diff --git a/netherearth-annotated.html-assets/img95.png b/netherearth-annotated.html-assets/img95.png new file mode 100644 index 0000000..5f2b4d7 Binary files /dev/null and b/netherearth-annotated.html-assets/img95.png differ diff --git a/netherearth-annotated.html-assets/img96.png b/netherearth-annotated.html-assets/img96.png new file mode 100644 index 0000000..d88bff7 Binary files /dev/null and b/netherearth-annotated.html-assets/img96.png differ diff --git a/netherearth-annotated.html-assets/img97.png b/netherearth-annotated.html-assets/img97.png new file mode 100644 index 0000000..81adb4e Binary files /dev/null and b/netherearth-annotated.html-assets/img97.png differ diff --git a/netherearth-annotated.html-assets/img98.png b/netherearth-annotated.html-assets/img98.png new file mode 100644 index 0000000..f39ac2a Binary files /dev/null and b/netherearth-annotated.html-assets/img98.png differ diff --git a/netherearth-annotated.html-assets/img99.png b/netherearth-annotated.html-assets/img99.png new file mode 100644 index 0000000..998c403 Binary files /dev/null and b/netherearth-annotated.html-assets/img99.png differ