Address | Position in Binary | Size | Timing | Assembled | Code |
#0000 | #0000 | | | | ; -------------------------------- |
#0000 | #0000 | | | | ; "Castle Master 2: The Crypt" by Incentive Software Ltd., 1990 |
#0000 | #0000 | | | | ; Disassembled by Santiago Ontañón in 2023 |
#0000 | #0000 | | | | ; |
#0000 | #0000 | | | | ; Disclaimer: All the comments, label and constant names in this disassembly are my best interpretation of what the |
#0000 | #0000 | | | | ; code actually does. Fully annotating a disassembly like this one requires a large amount of work (this one took |
#0000 | #0000 | | | | ; me over a month, dedicating 2-3 hours every day). Therefore, it might contain errors or misunderstandings. |
#0000 | #0000 | | | | ; Please report if you find something that is incorrect. When I am very unsure of what some code does, I added |
#0000 | #0000 | | | | ; a note, but I might have missed many. |
#0000 | #0000 | | | | ; |
#0000 | #0000 | | | | ; Notes and curiosities from the codebase: |
#0000 | #0000 | | | | ; - There are two identical functions: |
#0000 | #0000 | | | | ; - La9de_hl_eq_h_times_64 |
#0000 | #0000 | | | | ; - Lcb6d_hl_eq_h_times_64 |
#0000 | #0000 | | | | ; - There are two implemented versions of the same multiplication operation "(de,hl) = de * hl": |
#0000 | #0000 | | | | ; - La15e_de_times_hl_signed |
#0000 | #0000 | | | | ; - L8ab4_de_times_hl_signed |
#0000 | #0000 | | | | ; - Interestingly: the first is redundant, since the second is smaller and faster. However, it is the |
#0000 | #0000 | | | | ; first that is the most commonly used in the code!!! |
#0000 | #0000 | | | | ; - There is self-modifying code |
#0000 | #0000 | | | | ; - The 3d rendering engine is quite advanced for the year it was written: |
#0000 | #0000 | | | | ; - It contains all basic elements of later 3d engines |
#0000 | #0000 | | | | ; - It only considers 2 rotation angles (pitch and yaw), but it would be trivial to add a third, if it |
#0000 | #0000 | | | | ; wasn't because of the skybox (which would have to rotate if we added "roll"). |
#0000 | #0000 | | | | ; - It contains skybox rendering code for outdoor areas (and even a "lightning" animation over the skybox!) |
#0000 | #0000 | | | | ; - It supports textured shapes |
#0000 | #0000 | | | | ; - Objects can be lines, triangles, quads or pentagons |
#0000 | #0000 | | | | ; - It implements many levels of culling (quick rendering cube, rendering frustum/pyramid) |
#0000 | #0000 | | | | ; - It implements polygon clipping for those that are only partly within the screen |
#0000 | #0000 | | | | ; - Different stages of rendering are "cached" in memory, so that we do not need to repeat them. For example, |
#0000 | #0000 | | | | ; when entering a menu, and going back to the game, all the 3d -> 2d projection does not need to be redone, |
#0000 | #0000 | | | | ; as positions have not changed. So, this is skipped. Similarly, when player does not move, rotation matrices |
#0000 | #0000 | | | | ; are not recalculated. |
#0000 | #0000 | | | | ; - All in all, even if the individual functions are not very optimized (things can be done significantly faster), |
#0000 | #0000 | | | | ; the overall structure is very nice (and some of the low-level functions are indeed quite optimized, such as |
#0000 | #0000 | | | | ; the one that renders textured horizontal lines). |
#0000 | #0000 | | | | ; - All the computations are done with fixed point arithmetic. Even line and polygon drawing uses this fixed-point |
#0000 | #0000 | | | | ; calculations, rather than the more optimized Bresenham routines. This makes the code simpler, even if |
#0000 | #0000 | | | | ; slower than it could be. |
#0000 | #0000 | | | | ; - Sorting of objects for rendering is quite curious, as it happens in coordinates *before* they are projected to |
#0000 | #0000 | | | | ; camera coordinates (just distance from player in each separate axis). I am sure this causes many issues in corner |
#0000 | #0000 | | | | ; cases. |
#0000 | #0000 | | | | ; - I think the code has a couple of bugs, I marked them with "BUG?" tags. Of course, I am not 100% sure, but I |
#0000 | #0000 | | | | ; think they are bugs. |
#0000 | #0000 | | | | ; |
#0000 | #0000 | | | | ; Potential optimization of the code: |
#0000 | #0000 | | | | ; - The code seems more functional than optimized. The lowest level drawing routines seem to be optimized well, but most |
#0000 | #0000 | | | | ; of the math routines are not. So, there is a lot of opportunity to make the engine faster. |
#0000 | #0000 | | | | ; - I have added "OPTIMIZATION" tags in places where small things could be optimized. I only added those that |
#0000 | #0000 | | | | ; an automatic optimizer (in this case MDL: https://github.com/santiontanon/mdlz80optimizer) would not already |
#0000 | #0000 | | | | ; detect automatically. Basically, these are notes for an potential optimized version. Only small things are noted |
#0000 | #0000 | | | | ; large architectural changes (like moving from fixed-point arithmetic line-drawing to Bresenham-style, are not |
#0000 | #0000 | | | | ; annotated in the code). |
#0000 | #0000 | | | | ; |
#0000 | #0000 | | | | ; Related work: |
#0000 | #0000 | | | | ; - See Phantasma, a reimplementation of the Freescape engine: https://github.com/TomHarte/Phantasma |
#0000 | #0000 | | | | ; - See the information on the Freescape reimplementation in SCUMMVM: https://wiki.scummvm.org/index.php?title=Freescape |
#0000 | #0000 | | | | ; |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; -------------------------------- |
#0000 | #0000 | | | | ; BIOS Functions and constants: |
#0000 | #0000 | | | | ; - Information obtained from "The Spectrum Machine Code Reference Guide" book. |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Saves a collection of bytes to tape |
#0000 | #0000 | | | | ; Input: |
#0000 | #0000 | | | | ; - ix: address to save |
#0000 | #0000 | | | | ; - de: byte count |
#0000 | #0000 | | | | L04c6_BIOS_CASSETTE_SAVE_NO_BREAK_TEST: equ #04c6 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Saves a collection of bytes to tape |
#0000 | #0000 | | | | ; Input: |
#0000 | #0000 | | | | ; - ix: address where to load |
#0000 | #0000 | | | | ; - de: byte count |
#0000 | #0000 | | | | L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS: equ #0562 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ULA_PORT: equ #fe ; Writing to this port ignores the high 8bits. |
#0000 | #0000 | | | | ; The 8 bit value written is used as follows: |
#0000 | #0000 | | | | ; - bits 0, 1, 2: border color |
#0000 | #0000 | | | | ; - bit 3: MIC (tape output) |
#0000 | #0000 | | | | ; - bit 4: speaker output |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; -------------------------------- |
#0000 | #0000 | | | | ; Video memory constants: |
#0000 | #0000 | | | | ; - Information obtained from: http://www.breakintoprogram.co.uk/hardware/computers/zx-spectrum/screen-memory-layout |
#0000 | #0000 | | | | L4000_VIDEOMEM_PATTERNS: equ #4000 |
#0000 | #0000 | | | | L5800_VIDEOMEM_ATTRIBUTES: equ #5800 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | SCREEN_WIDTH: equ 24 |
#0000 | #0000 | | | | SCREEN_HEIGHT: equ 14 |
#0000 | #0000 | | | | SCREEN_WIDTH_IN_PIXELS: equ SCREEN_WIDTH * 8 ; 192 ; mdl: SCREEN_WIDTH_IN_PIXELS = 192 (#00c0) |
#0000 | #0000 | | | | SCREEN_HEIGHT_IN_PIXELS: equ SCREEN_HEIGHT * 8 ; 112 ; mdl: SCREEN_HEIGHT_IN_PIXELS = 112 (#0070) |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; -------------------------------- |
#0000 | #0000 | | | | ; Game constants: |
#0000 | #0000 | | | | CONTROL_MODE_KEYBOARD: equ 0 |
#0000 | #0000 | | | | CONTROL_MODE_SINCLAIR_JOYSTICK: equ 1 |
#0000 | #0000 | | | | CONTROL_MODE_KEMPSTON_JOYSTICK: equ 2 |
#0000 | #0000 | | | | CONTROL_MODE_CURSOR_JOYSTICK: equ 3 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | MAX_COORDINATE: equ 127 * 64 ; mdl: MAX_COORDINATE = 8128 (#1fc0) |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | MAX_PRESSED_KEYS: equ 5 |
#0000 | #0000 | | | | FILENAME_BUFFER_SIZE: equ 12 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | SPIRIT_METER_MAX: equ 64 |
#0000 | #0000 | | | | MAX_STRENGTH: equ 24 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | GAME_OVER_REASON_OVERPOWERED: equ 1 |
#0000 | #0000 | | | | GAME_OVER_REASON_YOU_COLLAPSE: equ 2 |
#0000 | #0000 | | | | GAME_OVER_REASON_CRUSHED: equ 3 |
#0000 | #0000 | | | | GAME_OVER_REASON_FATAL_FALL: equ 4 |
#0000 | #0000 | | | | GAME_OVER_REASON_ESCAPED: equ 5 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Sound FX: |
#0000 | #0000 | | | | SFX_MENU_SELECT: equ 3 ; Also used for when player collides with an object |
#0000 | #0000 | | | | SFX_THROW_ROCK_OR_LAND: equ 5 |
#0000 | #0000 | | | | SFX_FALLING: equ 6 |
#0000 | #0000 | | | | SFX_GAME_START: equ 7 |
#0000 | #0000 | | | | SFX_LIGHTNING: equ 8 |
#0000 | #0000 | | | | SFX_GATE_CLOSE: equ 9 |
#0000 | #0000 | | | | SFX_PICK_UP_ITEM: equ 10 |
#0000 | #0000 | | | | SFX_OPEN_CHEST: equ 11 |
#0000 | #0000 | | | | SFX_CLIMB_DROP: equ 12 |
#0000 | #0000 | | | | SFX_OPEN_ESCAPED: equ 13 |
#0000 | #0000 | | | | ; There are other SFX defined, but only used in the game scripts: |
#0000 | #0000 | | | | ; 1 ; sounds like if you die / get hit / error |
#0000 | #0000 | | | | ; 2 ; sounds like game over |
#0000 | #0000 | | | | ; 4 ; short high -> higher pitch beep |
#0000 | #0000 | | | | ; 14 ; low-pitch repeated sound, not sure what |
#0000 | #0000 | | | | ; 15 ; tiny short SFX |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | INPUT_FORWARD: equ 3 |
#0000 | #0000 | | | | INPUT_BACKWARD: equ 4 |
#0000 | #0000 | | | | INPUT_TURN_LEFT: equ 5 |
#0000 | #0000 | | | | INPUT_TURN_RIGHT: equ 6 |
#0000 | #0000 | | | | INPUT_LOOK_UP: equ 7 |
#0000 | #0000 | | | | INPUT_LOOK_DOWN: equ 8 |
#0000 | #0000 | | | | INPUT_CRAWL: equ 9 |
#0000 | #0000 | | | | INPUT_WALK: equ 10 |
#0000 | #0000 | | | | INPUT_RUN: equ 11 |
#0000 | #0000 | | | | INPUT_FACE_FORWARD: equ 12 |
#0000 | #0000 | | | | INPUT_U_TURN: equ 13 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | INPUT_MOVEMENT_POINTER_ON_OFF: equ 21 |
#0000 | #0000 | | | | INPUT_THROW_ROCK: equ 22 |
#0000 | #0000 | | | | INPUT_MOVE_POINTER_RIGHT: equ 23 |
#0000 | #0000 | | | | INPUT_MOVE_POINTER_LEFT: equ 24 |
#0000 | #0000 | | | | INPUT_MOVE_POINTER_DOWN: equ 25 |
#0000 | #0000 | | | | INPUT_MOVE_POINTER_UP: equ 26 |
#0000 | #0000 | | | | INPUT_ACTION: equ 27 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | INPUT_SWITCH_BETWEEN_MOVEMENT_AND_POINTER: equ 30 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | INPUT_INFO_MENU: equ 41 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; How many degrees is a full circle: |
#0000 | #0000 | | | | FULL_ROTATION_DEGREES: equ 72 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Datablock structures: |
#0000 | #0000 | | | | AREA_HEADER_SIZE: equ 8 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Area struct: |
#0000 | #0000 | | | | AREA_FLAGS: equ 0 |
#0000 | #0000 | | | | AREA_N_OBJECTS: equ 1 |
#0000 | #0000 | | | | AREA_ID: equ 2 |
#0000 | #0000 | | | | AREA_RULES_OFFSET: equ 3 ; 2 bytes |
#0000 | #0000 | | | | AREA_SCALE: equ 5 |
#0000 | #0000 | | | | AREA_ATTRIBUTE: equ 6 |
#0000 | #0000 | | | | AREA_NAME: equ 7 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Object struct: |
#0000 | #0000 | | | | OBJECT_TYPE_AND_FLAGS: equ 0 |
#0000 | #0000 | | | | OBJECT_X: equ 1 |
#0000 | #0000 | | | | OBJECT_Y: equ 2 |
#0000 | #0000 | | | | OBJECT_Z: equ 3 |
#0000 | #0000 | | | | OBJECT_SIZE_X: equ 4 |
#0000 | #0000 | | | | OBJECT_SIZE_Y: equ 5 |
#0000 | #0000 | | | | OBJECT_SIZE_Z: equ 6 |
#0000 | #0000 | | | | OBJECT_ID: equ 7 |
#0000 | #0000 | | | | OBJECT_SIZE: equ 8 |
#0000 | #0000 | | | | OBJECT_ADDITIONAL_DATA: equ 9 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Object types: |
#0000 | #0000 | | | | OBJECT_TYPE_ENTRANCE: equ 0 |
#0000 | #0000 | | | | OBJECT_TYPE_CUBE: equ 1 |
#0000 | #0000 | | | | OBJECT_TYPE_SPIRIT: equ 2 |
#0000 | #0000 | | | | OBJECT_TYPE_RECTANGLE: equ 3 |
#0000 | #0000 | | | | ; - Object types in between 4 and 9 are different solids, like pyramids, |
#0000 | #0000 | | | | ; hourglasses, wedges, etc. that are synthesized on the fly. |
#0000 | #0000 | | | | ; - I believe the object ID here just indicates their orientation (one of |
#0000 | #0000 | | | | ; the 6 possible cardinal directions in 3d), and their additional data |
#0000 | #0000 | | | | ; is used to determine their exact shape (via some checks in at the bedinning of |
#0000 | #0000 | | | | ; function "L97bb_project_other_solids"). |
#0000 | #0000 | | | | OBJECT_TYPE_LINE: equ 10 |
#0000 | #0000 | | | | OBJECT_TYPE_TRIANGLE: equ 11 |
#0000 | #0000 | | | | OBJECT_TYPE_QUAD: equ 12 |
#0000 | #0000 | | | | OBJECT_TYPE_PENTAGON: equ 13 |
#0000 | #0000 | | | | OBJECT_TYPE_HEXAGON: equ 14 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Rule types: |
#0000 | #0000 | | | | RULE_TYPE_ADD_TO_SCORE: equ 1 |
#0000 | #0000 | | | | RULE_TYPE_TOGGLE_OBJECT_VISIBILITY: equ 3 |
#0000 | #0000 | | | | RULE_TYPE_MAKE_OBJECT_VISIBILE: equ 4 |
#0000 | #0000 | | | | RULE_TYPE_MAKE_OBJECT_INVISIBILE: equ 5 |
#0000 | #0000 | | | | RULE_TYPE_TOGGLE_OBJECT_FROM_AREA_VISIBILITY: equ 6 |
#0000 | #0000 | | | | RULE_TYPE_MAKE_OBJECT_FROM_AREA_VISIBILE: equ 7 |
#0000 | #0000 | | | | RULE_TYPE_MAKE_OBJECT_FROM_AREA_INVISIBILE: equ 8 |
#0000 | #0000 | | | | RULE_TYPE_INCREMENT_VARIABLE: equ 9 |
#0000 | #0000 | | | | RULE_TYPE_DECREMENT_VARIABLE: equ 10 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_VARIABLE_DIFFERENT: equ 11 |
#0000 | #0000 | | | | RULE_TYPE_SET_BOOLEAN_TRUE: equ 12 |
#0000 | #0000 | | | | RULE_TYPE_SET_BOOLEAN_FALSE: equ 13 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_BOOLEAN_DIFFERENT: equ 14 |
#0000 | #0000 | | | | RULE_TYPE_PLAY_SFX: equ 15 |
#0000 | #0000 | | | | RULE_TYPE_DESTROY_OBJECT: equ 16 |
#0000 | #0000 | | | | RULE_TYPE_DESTROY_OBJECT_FROM_AREA: equ 17 |
#0000 | #0000 | | | | RULE_TYPE_TELEPORT: equ 18 |
#0000 | #0000 | | | | RULE_TYPE_STRENGTH_UPDATE: equ 19 |
#0000 | #0000 | | | | RULE_TYPE_SET_VARIABLE: equ 20 |
#0000 | #0000 | | | | RULE_TYPE_REDRAW: equ 26 |
#0000 | #0000 | | | | RULE_TYPE_PAUSE: equ 27 |
#0000 | #0000 | | | | RULE_TYPE_REQUEST_SFX_NEXT_FRAME: equ 28 |
#0000 | #0000 | | | | RULE_TYPE_TOGGLE_BOOLEAN: equ 29 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_OBJECT_INVISIBLE: equ 30 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_OBJECT_VISIBLE: equ 31 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_OBJECT_FROM_AREA_INVISIBLE: equ 32 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_OBJECT_FROM_AREA_VISIBLE: equ 33 |
#0000 | #0000 | | | | RULE_TYPE_SHOW_MESSAGE: equ 34 |
#0000 | #0000 | | | | RULE_TYPE_RENDER_EFFECT: equ 35 |
#0000 | #0000 | | | | RULE_TYPE_FLIP_SKIP_RULE: equ 44 |
#0000 | #0000 | | | | RULE_TYPE_UNSET_SKIP_RULE: equ 45 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_VARIABLE_LARGER: equ 46 |
#0000 | #0000 | | | | RULE_TYPE_END_RULE_IF_VARIABLE_LOWER: equ 47 |
#0000 | #0000 | | | | RULE_TYPE_SELECT_OBJECT: equ 48 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; -------------------------------- |
#0000 | #0000 | | | | ; RAM Variables before the game data: |
#0000 | #0000 | | | | L5cbc_render_buffer: equ #5cbc ; 2712 bytes ((SCREEN_HEIGHT * 8 + 1) * SCREEN_WIDTH) |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; Variables that overlap with the render buffer, these are used when projecting |
#0000 | #0000 | | | | ; the 3d vertices into 2d, so, they are discarded and not needed when using the |
#0000 | #0000 | | | | ; render buffer. |
#0000 | #0000 | | | | L5e4c_pitch_rotation_matrix: equ #5e4c |
#0000 | #0000 | | | | L5e55_rotation_matrix: equ #5e55 |
#0000 | #0000 | | | | L5e5e_at_least_one_vertex_outside_rendering_frustum: equ #5e5e |
#0000 | #0000 | | | | L5e5f_add_to_projected_objects_flag: equ #5e5f ; If this is 1, the current object being projected from 3d to 2d, will be added to the list of objects to draw. |
#0000 | #0000 | | | | L5e60_projection_pre_work_type: equ #5e60 ; Indicates whether we need to do additional computations before projecting each face. |
#0000 | #0000 | | | | L5e61_object_currently_being_processed_type: equ #5e61 |
#0000 | #0000 | | | | L5e62_player_collision_with_object_flags: equ #5e62 |
#0000 | #0000 | | | | L5e63_3d_vertex_coordinates_relative_to_player: equ #5e63 |
#0000 | #0000 | | | | L5e75_48_bit_accumulator: equ #5e75 |
#0000 | #0000 | | | | L5e7b_48bitmul_tmp1: equ #5e7b |
#0000 | #0000 | | | | L5e7d_48bitmul_tmp2: equ #5e7d |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L5e9f_3d_vertex_coordinates_after_rotation_matrix: equ #5e9f ; 16 bit representation. |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L5edc_vertex_rendering_frustum_checks: equ #5edc ; 5 bits per vertex, indicating if they passed or not each of the 5 culling tests for the rendering frustum. |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L5ee8_already_projected_vertex_coordinates: equ #5ee8 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L5f24_shape_edges_ptr: equ #5f24 ; Pointer to the array with the order of edges to use for projection. |
#0000 | #0000 | | | | L5f26_alternative_shape_edges_ptr: equ #5f26 ; Alternative edges pointer (for when object is seen from below, this is only needed for flat shapes). |
#0000 | #0000 | | | | L5f28_cull_face_when_no_projected_vertices: equ #5f28 |
#0000 | #0000 | | | | L5f29_extra_solid_dimensions: equ #5f29 ; stores 4 additional dimensions used temporarily to synthesize solids like pyramids, hourglasses, etc. on the fly. (4 16bit numbers). |
#0000 | #0000 | | | | L5f31_sorting_comparison_result: equ #5f31 ; result of comparing the coordinates of two objects to see if they should be flipped for rendering. |
#0000 | #0000 | | | | L5f32_sorting_any_change: equ #5f32 |
#0000 | #0000 | | | | L5f33_sorting_boundingbox_ptr1: equ #5f33 |
#0000 | #0000 | | | | L5f35_sorting_boundingbox_ptr2: equ #5f35 |
#0000 | #0000 | | | | L5f37_sorting_bbox1_c1: equ #5f37 ; These four variables hold the values of the min/max coordinates for the current axis of the two bounding boxes being compared for sorting. |
#0000 | #0000 | | | | L5f39_sorting_bbox2_c1: equ #5f39 |
#0000 | #0000 | | | | L5f3b_sorting_bbox1_c2: equ #5f3b |
#0000 | #0000 | | | | L5f3d_sorting_bbox2_c2: equ #5f3d |
#0000 | #0000 | | | | L5f3f_n_objects_covering_the_whole_screen_left: equ #5f3f |
#0000 | #0000 | | | | L5f40_16_bit_tmp_matrix: equ #5f40 ; Used internally to save the results of matrix multiplication. |
#0000 | #0000 | | | | L5f52_16_bit_tmp_matrix_ptr: equ #5f52 ; Used to keep track of the elements in the matrix above. |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L5fa2_3d_object_bounding_boxes_relative_to_player: equ #5fa2 ; in 16 bit precision: x1, x2, y1, y2, z1, z2 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | L6664_row_pointers: equ #6664 ; Pointers to each row of pixels in the buffer. |
#0000 | #0000 | | | | L6754_end_of_render_buffer: equ #6754 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; This contains the current room objects, already projected to 2d coordinates: |
#0000 | #0000 | | | | ; - Each entry has 2 pointers: |
#0000 | #0000 | | | | ; - One pointer to the "L67f4_projected_vertex_data" (with the projected vertices) |
#0000 | #0000 | | | | ; - One pointer to the "L5fa2_3d_object_bounding_boxes_relative_to_player" |
#0000 | #0000 | | | | L6754_current_room_object_projected_data: equ #6754 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | ; For each projected object, the data is organized as follows: |
#0000 | #0000 | | | | ; - 1 byte: object ID |
#0000 | #0000 | | | | ; - 1 byte: number of primitives/faces: |
#0000 | #0000 | | | | ; - If the most significant bit is set, it means this object covers the whole screen. |
#0000 | #0000 | | | | ; - face data: |
#0000 | #0000 | | | | ; - 1 byte (texture / # vertices), |
#0000 | #0000 | | | | ; - and then 2 bytes per vertex screen x, screen y (screen y is reversed, 0 = bottom). |
#0000 | #0000 | | | | L67f4_projected_vertex_data: equ #67f4 |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | |
#0000 | #0000 | | | | org #6a00 |
#6a00 | #0000 | | | | |
#6a00 | #0000 | | | | ; -------------------------------- |
#6a00 | #0000 | | | | ; Program start |
#6a00 | #0000 | | | | L6a00_start: |
#6a00 | #0000 | 3 | 11 | c3 2f 6a | jp L6a2f_game_init |
#6a03 | #0003 | | | | |
#6a03 | #0003 | | | | |
#6a03 | #0003 | | | | ; -------------------------------- |
#6a03 | #0003 | | | | ; Set up the interrupt routine to "Lbe66_interrupt_routine". |
#6a03 | #0003 | | | | L6a03_setup_interrupts: |
#6a03 | #0003 | 1 | 5 | f3 | di |
#6a04 | #0004 | 1 | 12 | e5 | push hl |
#6a05 | #0005 | 1 | 12 | d5 | push de |
#6a06 | #0006 | 1 | 12 | c5 | push bc |
#6a07 | #0007 | 1 | 12 | f5 | push af |
#6a08 | #0008 | 1 | 5 | af | xor a |
#6a09 | #0009 | 3 | 14 | 32 7c 74 | ld (L747c_within_interrupt_flag), a |
#6a0c | #000c | 3 | 11 | 21 00 fe | ld hl, Lfe00_interrupt_vector_table |
#6a0f | #000f | 1 | 5 | 7c | ld a, h |
#6a10 | #0010 | 2 | 11 | ed 47 | ld i, a |
#6a12 | #0012 | 1 | 5 | 54 | ld d, h |
#6a13 | #0013 | 1 | 5 | 5d | ld e, l |
#6a14 | #0014 | 1 | 5 | 1c | inc e |
#6a15 | #0015 | 2 | 11 | 36 fd | ld (hl), #fd |
#6a17 | #0017 | 3 | 11 | 01 00 01 | ld bc, 256 |
#6a1a | #001a | 2 | 23/18 | ed b0 | ldir |
#6a1c | #001c | 2 | 8 | 3e c3 | ld a, #c3 ; jp opcode |
#6a1e | #001e | 3 | 11 | 21 66 be | ld hl, Lbe66_interrupt_routine |
#6a21 | #0021 | 3 | 14 | 32 fd fd | ld (Lfdfd_interrupt_jp), a |
#6a24 | #0024 | 3 | 17 | 22 fe fd | ld (Lfdfe_interrupt_pointer), hl |
#6a27 | #0027 | 2 | 10 | ed 5e | im 2 |
#6a29 | #0029 | 1 | 11 | f1 | pop af |
#6a2a | #002a | 1 | 11 | c1 | pop bc |
#6a2b | #002b | 1 | 11 | d1 | pop de |
#6a2c | #002c | 1 | 11 | e1 | pop hl |
#6a2d | #002d | 1 | 5 | fb | ei |
#6a2e | #002e | 1 | 11 | c9 | ret |
#6a2f | #002f | | | | |
#6a2f | #002f | | | | |
#6a2f | #002f | | | | ; -------------------------------- |
#6a2f | #002f | | | | ; Initializes the game the very first time. |
#6a2f | #002f | | | | L6a2f_game_init: |
#6a2f | #002f | 3 | 11 | 31 f8 ff | ld sp, #fff8 ; initialize the stack |
#6a32 | #0032 | 1 | 5 | f3 | di |
#6a33 | #0033 | 1 | 5 | af | xor a ; Set control mode to keyboard |
#6a34 | #0034 | 3 | 14 | 32 83 76 | ld (L7683_control_mode), a |
#6a37 | #0037 | 4 | 22 | fd 22 7d 74 | ld (L747d), iy ; Note: This instruction is very strange, as at this point "iy" is undefined. |
#6a3b | #003b | 3 | 18 | cd c9 a4 | call La4c9_init_game_state |
#6a3e | #003e | 3 | 18 | cd 03 6a | call L6a03_setup_interrupts |
#6a41 | #0041 | 3 | 11 | c3 7e 6a | jp L6a7e_main_application_loop |
#6a44 | #0044 | | | | |
#6a44 | #0044 | | | | |
#6a44 | #0044 | | | | ; -------------------------------- |
#6a44 | #0044 | | | | ; Unused? |
#6a44 | #0044 | 16 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#6a54 | #0054 | 16 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#6a64 | #0064 | 16 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#6a74 | #0074 | 10 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#6a7e | #007e | | | | |
#6a7e | #007e | | | | |
#6a7e | #007e | | | | ; -------------------------------- |
#6a7e | #007e | | | | ; Main application loop: calls title screen, starts game, restarts title screen, etc. |
#6a7e | #007e | | | | ; I think this is a game loop |
#6a7e | #007e | | | | L6a7e_main_application_loop: |
#6a7e | #007e | 3 | 11 | 21 fd ff | ld hl, #fffd |
#6a81 | #0081 | 3 | 17 | 22 6c 74 | ld (L746c_game_flags), hl |
#6a84 | #0084 | 2 | 8 | 3e 02 | ld a, 2 |
#6a86 | #0086 | 3 | 14 | 32 77 74 | ld (L7477_render_buffer_effect), a ; Request gate opening effect |
#6a89 | #0089 | 3 | 18 | cd 2e c7 | call Lc72e_title_screen_loop |
#6a8c | #008c | 3 | 18 | cd aa 83 | call L83aa_redraw_whole_screen |
#6a8f | #008f | 1 | 5 | af | xor a |
#6a90 | #0090 | 3 | 14 | 32 79 74 | ld (L7479_current_game_state), a |
#6a93 | #0093 | 3 | 11 | c3 99 6a | jp L6a99 |
#6a96 | #0096 | | | | L6a96_game_loop: |
#6a96 | #0096 | 3 | 18 | cd aa 83 | call L83aa_redraw_whole_screen |
#6a99 | #0099 | | | | L6a99: |
#6a99 | #0099 | 3 | 18 | cd ec 9d | call L9dec_game_tick |
#6a9c | #009c | 3 | 18 | cd 05 a0 | call La005_check_rules |
#6a9f | #009f | 3 | 17 | 2a 6c 74 | ld hl, (L746c_game_flags) |
#6aa2 | #00a2 | 2 | 10 | cb 4d | bit 1, l ; check the "game over" flag |
#6aa4 | #00a4 | 3 | 11 | ca 96 6a | jp z, L6a96_game_loop |
#6aa7 | #00a7 | 3 | 18 | cd c9 a4 | call La4c9_init_game_state |
#6aaa | #00aa | 3 | 11 | c3 7e 6a | jp L6a7e_main_application_loop |
#6aad | #00ad | | | | |
#6aad | #00ad | | | | |
#6aad | #00ad | | | | ; -------------------------------- |
#6aad | #00ad | | | | ; Game state variables: |
#6aad | #00ad | | | | ; Saving game saves data starting from here: |
#6aad | #00ad | | | | L6aad_savegame_data_start: |
#6aad | #00ad | | | | L6aad_player_current_x: |
#6aad | #00ad | 2 | | | dw #00a0 |
#6aaf | #00af | | | | L6aaf_player_current_y: |
#6aaf | #00af | 2 | | | dw #09e0 |
#6ab1 | #00b1 | | | | L6ab1_player_current_z: |
#6ab1 | #00b1 | 2 | | | dw #1b60 |
#6ab3 | #00b3 | | | | L6ab3_current_speed_in_this_room: |
#6ab3 | #00b3 | 2 | | | dw #11d0 |
#6ab5 | #00b5 | | | | L6ab5_current_speed: ; This is a value form the Ld0c8_speed_when_crawling array, depending on L6b0b_selected_movement_mode. |
#6ab5 | #00b5 | 1 | | | db #f0 |
#6ab6 | #00b6 | | | | L6ab6_player_pitch_angle: ; from 18 to -18 (54) |
#6ab6 | #00b6 | 1 | | | db #00 |
#6ab7 | #00b7 | | | | L6ab7_player_yaw_angle: ; from 0 - 71 |
#6ab7 | #00b7 | 1 | | | db #1a |
#6ab8 | #00b8 | | | | L6ab8_player_crawling: ; 2 when standing up, 1 when crawling. |
#6ab8 | #00b8 | 1 | | | db 2 |
#6ab9 | #00b9 | | | | L6ab9_player_height: ; player height * room scale |
#6ab9 | #00b9 | 1 | | | db #26 |
#6aba | #00ba | | | | L6aba_max_falling_height_without_damage: ; 2 * room scale |
#6aba | #00ba | 1 | | | db #26 |
#6abb | #00bb | | | | L6abb_max_climbable_height: |
#6abb | #00bb | 1 | | | db #13 |
#6abc | #00bc | | | | L6abc_current_room_scale: |
#6abc | #00bc | 1 | | | db #13 |
#6abd | #00bd | | | | L6abd_cull_by_rendering_volume_flag: |
#6abd | #00bd | 1 | | | db #00 |
#6abe | #00be | | | | L6abe_use_eye_player_coordinate: ; When this is 0, we will use "feet" coordinates for collision checks, when 1, we will use "eye" coordinates. |
#6abe | #00be | 1 | | | db #00 |
#6abf | #00bf | | | | L6abf_current_area_name_string: |
#6abf | #00bf | 16 | | | db 0, " THE CRYPT " |
#6acf | #00cf | | | | L6acf_current_area_id: |
#6acf | #00cf | 1 | | | db #02 |
#6ad0 | #00d0 | | | | L6ad0_current_area_n_objects: |
#6ad0 | #00d0 | 1 | | | db #18 |
#6ad1 | #00d1 | | | | L6ad1_current_area_objects: |
#6ad1 | #00d1 | 2 | | | dw #d6ca |
#6ad3 | #00d3 | | | | |
#6ad3 | #00d3 | 2 | | | db #00, #00 ; unused? |
#6ad5 | #00d5 | | | | L6ad5_current_area_rules: |
#6ad5 | #00d5 | 2 | | | dw #d8ce |
#6ad7 | #00d7 | | | | L6ad7_current_border_color: |
#6ad7 | #00d7 | 2 | | | db #14, #00 |
#6ad9 | #00d9 | | | | L6ad9_current_attribute_color: |
#6ad9 | #00d9 | 2 | | | db #16, #0b |
#6adb | #00db | | | | L6adb_desired_border_color: |
#6adb | #00db | 2 | | | db #14, #00 |
#6add | #00dd | | | | L6add_desired_attribute_color: |
#6add | #00dd | 2 | | | db #47, #0b |
#6adf | #00df | | | | L6adf_game_boolean_variables: |
#6adf | #00df | | | | ; One bit corresponding to each variable. |
#6adf | #00df | | | | ; The first few correspond to collected keys. |
#6adf | #00df | 4 | | | db #00, #00, #00, #00 |
#6ae3 | #00e3 | | | | L6ae3_visited_areas: ; one bit per area (keeps track of which areas the player has already visited). |
#6ae3 | #00e3 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#6aeb | #00eb | | | | L6aeb_score: ; 3 bytes |
#6aeb | #00eb | 3 | | | db #00, #00, #00 |
#6aee | #00ee | | | | L6aee_game_variables: ; These can be accessed by the game scripts. |
#6aee | #00ee | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#6af6 | #00f6 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#6afe | #00fe | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#6b06 | #0106 | 3 | | | db #00, #00, #00 |
#6b09 | #0109 | | | | L6b09_number_of_spirits_destroyed: |
#6b09 | #0109 | 1 | | | db 0 |
#6b0a | #010a | | | | L6b0a_current_strength: |
#6b0a | #010a | 1 | | | db 16 |
#6b0b | #010b | | | | L6b0b_selected_movement_mode: ; 0: crawl, 1: walk, 2: run |
#6b0b | #010b | 1 | | | db 2 |
#6b0c | #010c | | | | L6b0c_num_collected_keys: |
#6b0c | #010c | 1 | | | db 0 |
#6b0d | #010d | | | | L6b0d_new_key_taken: |
#6b0d | #010d | 1 | | | db 0 ; Contains the ID of a key just picked up, before being added to the inventory. |
#6b0e | #010e | | | | L6b0e_lightning_time_seconds_countdown: |
#6b0e | #010e | 1 | | | db #14 |
#6b0f | #010f | | | | L6b0f_collected_keys: |
#6b0f | #010f | | | | ; Different from "L6adf_game_boolean_variables", this array has the keys in |
#6b0f | #010f | | | | ; the order the player picked them, directly as a list of IDs. |
#6b0f | #010f | 10 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#6b19 | #0119 | | | | L6b19_current_area_flags: |
#6b19 | #0119 | 1 | | | db #00 |
#6b1a | #011a | | | | L6b1a_pointer_x: |
#6b1a | #011a | 1 | | | db 0 |
#6b1b | #011b | | | | L6b1b_pointer_y: |
#6b1b | #011b | 1 | | | db 0 |
#6b1c | #011c | | | | L6b1c_movement_or_pointer: |
#6b1c | #011c | 1 | | | db 0 ; 0: movement, otherwise: pointer |
#6b1d | #011d | | | | L6b1d_time_interrupts: |
#6b1d | #011d | 1 | | | db #01 |
#6b1e | #011e | | | | L6b1e_time_unit5: ; Changes once per second, counting from 10 to 1 |
#6b1e | #011e | 1 | | | db #00 |
#6b1f | #011f | | | | L6b1f_current_spirit_meter: ; Increments in 1 each time Lbe65_time_unit3 wraps around (each 120 seconds). |
#6b1f | #011f | 1 | | | db #20 |
#6b20 | #0120 | | | | L6b20_display_movement_pointer_flag: ; Whether to draw a small cross in the center of the screen when in movement mode. |
#6b20 | #0120 | 1 | | | db #ff |
#6b21 | #0121 | | | | L6b21_time_unit6_previous: ; to keep track of when L6b22_time_unit6 changes. |
#6b21 | #0121 | 1 | | | db #00 |
#6b22 | #0122 | | | | L6b22_time_unit6: ; Increments by one each time L6b1e_time_unit5 cycles. |
#6b22 | #0122 | 1 | | | db #00 |
#6b23 | #0123 | | | | L6b23_set_bit7_byte_3_flag_at_start: ; If this is != 0, when starting a game, bit 7 of the 3rd byte of the boolean variables is set to 1 (not sure of the effect of this). |
#6b23 | #0123 | 1 | | | db #00 |
#6b24 | #0124 | | | | L6b24_savegame_data_end: |
#6b24 | #0124 | | | | |
#6b24 | #0124 | 4 | | | db #00, #00, #07, #00 ; Unused? |
#6b28 | #0128 | | | | L6b28_player_radius: |
#6b28 | #0128 | 2 | | | dw #000a |
#6b2a | #012a | | | | L6b2a_spirit_in_room: ; 0: no spirit, 1: spirit |
#6b2a | #012a | 1 | | | db 0 |
#6b2b | #012b | | | | L6b2b_desired_eye_compass_frame: |
#6b2b | #012b | 1 | | | db #00 |
#6b2c | #012c | | | | |
#6b2c | #012c | | | | ; If an object definition has more bytes than this, it means there are rule effects associated with it: |
#6b2c | #012c | | | | L6b2c_expected_object_size_by_type: |
#6b2c | #012c | 16 | | | db #09, #0c, #0e, #0a, #10, #10, #10, #10, #10, #10, #10, #13, #16, #19, #1c, #00 |
#6b3c | #013c | | | | |
#6b3c | #013c | | | | L6b3c_rule_size_by_type: ; Assuming there are only 49 rule types (maximum type if 48). |
#6b3c | #013c | 16 | | | db #01, #04, #02, #02, #02, #02, #03, #03, #03, #02, #02, #03, #02, #02, #03, #02 |
#6b4c | #014c | 16 | | | db #02, #03, #03, #02, #03, #00, #00, #00, #00, #02, #01, #02, #02, #02, #02, #02 |
#6b5c | #015c | 16 | | | db #03, #03, #02, #02, #00, #00, #00, #00, #00, #02, #01, #00, #01, #01, #03, #03 |
#6b6c | #016c | 1 | | | db #02 |
#6b6d | #016d | | | | |
#6b6d | #016d | | | | ; Edges for cubes: |
#6b6d | #016d | | | | L6b6d_cube_edges: |
#6b6d | #016d | 1 | | | db #0c |
#6b6e | #016e | 8 | | | db #00, #01, #01, #02, #02, #03, #03, #00 |
#6b76 | #0176 | 8 | | | db #04, #05, #05, #06, #06, #07, #07, #04 |
#6b7e | #017e | 8 | | | db #00, #04, #01, #05, #02, #06, #03, #07 |
#6b86 | #0186 | | | | |
#6b86 | #0186 | | | | ; byte 0: number of faces |
#6b86 | #0186 | | | | ; Each face then: |
#6b86 | #0186 | | | | ; - byte: texture |
#6b86 | #0186 | | | | ; - byte: number of vertices/edges |
#6b86 | #0186 | | | | ; - bytes 2+: edge indexes from where to get the vertices |
#6b86 | #0186 | | | | ; - the msb in the index indicates if we need to flip the vertexes in the edge in question. |
#6b86 | #0186 | | | | L6b86_face_definition_for_cubes: |
#6b86 | #0186 | 1 | | | db #06 |
#6b87 | #0187 | 6 | | | db #00, #04, #83, #0b, #07, #88 |
#6b8d | #018d | 6 | | | db #00, #04, #05, #8a, #81, #09 |
#6b93 | #0193 | 6 | | | db #00, #04, #08, #04, #89, #80 |
#6b99 | #0199 | 6 | | | db #00, #04, #0a, #06, #8b, #82 |
#6b9f | #019f | 6 | | | db #00, #04, #00, #01, #02, #03 |
#6ba5 | #01a5 | 6 | | | db #00, #04, #84, #87, #86, #85 |
#6bab | #01ab | | | | |
#6bab | #01ab | | | | ; Edges for pyramids: |
#6bab | #01ab | | | | L6bab_pyramid_edges: |
#6bab | #01ab | 1 | | | db #08 |
#6bac | #01ac | 8 | | | db #00, #01, #01, #02, #02, #03, #03, #00 |
#6bb4 | #01b4 | 8 | | | db #00, #04, #01, #04, #02, #04, #03, #04 |
#6bbc | #01bc | | | | |
#6bbc | #01bc | | | | L6bbc_face_definition_for_pyramids: |
#6bbc | #01bc | 1 | | | db #05 |
#6bbd | #01bd | 5 | | | db #00, #03, #83, #07, #84 |
#6bc2 | #01c2 | 5 | | | db #00, #03, #82, #06, #87 |
#6bc7 | #01c7 | 5 | | | db #00, #03, #81, #05, #86 |
#6bcc | #01cc | 5 | | | db #00, #03, #80, #04, #85 |
#6bd1 | #01d1 | 6 | | | db #00, #04, #00, #01, #02, #03 |
#6bd7 | #01d7 | | | | |
#6bd7 | #01d7 | | | | L6bd7_wedge_edges: |
#6bd7 | #01d7 | 1 | | | db #09 |
#6bd8 | #01d8 | 6 | | | db #00, #01, #01, #02, #02, #03 |
#6bde | #01de | 6 | | | db #03, #00, #00, #04, #01, #04 |
#6be4 | #01e4 | 6 | | | db #02, #05, #03, #05, #04, #05 |
#6bea | #01ea | | | | |
#6bea | #01ea | | | | L6bea_face_definition_for_wedges: |
#6bea | #01ea | 1 | | | db #05 |
#6beb | #01eb | 6 | | | db #00, #04, #83, #07, #88, #84 |
#6bf1 | #01f1 | 5 | | | db #00, #03, #82, #06, #87 |
#6bf6 | #01f6 | 6 | | | db #00, #04, #81, #05, #08, #86 |
#6bfc | #01fc | 5 | | | db #00, #03, #80, #04, #85 |
#6c01 | #0201 | 6 | | | db #00, #04, #00, #01, #02, #03 |
#6c07 | #0207 | | | | |
#6c07 | #0207 | | | | L6c07_triangle_houglass_edges: |
#6c07 | #0207 | 1 | | | db #09 |
#6c08 | #0208 | 6 | | | db #00, #01, #01, #02, #02, #03 |
#6c0e | #020e | 6 | | | db #03, #00, #00, #04, #01, #05 |
#6c14 | #0214 | 6 | | | db #02, #05, #03, #04, #04, #05 |
#6c1a | #021a | | | | |
#6c1a | #021a | | | | L6c1a_face_definition_for_triangle_hourglasses: |
#6c1a | #021a | 1 | | | db #05 |
#6c1b | #021b | 5 | | | db #00, #03, #83, #07, #84 |
#6c20 | #0220 | 6 | | | db #00, #04, #82, #06, #88, #87 |
#6c26 | #0226 | 5 | | | db #00, #03, #81, #05, #86 |
#6c2b | #022b | 6 | | | db #00, #04, #80, #04, #08, #85 |
#6c31 | #0231 | 6 | | | db #00, #04, #00, #01, #02, #03 |
#6c37 | #0237 | | | | |
#6c37 | #0237 | | | | L6c37_hourglass_edges: |
#6c37 | #0237 | 1 | | | db #0c |
#6c38 | #0238 | 8 | | | db #00, #01, #01, #02, #02, #03, #03, #00 |
#6c40 | #0240 | 8 | | | db #04, #07, #07, #05, #05, #06, #06, #04 |
#6c48 | #0248 | 8 | | | db #00, #04, #01, #06, #02, #05, #03, #07 |
#6c50 | #0250 | | | | |
#6c50 | #0250 | | | | L6c50_face_definition_for_hourglasses: |
#6c50 | #0250 | 1 | | | db #06 |
#6c51 | #0251 | 6 | | | db #00, #04, #83, #0b, #84, #88 |
#6c57 | #0257 | 6 | | | db #00, #04, #82, #0a, #85, #8b |
#6c5d | #025d | 6 | | | db #00, #04, #81, #09, #86, #8a |
#6c63 | #0263 | 6 | | | db #00, #04, #80, #08, #87, #89 |
#6c69 | #0269 | 6 | | | db #00, #04, #00, #01, #02, #03 |
#6c6f | #026f | 6 | | | db #00, #04, #04, #05, #06, #07 |
#6c75 | #0275 | | | | |
#6c75 | #0275 | | | | ; Edge definition for different shapes (lines, triangles, rectangles and pentagons), |
#6c75 | #0275 | | | | ; - the first byte is the # of edges |
#6c75 | #0275 | | | | ; - after that, each pair of bytes defines an edge. |
#6c75 | #0275 | | | | L6c75_line_edges: |
#6c75 | #0275 | 5 | | | db #02, #00, #01, #01, #00 |
#6c7a | #027a | | | | |
#6c7a | #027a | | | | ; Edges for triangles: |
#6c7a | #027a | | | | L6c7a_triangle_edges_top: |
#6c7a | #027a | 7 | | | db #03, #00, #01, #01, #02, #02, #00 |
#6c81 | #0281 | | | | L6c81_triangle_edges_bottom: |
#6c81 | #0281 | 7 | | | db #03, #00, #02, #02, #01, #01, #00 |
#6c88 | #0288 | | | | |
#6c88 | #0288 | | | | ; Edges for rectangles: |
#6c88 | #0288 | | | | L6c88_rectangle_edges_top: |
#6c88 | #0288 | 9 | | | db #04, #00, #01, #01, #02, #02, #03, #03, #00 |
#6c91 | #0291 | | | | L6c91_rectangle_edges_bottom: |
#6c91 | #0291 | 9 | | | db #04, #00, #03, #03, #02, #02, #01, #01, #00 |
#6c9a | #029a | | | | |
#6c9a | #029a | | | | ; Edges for pentagons: |
#6c9a | #029a | | | | L6c9a_pentagon_edges_top: |
#6c9a | #029a | 11 | | | db #05, #00, #01, #01, #02, #02, #03, #03, #04, #04, #00 |
#6ca5 | #02a5 | | | | L6ca5_pentagon_edges_bottom: |
#6ca5 | #02a5 | 11 | | | db #05, #00, #04, #04, #03, #03, #02, #02, #01, #01, #00 |
#6cb0 | #02b0 | | | | |
#6cb0 | #02b0 | | | | L6cb0_face_definition_for_flat_objects: |
#6cb0 | #02b0 | 1 | | | db #01 |
#6cb1 | #02b1 | 8 | | | db #00, #06, #00, #01, #02, #03, #04, #05 |
#6cb9 | #02b9 | | | | |
#6cb9 | #02b9 | | | | |
#6cb9 | #02b9 | | | | ; -------------------------------- |
#6cb9 | #02b9 | | | | L6cb9_game_text: |
#6cb9 | #02b9 | 16 | | | db 0, " PRESS ANY KEY " |
#6cc9 | #02c9 | | | | L6cc9_text_overpowered: |
#6cc9 | #02c9 | 16 | | | db 0, " OVERPOWERED " |
#6cd9 | #02d9 | 16 | | | db 1, " YOU COLLAPSE " |
#6ce9 | #02e9 | 16 | | | db 0, " CRUSHED " |
#6cf9 | #02f9 | 16 | | | db 1, " FATAL FALL " |
#6d09 | #0309 | 16 | | | db 0, " ESCAPE !! " |
#6d19 | #0319 | 16 | | | db 0, " THE CRYPT " |
#6d29 | #0329 | | | | L6d29_text_out_of_reach: |
#6d29 | #0329 | 16 | | | db 1, " OUT OF REACH " |
#6d39 | #0339 | | | | L6d39_text_no_effect: |
#6d39 | #0339 | 16 | | | db 0, " NO EFFECT " |
#6d49 | #0349 | 16 | | | db 1, " NO ENTRY " |
#6d59 | #0359 | 16 | | | db 0, " WAY BLOCKED " |
#6d69 | #0369 | | | | L6d69_text_not_enough_room: |
#6d69 | #0369 | 16 | | | db 0, "NOT ENOUGH ROOM" |
#6d79 | #0379 | | | | L6d79_text_too_weak: |
#6d79 | #0379 | 16 | | | db 1, " TOO WEAK " |
#6d89 | #0389 | | | | L6d89_text_crawl: |
#6d89 | #0389 | 16 | | | db 1, "CRAWL SELECTED " |
#6d99 | #0399 | | | | L6d99_text_walk: |
#6d99 | #0399 | 16 | | | db 0, " WALK SELECTED " |
#6da9 | #03a9 | | | | L6da9_text_run: |
#6da9 | #03a9 | 16 | | | db 1, " RUN SELECTED " |
#6db9 | #03b9 | 16 | | | db 1, " AAAAAARRRGH! " |
#6dc9 | #03c9 | 16 | | | db 0, " KEY COLLECTED " |
#6dd9 | #03d9 | 16 | | | db 0, " NO KEYS FOUND " |
#6de9 | #03e9 | 16 | | | db 1, "NEED RIGHT KEY " |
#6df9 | #03f9 | 16 | | | db 0, " IT IS EMPTY " |
#6e09 | #0409 | 16 | | | db 1, " DOOR TO... " |
#6e19 | #0419 | 16 | | | db 0, "IN CASE OF FIRE" |
#6e29 | #0429 | 16 | | | db 0, "CHOMP CHOMP AHH" |
#6e39 | #0439 | 16 | | | db 1, " OOOOFFF! " |
#6e49 | #0449 | 16 | | | db 1, "TREASURE FOUND " |
#6e59 | #0459 | 16 | | | db 1, "THE DOOR OPENS " |
#6e69 | #0469 | 16 | | | db 0, "THE DOOR CLOSES" |
#6e79 | #0479 | 16 | | | db 0, " PADLOCKED " |
#6e89 | #0489 | 16 | | | db 0, "IT'S VERY HEAVY" |
#6e99 | #0499 | 16 | | | db 0, " SMASH ! " |
#6ea9 | #04a9 | 16 | | | db 0, "SHOWS LEVEL NO." |
#6eb9 | #04b9 | 16 | | | db 0, " PADLOCKED " |
#6ec9 | #04c9 | 16 | | | db 0, "HMM, NEED A BIT" |
#6ed9 | #04d9 | 16 | | | db 1, "MORE SPRING IN " |
#6ee9 | #04e9 | 16 | | | db 1, "YOUR STEP HERE " |
#6ef9 | #04f9 | 16 | | | db 0, " THE LID OPENS " |
#6f09 | #0509 | 16 | | | db 1, "THE LID CLOSES " |
#6f19 | #0519 | 16 | | | db 1, "GLUG GLUG GLUG " |
#6f29 | #0529 | 16 | | | db 0, "RETRY THE CHEST" |
#6f39 | #0539 | 16 | | | db 1, "REVITALISATION " |
#6f49 | #0549 | | | | L6f49_area_names: |
#6f49 | #0549 | 16 | | | db 1, " WILDERNESS " |
#6f59 | #0559 | 16 | | | db 0, " THE CRYPT " |
#6f69 | #0569 | 16 | | | db 1, "CRYPT CORRIDOR " |
#6f79 | #0579 | 16 | | | db 0, " THE MOUSETRAP " |
#6f89 | #0589 | 16 | | | db 0, " LAST TREASURE " |
#6f99 | #0599 | 16 | | | db 1, " TANTALUS " |
#6fa9 | #05a9 | 16 | | | db 0, " BELENUS " |
#6fb9 | #05b9 | 16 | | | db 0, " POTHOLE " |
#6fc9 | #05c9 | 16 | | | db 0, " THE STEPS " |
#6fd9 | #05d9 | 16 | | | db 1, " LOOKOUT POST " |
#6fe9 | #05e9 | 16 | | | db 1, " KERBEROS " |
#6ff9 | #05f9 | 16 | | | db 0, " CRYPT KEY " |
#7009 | #0609 | 16 | | | db 0, " GATEHOUSE " |
#7019 | #0619 | 16 | | | db 0, " BELENUS KEY " |
#7029 | #0629 | 16 | | | db 1, "SPIRITS' ABODE " |
#7039 | #0639 | 16 | | | db 1, " RAVINE " |
#7049 | #0649 | 16 | | | db 1, " LIFT SHAFT " |
#7059 | #0659 | 16 | | | db 0, " LEVEL 2 KEY " |
#7069 | #0669 | 16 | | | db 0, "LIFT ENTRANCE 6" |
#7079 | #0679 | 16 | | | db 1, " TUNNEL " |
#7089 | #0689 | 16 | | | db 0, " LEVEL 3 KEY " |
#7099 | #0699 | 16 | | | db 1, " THE TUBE " |
#70a9 | #06a9 | 16 | | | db 0, "LIFT ENTRANCE 5" |
#70b9 | #06b9 | 16 | | | db 0, " EPONA " |
#70c9 | #06c9 | 16 | | | db 0, " LEVEL 4 KEY " |
#70d9 | #06d9 | 16 | | | db 0, "LIFT ENTRANCE 4" |
#70e9 | #06e9 | 16 | | | db 0, " NANTOSUELTA " |
#70f9 | #06f9 | 16 | | | db 0, " STALACTITES " |
#7109 | #0709 | 16 | | | db 0, " NO ROOM " |
#7119 | #0719 | 16 | | | db 0, " THE TRAPEZE " |
#7129 | #0729 | 16 | | | db 1, "TREASURE CHEST " |
#7139 | #0739 | 16 | | | db 0, "LIFT ENTRANCE 3" |
#7149 | #0749 | 16 | | | db 1, " THE SWITCH " |
#7159 | #0759 | 16 | | | db 1, " THE PILLAR " |
#7169 | #0769 | 16 | | | db 1, " GROUND FLOOR " |
#7179 | #0779 | 16 | | | db 1, " THE RAT TRAP " |
#7189 | #0789 | 16 | | | db 0, " YIN KEY " |
#7199 | #0799 | 16 | | | db 1, " LIFT " |
#71a9 | #07a9 | 16 | | | db 0, " TRAPEZE KEY " |
#71b9 | #07b9 | 16 | | | db 1, " YANG KEY " |
#71c9 | #07c9 | | | | |
#71c9 | #07c9 | | | | |
#71c9 | #07c9 | | | | ; -------------------------------- |
#71c9 | #07c9 | | | | L71c9_text_status_array: |
#71c9 | #07c9 | 11 | | | db 0, "FEEBLE " |
#71d4 | #07d4 | 11 | | | db 0, "WEAK " |
#71df | #07df | 11 | | | db 0, "HEALTHY " |
#71ea | #07ea | 11 | | | db 0, "STRONG " |
#71f5 | #07f5 | 11 | | | db 0, "MIGHTY " |
#7200 | #0800 | 11 | | | db 0, "HERCULEAN " |
#720b | #080b | | | | |
#720b | #080b | | | | ; -------------------------------- |
#720b | #080b | | | | ; Used to store the filename the user inputs in the load/save menu. |
#720b | #080b | | | | L720b_text_input_buffer: |
#720b | #080b | 14 | | | db 0, " " |
#7219 | #0819 | 1 | | | db 19 ; Unused? |
#721a | #081a | | | | |
#721a | #081a | | | | L721a_text_asterisks: |
#721a | #081a | 22 | | | db 0, "*********************" |
#7230 | #0830 | | | | |
#7230 | #0830 | 13 | | | db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
#723d | #083d | 16 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #30, #72, #30, #72, #30 |
#724d | #084d | 15 | | | db #72, #30, #72, #30, #72, #30, #72, #30, #72, #30, #72, #30, #72, #30, #72 |
#725c | #085c | | | | |
#725c | #085c | | | | |
#725c | #085c | | | | ; -------------------------------- |
#725c | #085c | | | | L725c_videomem_row_pointers: |
#725c | #085c | 16 | | | dw #4084, #4184, #4284, #4384, #4484, #4584, #4684, #4784 |
#726c | #086c | 16 | | | dw #40a4, #41a4, #42a4, #43a4, #44a4, #45a4, #46a4, #47a4 |
#727c | #087c | 16 | | | dw #40c4, #41c4, #42c4, #43c4, #44c4, #45c4, #46c4, #47c4 |
#728c | #088c | 16 | | | dw #40e4, #41e4, #42e4, #43e4, #44e4, #45e4, #46e4, #47e4 |
#729c | #089c | 16 | | | dw #4804, #4904, #4a04, #4b04, #4c04, #4d04, #4e04, #4f04 |
#72ac | #08ac | 16 | | | dw #4824, #4924, #4a24, #4b24, #4c24, #4d24, #4e24, #4f24 |
#72bc | #08bc | 16 | | | dw #4844, #4944, #4a44, #4b44, #4c44, #4d44, #4e44, #4f44 |
#72cc | #08cc | 16 | | | dw #4864, #4964, #4a64, #4b64, #4c64, #4d64, #4e64, #4f64 |
#72dc | #08dc | 16 | | | dw #4884, #4984, #4a84, #4b84, #4c84, #4d84, #4e84, #4f84 |
#72ec | #08ec | 16 | | | dw #48a4, #49a4, #4aa4, #4ba4, #4ca4, #4da4, #4ea4, #4fa4 |
#72fc | #08fc | 16 | | | dw #48c4, #49c4, #4ac4, #4bc4, #4cc4, #4dc4, #4ec4, #4fc4 |
#730c | #090c | 16 | | | dw #48e4, #49e4, #4ae4, #4be4, #4ce4, #4de4, #4ee4, #4fe4 |
#731c | #091c | 16 | | | dw #5004, #5104, #5204, #5304, #5404, #5504, #5604, #5704 |
#732c | #092c | 16 | | | dw #5024, #5124, #5224, #5324, #5424, #5524, #5624, #5724 |
#733c | #093c | | | | |
#733c | #093c | | | | |
#733c | #093c | | | | ; -------------------------------- |
#733c | #093c | | | | ; Unused? |
#733c | #093c | | | | L733c: |
#733c | #093c | 10 | | | db #30, #72, #30, #72, #30, #72, #30, #72, #30, #72 |
#7346 | #0946 | 10 | | | db #30, #72, #30, #72, #30, #72, #30, #72, #30, #72 |
#7350 | #0950 | | | | |
#7350 | #0950 | | | | L7350_compass_eye_ui_row_pointers: |
#7350 | #0950 | | | | ; from (25, 158) to (25, 162) |
#7350 | #0950 | 10 | | | dw #5679, #5779, #5099, #5199, #5299 |
#735a | #095a | | | | |
#735a | #095a | | | | L735a_ui_message_row_pointers: |
#735a | #095a | | | | ; from (11, 176) to (11, 183) |
#735a | #095a | 8 | | | dw #50cb, #51cb, #52cb, #53cb |
#7362 | #0962 | 8 | | | dw #54cb, #55cb, #56cb, #57cb |
#736a | #096a | | | | |
#736a | #096a | | | | L736a_spirit_count_ui_row_pointers: |
#736a | #096a | | | | ; from (14, 152) to (14, 159) |
#736a | #096a | 8 | | | dw #506e, #516e, #526e, #536e |
#7372 | #0972 | 8 | | | dw #546e, #556e, #566e, #576e |
#737a | #097a | | | | |
#737a | #097a | | | | L737a_strength_ui_row_pointers: |
#737a | #097a | | | | ; from (4, 151) to (4, 165) |
#737a | #097a | 8 | | | dw #5744, #5064, #5164, #5264 |
#7382 | #0982 | 8 | | | dw #5364, #5464, #5564, #5664 |
#738a | #098a | 8 | | | dw #5764, #5084, #5184, #5284 |
#7392 | #0992 | 6 | | | dw #5384, #5484, #5584 |
#7398 | #0998 | | | | |
#7398 | #0998 | | | | L7398_key_count_ui_row_pointers: |
#7398 | #0998 | | | | ; from (4, 173) to (4, 186) |
#7398 | #0998 | 8 | | | dw #55a4, #56a4, #57a4, #50c4 |
#73a0 | #09a0 | 8 | | | dw #51c4, #52c4, #53c4, #54c4 |
#73a8 | #09a8 | 8 | | | dw #55c4, #56c4, #57c4, #50e4 |
#73b0 | #09b0 | 4 | | | dw #51e4, #52e4 |
#73b4 | #09b4 | | | | |
#73b4 | #09b4 | | | | L73b4_waving_flag_row_pointers: |
#73b4 | #09b4 | 8 | | | dw #451d, #461d, #471d, #403d |
#73bc | #09bc | 8 | | | dw #413d, #423d, #433d, #443d |
#73c4 | #09c4 | 2 | | | dw #453d |
#73c6 | #09c6 | | | | |
#73c6 | #09c6 | | | | L73c6_cosine_sine_table: |
#73c6 | #09c6 | | | | ; Each "dw" contains (cos, sin) (one byte each): |
#73c6 | #09c6 | | | | ; [-64, 64] |
#73c6 | #09c6 | | | | ; 72 steps is a whole turn. |
#73c6 | #09c6 | 8 | | | dw #4000, #4006, #3f0b, #3e11 |
#73ce | #09ce | 8 | | | dw #3c16, #3a1b, #3720, #3425 |
#73d6 | #09d6 | 8 | | | dw #3129, #2d2d, #2931, #2534 |
#73de | #09de | 8 | | | dw #2037, #1b3a, #163c, #113e |
#73e6 | #09e6 | 8 | | | dw #0b3f, #0640, #0040, #fa40 |
#73ee | #09ee | 8 | | | dw #f53f, #ef3e, #ea3c, #e53a |
#73f6 | #09f6 | 8 | | | dw #e037, #db34, #d731, #d32d |
#73fe | #09fe | 8 | | | dw #cf29, #cc25, #c920, #c61b |
#7406 | #0a06 | 8 | | | dw #c416, #c211, #c10b, #c006 |
#740e | #0a0e | 8 | | | dw #c000, #c0fa, #c1f5, #c2ef |
#7416 | #0a16 | 8 | | | dw #c4ea, #c6e5, #c9e0, #ccdb |
#741e | #0a1e | 8 | | | dw #cfd7, #d3d3, #d7cf, #dbcc |
#7426 | #0a26 | 8 | | | dw #e0c9, #e5c6, #eac4, #efc2 |
#742e | #0a2e | 8 | | | dw #f5c1, #fac0, #00c0, #06c0 |
#7436 | #0a36 | 8 | | | dw #0bc1, #11c2, #16c4, #1bc6 |
#743e | #0a3e | 8 | | | dw #20c9, #25cc, #29cf, #2dd3 |
#7446 | #0a46 | 8 | | | dw #31d7, #34db, #37e0, #3ae5 |
#744e | #0a4e | 8 | | | dw #3cea, #3eef, #3ff5, #40fa |
#7456 | #0a56 | | | | |
#7456 | #0a56 | | | | L7456_player_desired_x: |
#7456 | #0a56 | 2 | | | dw 0 |
#7458 | #0a58 | | | | L7458_player_desired_y: |
#7458 | #0a58 | 2 | | | dw 0 |
#745a | #0a5a | | | | L745a_player_desired_z: |
#745a | #0a5a | 2 | | | dw 0 |
#745c | #0a5c | 1 | | | db #00 ; Unused? |
#745d | #0a5d | | | | L745d_rendering_cube_volume: ; max/min x, max/min y, max/min z (objects outside this will not be rendered). |
#745d | #0a5d | 6 | | | db #00, #00, #00, #00, #00, #00 |
#7463 | #0a63 | | | | L7463_global_area_objects: |
#7463 | #0a63 | 2 | | | dw #d2c6 |
#7465 | #0a65 | | | | L7465_global_area_n_objects: |
#7465 | #0a65 | 1 | | | db #4b |
#7466 | #0a66 | | | | |
#7466 | #0a66 | | | | L7466_need_attribute_refresh_flag: |
#7466 | #0a66 | 1 | | | db 1 |
#7467 | #0a67 | | | | L7467_player_starting_position_object_id: |
#7467 | #0a67 | 1 | | | db #01 |
#7468 | #0a68 | | | | L7468_focus_object_id: |
#7468 | #0a68 | 1 | | | db #01 |
#7469 | #0a69 | | | | L7469_n_spirits_found_in_current_area: |
#7469 | #0a69 | 1 | | | db #00 |
#746a | #0a6a | | | | L746a_current_drawing_texture_id: |
#746a | #0a6a | 1 | | | db #00 |
#746b | #0a6b | | | | L746b_n_objects_to_draw: |
#746b | #0a6b | 1 | | | db #00 |
#746c | #0a6c | | | | L746c_game_flags: |
#746c | #0a6c | 2 | | | db #fd, #ff ; 1st byte : |
#746e | #0a6e | | | | ; - bit 0: ???? |
#746e | #0a6e | | | | ; - bit 1: game over indicator. |
#746e | #0a6e | | | | ; - bit 2: indicates that we need to "reproject" 3d objects to the 2d viewport. |
#746e | #0a6e | | | | ; - bit 3: ???? |
#746e | #0a6e | | | | ; - bit 4/5: trigger redraw of compass eye. |
#746e | #0a6e | | | | ; - bit 6: ???? |
#746e | #0a6e | | | | ; - bit 7: ???? |
#746e | #0a6e | | | | ; 2nd byte: |
#746e | #0a6e | | | | ; - bit 0: ???? |
#746e | #0a6e | | | | ; - bit 1: ???? |
#746e | #0a6e | | | | ; - bit 2: ???? |
#746e | #0a6e | | | | ; - bit 3: trigger a re-render. |
#746e | #0a6e | | | | ; - bit 4: flag to refresh spirit meter. |
#746e | #0a6e | | | | ; - bit 5: in the update function, it triggers waiting until interrupt timer is 0, and then reprints the current room name. |
#746e | #0a6e | | | | ; - bit 6: flag to refresh # of keys in UI. |
#746e | #0a6e | | | | ; - bit 7: flag to redraw keys in the UI. |
#746e | #0a6e | | | | L746e_global_rules_ptr: |
#746e | #0a6e | 2 | | | dw #d11f |
#7470 | #0a70 | | | | L7470_previous_area_id: ; Set when a RULE_TYPE_TELEPORT is triggered, but it is unused. |
#7470 | #0a70 | 1 | | | db #00 |
#7471 | #0a71 | | | | L7471_event_rule_found: ; 1 indicates that a rule for the corresponding event was found (0 otherwise). |
#7471 | #0a71 | 1 | | | db #00 |
#7472 | #0a72 | | | | L7472_symbol_shift_pressed: |
#7472 | #0a72 | 1 | | | db 0 ; 0 = not pressed, 1 = pressed. |
#7473 | #0a73 | | | | L7473_timer_event: ; every time L6b22_time_unit6 changes, this is set to 8. |
#7473 | #0a73 | 1 | | | db #00 |
#7474 | #0a74 | | | | L7474_check_if_object_crushed_player_flag: |
#7474 | #0a74 | 1 | | | db #00 |
#7475 | #0a75 | | | | L7475_call_Lcba4_check_for_player_falling_flag: ; Indicates whether we should call Lcba4_check_for_player_falling this game cycle. |
#7475 | #0a75 | 1 | | | db #01 |
#7476 | #0a76 | | | | L7476_trigger_collision_event_flag: ; If this is "1" after the player has tried to move, it means we collided with an object. |
#7476 | #0a76 | 1 | | | db #00 |
#7477 | #0a77 | | | | L7477_render_buffer_effect: |
#7477 | #0a77 | 1 | | | db #02 |
#7478 | #0a78 | | | | L7478_interrupt_executed_flag: ; some methods use this to wait for the interrupt to be executed. |
#7478 | #0a78 | 1 | | | db #01 |
#7479 | #0a79 | | | | L7479_current_game_state: |
#7479 | #0a79 | | | | ; This is: |
#7479 | #0a79 | | | | ; - 0: for when player is controlling |
#7479 | #0a79 | | | | ; - 1: some times game state is 1 even not at game over (e.g. before game starts). |
#7479 | #0a79 | | | | ; - 1-5: when game is over (and number identifies the reason, including successful escape!) |
#7479 | #0a79 | | | | ; - 6: for when in the load/save/quit menu |
#7479 | #0a79 | 1 | | | db #01 |
#747a | #0a7a | | | | L747a_requested_SFX: |
#747a | #0a7a | 1 | | | db #00 |
#747b | #0a7b | | | | L747b: ; Unused, set to 63 at game start, unused afterwards. |
#747b | #0a7b | 1 | | | db #3f |
#747c | #0a7c | | | | L747c_within_interrupt_flag: |
#747c | #0a7c | 1 | | | db 0 ; This is changed to #80 when we are inside the interrupt. |
#747d | #0a7d | | | | |
#747d | #0a7d | | | | L747d: ; Note: This saves the value of "iy" at game start, and restores it each time tape is accessed. |
#747d | #0a7d | | | | ; But it makes no sense, as the tape load/save functions do not make use of iy. Very strange! |
#747d | #0a7d | 2 | | | dw #5c3a |
#747f | #0a7f | | | | L747f_player_event: ; player events (they can be "or-ed"): 1: moving, 2: interact, 4: trow rock |
#747f | #0a7f | 1 | | | db #00 |
#7480 | #0a80 | | | | L7480_under_pointer_object_ID: ; stores the ID of the object under the player pointer. |
#7480 | #0a80 | 1 | | | db #00 |
#7481 | #0a81 | | | | L7481_n_objects_covering_the_whole_screen: |
#7481 | #0a81 | 1 | | | db 0 |
#7482 | #0a82 | | | | ; Copy of the projected vertex coordinates used by the Lb607_find_object_under_pointer |
#7482 | #0a82 | | | | ; function: |
#7482 | #0a82 | | | | L7482_object_under_pointer__current_face_vertices: |
#7482 | #0a82 | 10 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#748c | #0a8c | 10 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7496 | #0a96 | | | | L7496_current_drawing_primitive_n_vertices: |
#7496 | #0a96 | 1 | | | db #00 |
#7497 | #0a97 | | | | L7497_next_projected_vertex_ptr: ; initialized at 'L67f4_projected_vertex_data', and keeps increasing as we project objects from 3d to 2d. |
#7497 | #0a97 | 2 | | | dw #0000 |
#7499 | #0a99 | | | | L7499_3d_object_bounding_box_relative_to_player_ptr: |
#7499 | #0a99 | 2 | | | dw #0000 |
#749b | #0a9b | | | | L749b_next_object_projected_data_ptr: |
#749b | #0a9b | 2 | | | dw #0000 |
#749d | #0a9d | | | | L749d_object_currently_being_processed_ptr: |
#749d | #0a9d | 2 | | | dw #0000 |
#749f | #0a9f | | | | L749f_number_of_pressed_keys: |
#749f | #0a9f | 1 | | | db #00 |
#74a0 | #0aa0 | | | | L74a0_pressed_keys_buffer: |
#74a0 | #0aa0 | 5 | | | db #ef, #4e, #cd, #77, #66 |
#74a5 | #0aa5 | | | | L74a5_interrupt_timer: |
#74a5 | #0aa5 | 1 | | | db #00 ; Decreases by 1 at each interrupt until reaching 0. It is used by the game to create pauses. |
#74a6 | #0aa6 | | | | L74a6_player_movement_delta: |
#74a6 | #0aa6 | 6 | | | dw #0000, #0000, #0000 |
#74ac | #0aac | | | | ; These two sets of coordinates are used to define the volume the player will traverse when moving. |
#74ac | #0aac | | | | ; It is used because, due to the low frame rate, the player moves in very large steps, and we need |
#74ac | #0aac | | | | ; to ensure small objects are not skipped. |
#74ac | #0aac | | | | L74ac_movement_volume_max_coordinate: |
#74ac | #0aac | 6 | | | dw #0000, #0000, #0000 |
#74b2 | #0ab2 | | | | L74b2_movement_volume_min_coordinate: |
#74b2 | #0ab2 | 6 | | | dw #0000, #0000, #0000 |
#74b8 | #0ab8 | | | | ; These 3 sets of coordinates are used in the "Lab6d_correct_player_movement_if_collision_internal" |
#74b8 | #0ab8 | | | | ; function to store the target movement position after correcting them in case there is a |
#74b8 | #0ab8 | | | | ; collision with an object. |
#74b8 | #0ab8 | | | | L74b8_collision_corrected_coordinates_2: |
#74b8 | #0ab8 | 6 | | | dw #0000, #0000, #0000 |
#74be | #0abe | | | | L74be_collision_corrected_climb_coordinates: |
#74be | #0abe | 6 | | | dw #0000, #0000, #0000 |
#74c4 | #0ac4 | | | | L74c4_collision_corrected_coordinates_1: |
#74c4 | #0ac4 | 6 | | | dw #0000, #0000, #0000 |
#74ca | #0aca | | | | L74ca_movement_target_coordinates_2: ; used when there is falling involved in movement |
#74ca | #0aca | 6 | | | dw #0000, #0000, #0000 |
#74d0 | #0ad0 | | | | L74d0_target_object_climb_coordinates: |
#74d0 | #0ad0 | 2 | | | dw #0000 ; x |
#74d2 | #0ad2 | 2 | | | dw #0000 ; y |
#74d4 | #0ad4 | 2 | | | dw #0000 ; z |
#74d6 | #0ad6 | | | | L74d6_movement_target_coordinates_1: ; used when there is no falling involved in movement |
#74d6 | #0ad6 | 6 | | | dw #0000, #0000, #0000 |
#74dc | #0adc | | | | L74dc_falling_reference_coordinates: |
#74dc | #0adc | 6 | | | dw #0000, #0000, #0000 |
#74e2 | #0ae2 | | | | L74e2_movement_direction_bits: |
#74e2 | #0ae2 | | | | ; bit 0 means negative movement on x, bit 1 means positive movement on y |
#74e2 | #0ae2 | | | | ; bits 2, 3 the same for y, and 4, 5 the same for z. |
#74e2 | #0ae2 | 1 | | | db #00 |
#74e3 | #0ae3 | | | | L74e3_player_height_16bits: ; (L6ab9_player_height) * 64 |
#74e3 | #0ae3 | 2 | | | dw #0000 |
#74e5 | #0ae5 | | | | L74e5_collision_correction_object_shape_type: ; the game prefers 3d shapes to 2d shapes when correcting movement upon collisions. This variable is used to implemetn such preference. |
#74e5 | #0ae5 | 1 | | | db #00 |
#74e6 | #0ae6 | | | | L74e6_movement_involves_falling_flag: ; 0: no falling, 1: we fell |
#74e6 | #0ae6 | 1 | | | db #00 |
#74e7 | #0ae7 | | | | L74e7_closest_object_below_distance: |
#74e7 | #0ae7 | 2 | | | dw #0000 |
#74e9 | #0ae9 | | | | L74e9_closest_object_below_ptr: |
#74e9 | #0ae9 | 2 | | | dw #0000 |
#74eb | #0aeb | | | | L74eb_closest_object_below_ID: |
#74eb | #0aeb | 1 | | | db #00 |
#74ec | #0aec | | | | L74ec_previous_pressed_keys_buffer: |
#74ec | #0aec | 5 | | | db #16, #5e, #3a, #d6, #1f |
#74f1 | #0af1 | | | | L74f1: ; Note: I believe this is unused (written, but never read) |
#74f1 | #0af1 | 1 | | | db #0e |
#74f2 | #0af2 | | | | L74f2_keyboard_input: ; 8 bytes, one per keyboard half row |
#74f2 | #0af2 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#74fa | #0afa | | | | |
#74fa | #0afa | | | | L74fa_object_under_pointer__current_face: ; saves the pointer to the current face we are checking when trying to find which object is under the pointer. |
#74fa | #0afa | 2 | | | dw #0c67 |
#74fc | #0afc | | | | |
#74fc | #0afc | | | | L74fc_object_under_pointer__projected_xs_at_pointer_y: |
#74fc | #0afc | 1 | | | db #18 ; number of points in the lsit below |
#74fd | #0afd | 5 | | | db #f5, #c6, #30, #23, #77 ; screen x coordinates of face edges at the y coordinate of the pointer. |
#7502 | #0b02 | | | | ; Used by the "Lb607_find_object_under_pointer" function, to determine |
#7502 | #0b02 | | | | ; which object is under the player pointer. |
#7502 | #0b02 | | | | |
#7502 | #0b02 | | | | ; -------------------------------- |
#7502 | #0b02 | | | | ; Rendering variables: |
#7502 | #0b02 | | | | L7502_sp_tmp: ; Used to temporarily save the 'sp' register. |
#7502 | #0b02 | 2 | | | dw 0 |
#7504 | #0b04 | | | | L7504_line_drawing_slope: ; Amount we need to move in the X axis each time we move one pixel in the Y axis. |
#7504 | #0b04 | 2 | | | dw #0000 ; Uses fixed point arithmetic (with 8 bits of decimal part). |
#7506 | #0b06 | | | | L7506_polygon_drawing_second_slope: ; When drawing polygons, we calculate two lines at once, and draw |
#7506 | #0b06 | 2 | | | dw #0000 ; horizontal lines between them. This is the slopw of the second line. |
#7508 | #0b08 | | | | L7508_current_drawing_row: |
#7508 | #0b08 | 1 | | | db #00 |
#7509 | #0b09 | | | | L7509_line_drawing_thinning_direction: |
#7509 | #0b09 | 1 | | | db #00 |
#750a | #0b0a | | | | L750a_first_loop_flags: ; Used to indicate if we have drawn at least one pixel when drawing polygons. |
#750a | #0b0a | 1 | | | db #00 |
#750b | #0b0b | | | | L750b_current_drawing_n_vertices_left: ; How many vertices are there to draw in the current primitive. |
#750b | #0b0b | 1 | | | db 0 |
#750c | #0b0c | | | | L750c_current_drawing_row_ptr: |
#750c | #0b0c | 2 | | | dw 0 |
#750e | #0b0e | | | | L750e_current_drawing_texture_ptr: |
#750e | #0b0e | 2 | | | dw 0 |
#7510 | #0b10 | | | | L7510_current_drawing_2d_vertex_buffer: |
#7510 | #0b10 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#7518 | #0b18 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#7520 | #0b20 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#7528 | #0b28 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#7530 | #0b30 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 |
#7538 | #0b38 | | | | |
#7538 | #0b38 | | | | ; -------------------------------- |
#7538 | #0b38 | | | | L7538_text_spaces: |
#7538 | #0b38 | 15 | | | db 0, " " |
#7547 | #0b47 | | | | L7547_text_play_record: |
#7547 | #0b47 | 15 | | | db 0, "PLAY & RECORD," |
#7556 | #0b56 | | | | L7556_text_invalid_file: |
#7556 | #0b56 | 15 | | | db 0, "INVALID FILE " |
#7565 | #0b65 | | | | L7565_text_loading_error: |
#7565 | #0b65 | 15 | | | db 0, "LOADING ERROR " |
#7574 | #0b74 | | | | L7574_text_loading: |
#7574 | #0b74 | 15 | | | db 0, "LOADING : " |
#7583 | #0b83 | | | | L7583_text_then_any_key: |
#7583 | #0b83 | 15 | | | db 0, "THEN ANY KEY " |
#7592 | #0b92 | | | | L7592_text_saving_file: |
#7592 | #0b92 | 15 | | | db 0, "SAVING FILE " |
#75a1 | #0ba1 | | | | L75a1_text_found: |
#75a1 | #0ba1 | 15 | | | db 0, "FOUND : " |
#75b0 | #0bb0 | | | | L75b0_text_searching: |
#75b0 | #0bb0 | 15 | | | db 0, "SEARCHING " |
#75bf | #0bbf | | | | |
#75bf | #0bbf | | | | ; -------------------------------- |
#75bf | #0bbf | | | | L75bf_SFX_table: |
#75bf | #0bbf | 4 | | | db 30, #59, #00, #01 ; 30, 89 (dw), 1 |
#75c3 | #0bc3 | 4 | | | db 18, #47, #00, #01 ; 18, 71 (dw), 1 |
#75c7 | #0bc7 | 4 | | | db 1, #ef, #00, #01 ; 1, 239 (dw), 1 |
#75cb | #0bcb | 4 | | | db 9, #00, #03, #01 ; 9, 768 (dw), 1 |
#75cf | #0bcf | 4 | | | db 2, #00, #00, #01 ; 2, 0 (dw), 1 |
#75d3 | #0bd3 | 4 | | | db 8, #50, #00, #01 ; 8, 90 (dw), 1 |
#75d7 | #0bd7 | 4 | | | db 26, #00, #03, #03 ; 26, 768 (dw), 3 |
#75db | #0bdb | 4 | | | db 11, #02, #00, #01 ; 11, 2 (dw), 1 |
#75df | #0bdf | 4 | | | db 30, #59, #00, #01 ; ... |
#75e3 | #0be3 | 4 | | | db 13, #43, #00, #0c |
#75e7 | #0be7 | 4 | | | db 22, #f7, #09, #01 |
#75eb | #0beb | 4 | | | db 0, #77, #00, #01 |
#75ef | #0bef | 4 | | | db 4, #52, #01, #01 |
#75f3 | #0bf3 | 4 | | | db 28, #96, #00, #08 |
#75f7 | #0bf7 | 4 | | | db 16, #00, #00, #09 |
#75fb | #0bfb | | | | L75fb_SFX_data: |
#75fb | #0bfb | 4 | | | db #01, #17, #01, #01 |
#75ff | #0bff | 4 | | | db #01, #02, #81, #04 |
#7603 | #0c03 | 4 | | | db #81, #2e, #00, #01 |
#7607 | #0c07 | 4 | | | db #00, #14, #00, #00 |
#760b | #0c0b | 4 | | | db #04, #02, #81, #10 |
#760f | #0c0f | 4 | | | db #07, #ff, #0a, #34 |
#7613 | #0c13 | 4 | | | db #ff, #01, #06, #00 |
#7617 | #0c17 | 4 | | | db #02, #00, #00, #00 |
#761b | #0c1b | 4 | | | db #01, #7f, #01, #03 |
#761f | #0c1f | 4 | | | db #81, #4c, #00, #01 |
#7623 | #0c23 | 4 | | | db #00, #f6, #ff, #00 |
#7627 | #0c27 | 4 | | | db #81, #20, #00, #02 |
#762b | #0c2b | 4 | | | db #00, #30, #00, #00 |
#762f | #0c2f | 4 | | | db #03, #06, #00, #01 |
#7633 | #0c33 | 4 | | | db #04, #01, #02, #08 |
#7637 | #0c37 | 4 | | | db #ff, #01, #00, #00 |
#763b | #0c3b | 4 | | | db #80, #07, #02, #00 |
#763f | #0c3f | 4 | | | db #00, #00, #00, #00 |
#7643 | #0c43 | 4 | | | db #05, #02, #7f, #04 |
#7647 | #0c47 | 4 | | | db #02, #7f, #0a, #03 |
#764b | #0c4b | 4 | | | db #7f, #0f, #06, #7f |
#764f | #0c4f | 4 | | | db #10, #06, #7f, #22 |
#7653 | #0c53 | 4 | | | db #04, #02, #81, #43 |
#7657 | #0c57 | 4 | | | db #04, #81, #0a, #08 |
#765b | #0c5b | 4 | | | db #81, #0a, #05, #81 |
#765f | #0c5f | 4 | | | db #09, #00, #00, #00 |
#7663 | #0c63 | 4 | | | db #81, #4c, #00, #01 |
#7667 | #0c67 | 4 | | | db #00, #fa, #ff, #00 |
#766b | #0c6b | 4 | | | db #02, #04, #7f, #02 |
#766f | #0c6f | 4 | | | db #04, #81, #04, #00 |
#7673 | #0c73 | 4 | | | db #04, #03, #7f, #03 |
#7677 | #0c77 | 4 | | | db #04, #7f, #05, #07 |
#767b | #0c7b | 4 | | | db #7f, #06, #06, #00 |
#767f | #0c7f | 4 | | | db #04, #00, #00, #00 |
#7683 | #0c83 | | | | |
#7683 | #0c83 | | | | L7683_control_mode: |
#7683 | #0c83 | 1 | | | db #00 ; Current control mode: |
#7684 | #0c84 | | | | ; 0: keyboard |
#7684 | #0c84 | | | | ; 1: sinclair joystick |
#7684 | #0c84 | | | | ; 2: kempston joystick |
#7684 | #0c84 | | | | ; 3: cursor joystick |
#7684 | #0c84 | | | | |
#7684 | #0c84 | | | | |
#7684 | #0c84 | | | | ; -------------------------------- |
#7684 | #0c84 | | | | ; Input mapping (table that assigns keys to game functions). |
#7684 | #0c84 | | | | L7684_input_mapping: |
#7684 | #0c84 | | | | ; Each row has 3 values: (key, game function while in movement, game function while in pointer) |
#7684 | #0c84 | 3 | | | db "7", INPUT_FORWARD, INPUT_MOVE_POINTER_UP |
#7687 | #0c87 | 3 | | | db "O", INPUT_FORWARD, INPUT_MOVE_POINTER_UP |
#768a | #0c8a | 3 | | | db #91, INPUT_FORWARD, INPUT_MOVE_POINTER_UP |
#768d | #0c8d | 3 | | | db "6", INPUT_BACKWARD, INPUT_MOVE_POINTER_DOWN |
#7690 | #0c90 | 3 | | | db "K", INPUT_BACKWARD, INPUT_MOVE_POINTER_DOWN |
#7693 | #0c93 | 3 | | | db #92, INPUT_BACKWARD, INPUT_MOVE_POINTER_DOWN |
#7696 | #0c96 | 3 | | | db "5", INPUT_TURN_LEFT, INPUT_MOVE_POINTER_LEFT |
#7699 | #0c99 | 3 | | | db "Z", INPUT_TURN_LEFT, INPUT_MOVE_POINTER_LEFT |
#769c | #0c9c | 3 | | | db #93, INPUT_TURN_LEFT, INPUT_MOVE_POINTER_LEFT |
#769f | #0c9f | 3 | | | db "8", INPUT_TURN_RIGHT, INPUT_MOVE_POINTER_RIGHT |
#76a2 | #0ca2 | 3 | | | db "X", INPUT_TURN_RIGHT, INPUT_MOVE_POINTER_RIGHT |
#76a5 | #0ca5 | 3 | | | db #94, INPUT_TURN_RIGHT, INPUT_MOVE_POINTER_RIGHT |
#76a8 | #0ca8 | | | | ; Each row has 2 values: (key, game function) |
#76a8 | #0ca8 | 2 | | | db "0", INPUT_THROW_ROCK |
#76aa | #0caa | 2 | | | db #95, INPUT_THROW_ROCK |
#76ac | #0cac | 2 | | | db "B", INPUT_MOVEMENT_POINTER_ON_OFF |
#76ae | #0cae | 2 | | | db "C", INPUT_CRAWL |
#76b0 | #0cb0 | 2 | | | db "W", INPUT_WALK |
#76b2 | #0cb2 | 2 | | | db "R", INPUT_RUN |
#76b4 | #0cb4 | 2 | | | db " ", INPUT_SWITCH_BETWEEN_MOVEMENT_AND_POINTER |
#76b6 | #0cb6 | 2 | | | db "A", INPUT_ACTION |
#76b8 | #0cb8 | 2 | | | db "U", INPUT_U_TURN |
#76ba | #0cba | 2 | | | db "F", INPUT_FACE_FORWARD |
#76bc | #0cbc | 2 | | | db "P", INPUT_LOOK_UP |
#76be | #0cbe | 2 | | | db "L", INPUT_LOOK_DOWN |
#76c0 | #0cc0 | 2 | | | db "I", INPUT_INFO_MENU |
#76c2 | #0cc2 | | | | |
#76c2 | #0cc2 | | | | ; Temporary sprite attribute buffer for method Lcc19_draw_viewport_sprite_with_offset: |
#76c2 | #0cc2 | | | | L76c2_buffer_sprite_x: |
#76c2 | #0cc2 | 1 | | | db 0 |
#76c3 | #0cc3 | | | | L76c3_buffer_sprite_y: |
#76c3 | #0cc3 | 1 | | | db 0 |
#76c4 | #0cc4 | | | | L76c4_buffer_sprite_width: |
#76c4 | #0cc4 | 1 | | | db 0 |
#76c5 | #0cc5 | | | | L76c5_buffer_sprite_height: |
#76c5 | #0cc5 | 1 | | | db 0 |
#76c6 | #0cc6 | | | | L76c6_buffer_sprite_ptr: |
#76c6 | #0cc6 | 2 | | | dw #0000 |
#76c8 | #0cc8 | | | | L76c8_buffer_sprite_bytes_to_skip_at_start: |
#76c8 | #0cc8 | 1 | | | db #00 |
#76c9 | #0cc9 | 1 | | | db #00 ; unused |
#76ca | #0cca | | | | L76ca_bytes_to_skip_after_row: |
#76ca | #0cca | 1 | | | db #00 |
#76cb | #0ccb | 1 | | | db #00 ; unused |
#76cc | #0ccc | | | | |
#76cc | #0ccc | | | | L76cc_ui_key_bg_sprite: |
#76cc | #0ccc | 3 | | | db 6, 14, #ff ; width, height, and-mask |
#76cf | #0ccf | 2 | | | dw 84 ; frame size |
#76d1 | #0cd1 | 6 | | | db #63, #ff, #ff, #ff, #ff, #f8 |
#76d7 | #0cd7 | 6 | | | db #41, #ff, #ff, #ff, #ff, #f0 |
#76dd | #0cdd | 6 | | | db #41, #ff, #ff, #ff, #ff, #f0 |
#76e3 | #0ce3 | 6 | | | db #54, #00, #00, #00, #00, #05 |
#76e9 | #0ce9 | 6 | | | db #40, #00, #00, #00, #00, #00 |
#76ef | #0cef | 6 | | | db #55, #55, #55, #55, #55, #55 |
#76f5 | #0cf5 | 6 | | | db #41, #ff, #ff, #ff, #ff, #f0 |
#76fb | #0cfb | 6 | | | db #41, #ff, #ff, #ff, #ff, #f0 |
#7701 | #0d01 | 6 | | | db #63, #ff, #ff, #ff, #ff, #f8 |
#7707 | #0d07 | 6 | | | db #7f, #ff, #ff, #ff, #ff, #ff |
#770d | #0d0d | 6 | | | db #bf, #ff, #ff, #ff, #ff, #ff |
#7713 | #0d13 | 6 | | | db #aa, #ba, #aa, #af, #ba, #a8 |
#7719 | #0d19 | 6 | | | db #27, #47, #7e, #aa, #aa, #aa |
#771f | #0d1f | 6 | | | db #55, #55, #75, #55, #55, #55 ;  |
#7725 | #0d25 | | | | |
#7725 | #0d25 | | | | L7725_ui_key_sprite: |
#7725 | #0d25 | 3 | | | db 1, 14, #fc ; width, height, and-mask |
#7728 | #0d28 | 2 | | | dw 14 ; frame size |
#772a | #0d2a | 14 | | | db #fc, #80, #b8, #08, #08, #f8, #80, #ec, #ec, #ec, #ec, #74, #34, #74 ;  |
#7738 | #0d38 | | | | |
#7738 | #0d38 | | | | L7738_ui_spirit_meter_bg_sprite: |
#7738 | #0d38 | 3 | | | db 8, 8, #ff ; width, height, and-mask |
#773b | #0d3b | 2 | | | dw 72 ; frame size |
#773d | #0d3d | | | | ; Note: this value is wrong, it should be 64, but it does not matter, as there is only one frame in this sprite. |
#773d | #0d3d | 8 | | | db #ff, #ff, #ff, #ff, #ff, #ff, #ff, #ff |
#7745 | #0d45 | 8 | | | db #ff, #ff, #ff, #ff, #ff, #ff, #ff, #ff |
#774d | #0d4d | 8 | | | db #ff, #ff, #ff, #ff, #ff, #ff, #ff, #ff |
#7755 | #0d55 | 8 | | | db #fb, #ff, #ff, #ff, #ff, #ff, #fd, #ff |
#775d | #0d5d | 8 | | | db #ff, #ff, #ff, #ff, #ff, #ff, #df, #ff |
#7765 | #0d65 | 8 | | | db #ff, #ef, #ff, #bf, #ef, #ff, #ff, #bb |
#776d | #0d6d | 8 | | | db #ff, #7f, #f7, #ff, #ff, #fe, #ff, #ff |
#7775 | #0d75 | 8 | | | db #ff, #ff, #ff, #ff, #ff, #ff, #ff, #ff ;  |
#777d | #0d7d | | | | |
#777d | #0d7d | | | | L777d_ui_spirit_meter_indicator_sprite: |
#777d | #0d7d | 3 | | | db 2, 8, #fc ; width, height, and-mask |
#7780 | #0d80 | 2 | | | dw 16 ; frame size |
#7782 | #0d82 | 8 | | | db #f0, #3f, #c0, #0f, #82, #87, #01, #43 |
#778a | #0d8a | 8 | | | db #00, #03, #80, #07, #c0, #0f, #f0, #3f ;  |
#7792 | #0d92 | | | | |
#7792 | #0d92 | | | | L7792_ui_compass_eye_sprites: |
#7792 | #0d92 | 3 | | | db 2, 5, #ff |
#7795 | #0d95 | 2 | | | dw 10 |
#7797 | #0d97 | 10 | | | db #00, #fc, #43, #df, #73, #87, #43, #cf, #00, #fc ;  |
#77a1 | #0da1 | 10 | | | db #00, #dc, #43, #87, #73, #cf, #43, #ff, #00, #fc ;  |
#77ab | #0dab | 10 | | | db #00, #fc, #43, #ff, #73, #df, #43, #87, #00, #cc ;  |
#77b5 | #0db5 | 10 | | | db #00, #fc, #43, #7f, #72, #1f, #43, #3f, #01, #fc ;  |
#77bf | #0dbf | 10 | | | db #00, #fc, #43, #f7, #73, #e1, #43, #f3, #00, #fc ;  |
#77c9 | #0dc9 | 10 | | | db #00, #00, #40, #d8, #73, #87, #43, #cf, #00, #fc ;  |
#77d3 | #0dd3 | 10 | | | db #00, #00, #40, #00, #71, #8c, #43, #cf, #00, #fc ;  |
#77dd | #0ddd | 10 | | | db #00, #00, #40, #00, #70, #00, #43, #ce, #00, #fc ;  |
#77e7 | #0de7 | 10 | | | db #00, #00, #40, #00, #70, #00, #40, #00, #00, #00 ;  |
#77f1 | #0df1 | 10 | | | db #00, #fc, #43, #cf, #73, #87, #43, #cf, #00, #fc ;  |
#77fb | #0dfb | 10 | | | db #00, #fc, #43, #ff, #73, #cf, #43, #cf, #00, #fc ;  |
#7805 | #0e05 | | | | |
#7805 | #0e05 | | | | L7805_ui_strength_bg_sprite: |
#7805 | #0e05 | 3 | | | db 9, 15, #ff ; width, height, and-mask |
#7808 | #0e08 | 2 | | | dw 135 ; frame size |
#780a | #0e0a | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7813 | #0e13 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#781c | #0e1c | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7825 | #0e25 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#782e | #0e2e | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7837 | #0e37 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7840 | #0e40 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7849 | #0e49 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7852 | #0e52 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#785b | #0e5b | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#7864 | #0e64 | 9 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00 |
#786d | #0e6d | 9 | | | db #00, #00, #15, #55, #55, #55, #50, #00, #00 |
#7876 | #0e76 | 9 | | | db #0a, #aa, #aa, #aa, #aa, #aa, #aa, #aa, #a0 |
#787f | #0e7f | 9 | | | db #1f, #ff, #ff, #ff, #ff, #ff, #ff, #ff, #f8 |
#7888 | #0e88 | 9 | | | db #3f, #ff, #ff, #ff, #ff, #ff, #ff, #ff, #fc ;  |
#7891 | #0e91 | | | | |
#7891 | #0e91 | | | | L7891_ui_strength_bar_sprite: |
#7891 | #0e91 | 3 | | | db 9, 3, #ff |
#7894 | #0e94 | 2 | | | dw 27 |
#7896 | #0e96 | 9 | | | db #1f, #ff, #ff, #ff, #ff, #ff, #ff, #ff, #f8 |
#789f | #0e9f | 9 | | | db #1f, #ff, #ff, #ff, #ff, #ff, #ff, #ff, #f8 |
#78a8 | #0ea8 | 9 | | | db #0a, #aa, #aa, #aa, #aa, #aa, #aa, #aa, #a8 ;  |
#78b1 | #0eb1 | | | | |
#78b1 | #0eb1 | | | | L78b1_ui_strength_weight_sprite: |
#78b1 | #0eb1 | 3 | | | db #01, #0f, #f0 |
#78b4 | #0eb4 | 2 | | | dw #000f |
#78b6 | #0eb6 | 15 | | | db #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #40, #20 ;  |
#78c5 | #0ec5 | 15 | | | db #00, #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #60, #40, #20, #f0 ;  |
#78d4 | #0ed4 | 15 | | | db #00, #00, #60, #60, #60, #60, #60, #60, #60, #60, #60, #40, #20, #f0, #f0 ;  |
#78e3 | #0ee3 | 15 | | | db #00, #00, #00, #60, #60, #60, #60, #60, #60, #60, #40, #20, #f0, #f0, #f0 ;  |
#78f2 | #0ef2 | | | | |
#78f2 | #0ef2 | | | | L78f2_background_mountains_gfx: |
#78f2 | #0ef2 | 16 | | | db #06, #00, #00, #10, #00, #00, #00, #00, #00, #00, #0c, #00, #00, #00, #00, #00 |
#7902 | #0f02 | 16 | | | db #0b, #00, #00, #38, #01, #a0, #00, #00, #00, #00, #1e, #30, #00, #00, #00, #00 |
#7912 | #0f12 | 16 | | | db #17, #80, #00, #7c, #03, #d0, #00, #00, #01, #00, #3f, #5c, #80, #00, #18, #00 |
#7922 | #0f22 | 16 | | | db #23, #c0, #00, #fe, #0d, #fe, #06, #00, #02, #80, #7e, #be, #c0, #00, #3c, #00 |
#7932 | #0f32 | 16 | | | db #47, #e0, #01, #57, #56, #ff, #0f, #80, #05, #40, #f5, #fb, #40, #00, #76, #00 |
#7942 | #0f42 | 16 | | | db #93, #d0, #0a, #ab, #ab, #ff, #af, #c3, #2a, #a1, #eb, #fe, #a8, #00, #de, #00 |
#7952 | #0f52 | 16 | | | db #21, #a8, #75, #55, #41, #ff, #d6, #ef, #d5, #53, #57, #fc, #14, #01, #b7, #07 |
#7962 | #0f62 | 16 | | | db #42, #d5, #ea, #aa, #92, #fb, #eb, #ab, #ea, #aa, #ae, #fa, #4a, #82, #ea, #be |
#7972 | #0f72 | 16 | | | db #97, #ab, #d5, #55, #25, #dd, #75, #45, #f5, #55, #7d, #dd, #25, #55, #d5, #54 |
#7982 | #0f82 | 16 | | | db #2f, #f7, #aa, #aa, #53, #ea, #a8, #13, #fa, #aa, #ea, #be, #42, #ab, #aa, #a9 |
#7992 | #0f92 | 16 | | | db #5f, #dd, #d5, #55, #07, #55, #02, #45, #fd, #51, #55, #57, #15, #57, #d5, #52 |
#79a2 | #0fa2 | 16 | | | db #af, #ee, #fa, #aa, #2b, #aa, #80, #8b, #fe, #aa, #aa, #ae, #aa, #be, #aa, #a4 |
#79b2 | #0fb2 | 16 | | | db #5a, #b5, #5d, #5c, #56, #d5, #29, #1f, #ff, #55, #55, #5b, #55, #7d, #55, #09 |
#79c2 | #0fc2 | 16 | | | db #b5, #5a, #af, #ba, #ad, #aa, #92, #3e, #bf, #ea, #aa, #af, #ab, #ea, #aa, #02 |
#79d2 | #0fd2 | 16 | | | db #5a, #f5, #55, #fd, #57, #55, #05, #5f, #57, #fd, #55, #55, #57, #55, #50, #15 |
#79e2 | #0fe2 | 16 | | | db #af, #ba, #aa, #fe, #ae, #fa, #aa, #be, #aa, #bf, #aa, #aa, #aa, #aa, #82, #aa |
#79f2 | #0ff2 | 16 | | | db #55, #55, #55, #5f, #d5, #fd, #55, #55, #55, #5f, #fd, #55, #55, #55, #55, #55 |
#7a02 | #1002 | 16 | | | db #ea, #aa, #aa, #aa, #aa, #aa, #aa, #aa, #aa, #aa, #ff, #ff, #ff, #ff, #ff, #ff ;  |
#7a12 | #1012 | | | | |
#7a12 | #1012 | | | | L7a12_waving_flag_gfx_properties: |
#7a12 | #1012 | 3 | | | db 3, 9, #ff ; width (in bytes), height, and-mask of last byte |
#7a15 | #1015 | 2 | | | dw 27 ; 3 * 9 (bytes of each frame) |
#7a17 | #1017 | | | | ; Waving flag frame 1: |
#7a17 | #1017 | 3 | | | db #00, #03, #f6 |
#7a1a | #101a | 3 | | | db #00, #07, #fe |
#7a1d | #101d | 3 | | | db #07, #ff, #f6 |
#7a20 | #1020 | 3 | | | db #01, #ff, #f6 |
#7a23 | #1023 | 3 | | | db #00, #7f, #f6 |
#7a26 | #1026 | 3 | | | db #00, #1f, #f6 |
#7a29 | #1029 | 3 | | | db #01, #ff, #f6 |
#7a2c | #102c | 3 | | | db #03, #ff, #7e |
#7a2f | #102f | 3 | | | db #03, #9f, #06 ;  |
#7a32 | #1032 | | | | ; Waving flag frame 2: |
#7a32 | #1032 | 3 | | | db #00, #1f, #06 |
#7a35 | #1035 | 3 | | | db #00, #3f, #fe |
#7a38 | #1038 | 3 | | | db #0f, #ff, #f6 |
#7a3b | #103b | 3 | | | db #01, #ff, #f6 |
#7a3e | #103e | 3 | | | db #00, #7f, #f6 |
#7a41 | #1041 | 3 | | | db #00, #3f, #f6 |
#7a44 | #1044 | 3 | | | db #01, #ff, #f6 |
#7a47 | #1047 | 3 | | | db #03, #f9, #fe |
#7a4a | #104a | 3 | | | db #0f, #f0, #06 ;  |
#7a4d | #104d | | | | ; Waving flag frame 3: |
#7a4d | #104d | 3 | | | db #00, #7e, #06 |
#7a50 | #1050 | 3 | | | db #01, #ff, #1e |
#7a53 | #1053 | 3 | | | db #07, #ff, #f6 |
#7a56 | #1056 | 3 | | | db #00, #ff, #f6 |
#7a59 | #1059 | 3 | | | db #00, #3f, #f6 |
#7a5c | #105c | 3 | | | db #01, #ff, #f6 |
#7a5f | #105f | 3 | | | db #07, #ff, #f6 |
#7a62 | #1062 | 3 | | | db #0f, #87, #fe |
#7a65 | #1065 | 3 | | | db #00, #01, #e6 ;  |
#7a68 | #1068 | | | | ; Waving flag frame 4: |
#7a68 | #1068 | 3 | | | db #00, #00, #7e |
#7a6b | #106b | 3 | | | db #01, #fd, #f6 |
#7a6e | #106e | 3 | | | db #07, #ff, #f6 |
#7a71 | #1071 | 3 | | | db #00, #7f, #f6 |
#7a74 | #1074 | 3 | | | db #00, #1f, #f6 |
#7a77 | #1077 | 3 | | | db #00, #3f, #f6 |
#7a7a | #107a | 3 | | | db #00, #ff, #f6 |
#7a7d | #107d | 3 | | | db #07, #ff, #fe |
#7a80 | #1080 | 3 | | | db #0f, #1f, #06 ;  |
#7a83 | #1083 | | | | |
#7a83 | #1083 | | | | ; -------------------------------- |
#7a83 | #1083 | | | | ; Unused graphics? |
#7a83 | #1083 | | | | L7a83: |
#7a83 | #1083 | 3 | | | db #0f, #ff, #f0 |
#7a86 | #1086 | 3 | | | db #08, #00, #10 |
#7a89 | #1089 | 3 | | | db #09, #ff, #90 |
#7a8c | #108c | 3 | | | db #09, #00, #90 ;  |
#7a8f | #108f | | | | |
#7a8f | #108f | | | | L7a8f: |
#7a8f | #108f | 5 | | | db #01, #07, #ff, #07, #00 ;  |
#7a94 | #1094 | | | | L7a94: |
#7a94 | #1094 | 7 | | | db #7e, #c3, #81, #81, #81, #c3, #7e ;  |
#7a9b | #109b | | | | |
#7a9b | #109b | | | | ; -------------------------------- |
#7a9b | #109b | | | | L7a9b_lightning_gfx: |
#7a9b | #109b | 4 | | | db #00, #40, #00, #40 |
#7a9f | #109f | 4 | | | db #00, #40, #00, #40 |
#7aa3 | #10a3 | 4 | | | db #00, #40, #00, #40 |
#7aa7 | #10a7 | 4 | | | db #00, #40, #00, #80 |
#7aab | #10ab | 4 | | | db #01, #80, #01, #00 |
#7aaf | #10af | 4 | | | db #01, #00, #02, #00 |
#7ab3 | #10b3 | 4 | | | db #04, #00, #08, #00 |
#7ab7 | #10b7 | 4 | | | db #18, #00, #10, #00 |
#7abb | #10bb | 4 | | | db #30, #00, #20, #00 |
#7abf | #10bf | 4 | | | db #20, #00, #20, #00 |
#7ac3 | #10c3 | 4 | | | db #70, #00, #50, #00 |
#7ac7 | #10c7 | 4 | | | db #50, #00, #88, #00 |
#7acb | #10cb | 4 | | | db #08, #00, #04, #00 |
#7acf | #10cf | 4 | | | db #02, #00, #02, #00 |
#7ad3 | #10d3 | 4 | | | db #01, #00, #01, #00 |
#7ad7 | #10d7 | 4 | | | db #01, #00, #00, #80 |
#7adb | #10db | 4 | | | db #00, #c0, #00, #40 |
#7adf | #10df | 4 | | | db #00, #20, #00, #10 |
#7ae3 | #10e3 | 4 | | | db #00, #08, #00, #0c |
#7ae7 | #10e7 | 4 | | | db #00, #1c, #00, #32 |
#7aeb | #10eb | 4 | | | db #00, #22, #00, #c2 |
#7aef | #10ef | 4 | | | db #01, #81, #02, #01 |
#7af3 | #10f3 | 4 | | | db #02, #00, #02, #00 |
#7af7 | #10f7 | 4 | | | db #02, #00, #02, #00 |
#7afb | #10fb | 4 | | | db #02, #00, #02, #00 |
#7aff | #10ff | 4 | | | db #06, #00, #04, #00 |
#7b03 | #1103 | 4 | | | db #04, #00, #0c, #00 |
#7b07 | #1107 | 4 | | | db #18, #00, #30, #00 |
#7b0b | #110b | 4 | | | db #20, #00, #20, #00 |
#7b0f | #110f | 4 | | | db #70, #00, #4c, #00 |
#7b13 | #1113 | 4 | | | db #86, #00, #02, #00 |
#7b17 | #1117 | 4 | | | db #01, #00, #01, #00 |
#7b1b | #111b | 4 | | | db #00, #80, #00, #80 |
#7b1f | #111f | 4 | | | db #00, #80, #00, #80 |
#7b23 | #1123 | 4 | | | db #00, #80, #00, #80 |
#7b27 | #1127 | 4 | | | db #00, #80, #00, #60 |
#7b2b | #112b | 4 | | | db #00, #30, #00, #08 |
#7b2f | #112f | 4 | | | db #00, #08, #00, #06 |
#7b33 | #1133 | 4 | | | db #00, #02, #00, #02 |
#7b37 | #1137 | 4 | | | db #00, #02, #00, #02 |
#7b3b | #113b | 4 | | | db #00, #02, #00, #02 |
#7b3f | #113f | 4 | | | db #00, #03, #00, #01 |
#7b43 | #1143 | 4 | | | db #00, #01, #00, #00 ;  |
#7b47 | #1147 | | | | |
#7b47 | #1147 | | | | |
#7b47 | #1147 | | | | ; -------------------------------- |
#7b47 | #1147 | | | | ; Each block of 8 bytes correspods to a character. So, this includes |
#7b47 | #1147 | | | | ; a definition of the font being used, the first character is ' ': |
#7b47 | #1147 | | | | ; these tags inside comments are used to visualize the gfx using MDL with the "-mdl-asm+:html" flag. |
#7b47 | #1147 | | | | L7b47_font: |
#7b47 | #1147 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 ;  |
#7b4f | #114f | 8 | | | db #1c, #1c, #1c, #18, #18, #00, #18, #18 ;  |
#7b57 | #1157 | 8 | | | db #66, #66, #44, #22, #00, #00, #00, #00 ;  |
#7b5f | #115f | 8 | | | db #00, #7f, #7f, #7f, #7f, #7f, #7f, #00 ;  |
#7b67 | #1167 | 8 | | | db #10, #54, #38, #fe, #38, #54, #10, #00 ;  |
#7b6f | #116f | 8 | | | db #3c, #42, #9d, #b1, #b1, #9d, #42, #3c ;  |
#7b77 | #1177 | 8 | | | db #78, #cc, #cc, #78, #db, #cf, #ce, #7b ;  |
#7b7f | #117f | 8 | | | db #30, #30, #10, #20, #00, #00, #00, #00 ;  |
#7b87 | #1187 | 8 | | | db #10, #20, #40, #40, #40, #40, #20, #10 ;  |
#7b8f | #118f | 8 | | | db #10, #08, #04, #04, #04, #04, #08, #10 ;  |
#7b97 | #1197 | 8 | | | db #10, #54, #38, #fe, #38, #54, #10, #00 ;  |
#7b9f | #119f | 8 | | | db #00, #00, #10, #10, #7c, #10, #10, #00 ;  |
#7ba7 | #11a7 | 8 | | | db #00, #00, #00, #00, #18, #18, #08, #10 ;  |
#7baf | #11af | 8 | | | db #00, #00, #00, #00, #3c, #00, #00, #00 ;  |
#7bb7 | #11b7 | 8 | | | db #00, #00, #00, #00, #00, #00, #18, #18 ;  |
#7bbf | #11bf | 8 | | | db #01, #02, #04, #08, #10, #20, #40, #80 ;  |
#7bc7 | #11c7 | 8 | | | db #18, #66, #c3, #c3, #c3, #c3, #66, #18 ;  |
#7bcf | #11cf | 8 | | | db #18, #38, #18, #18, #18, #18, #18, #18 ;  |
#7bd7 | #11d7 | 8 | | | db #9e, #61, #01, #7e, #e0, #c6, #e3, #fe ;  |
#7bdf | #11df | 8 | | | db #ee, #73, #03, #3e, #03, #01, #7f, #e6 ;  |
#7be7 | #11e7 | 8 | | | db #0e, #1c, #38, #71, #fd, #e6, #0c, #0c ;  |
#7bef | #11ef | 8 | | | db #fd, #86, #80, #7e, #07, #63, #c7, #7c ;  |
#7bf7 | #11f7 | 8 | | | db #3d, #66, #c0, #f0, #fc, #c6, #66, #3c ;  |
#7bff | #11ff | 8 | | | db #b3, #4e, #06, #0c, #0c, #18, #18, #3c ;  |
#7c07 | #1207 | 8 | | | db #7c, #c6, #c6, #7c, #c6, #c2, #fe, #4c ;  |
#7c0f | #120f | 8 | | | db #3c, #4e, #c6, #c6, #4e, #36, #46, #3c ;  |
#7c17 | #1217 | 8 | | | db #00, #18, #18, #00, #00, #18, #18, #00 ;  |
#7c1f | #121f | 8 | | | db #00, #18, #18, #00, #00, #18, #08, #10 ;  |
#7c27 | #1227 | 8 | | | db #03, #0c, #30, #c0, #30, #0c, #03, #00 ;  |
#7c2f | #122f | 8 | | | db #00, #00, #ff, #00, #ff, #00, #00, #00 ;  |
#7c37 | #1237 | 8 | | | db #c0, #30, #0c, #03, #0c, #30, #c0, #00 ;  |
#7c3f | #123f | 8 | | | db #7c, #c6, #06, #0c, #30, #30, #00, #30 ;  |
#7c47 | #1247 | 8 | | | db #00, #08, #0c, #fe, #ff, #fe, #0c, #08 ;  |
#7c4f | #124f | 8 | | | db #1e, #1c, #1e, #66, #be, #26, #43, #e3 ;  |
#7c57 | #1257 | 8 | | | db #ee, #73, #23, #3e, #23, #21, #7f, #e6 ;  |
#7c5f | #125f | 8 | | | db #39, #6e, #c6, #c0, #c0, #c2, #63, #3e ;  |
#7c67 | #1267 | 8 | | | db #ec, #72, #23, #23, #23, #23, #72, #ec ;  |
#7c6f | #126f | 8 | | | db #ce, #7f, #61, #6c, #78, #61, #7f, #ce ;  |
#7c77 | #1277 | 8 | | | db #ce, #7f, #61, #6c, #78, #60, #60, #f0 ;  |
#7c7f | #127f | 8 | | | db #3d, #66, #c0, #c1, #ce, #c6, #66, #3c ;  |
#7c87 | #1287 | 8 | | | db #e7, #66, #66, #6e, #76, #66, #66, #e7 ;  |
#7c8f | #128f | 8 | | | db #66, #3c, #18, #18, #18, #18, #3c, #66 ;  |
#7c97 | #1297 | 8 | | | db #33, #1e, #0c, #8c, #4c, #cc, #dc, #78 ;  |
#7c9f | #129f | 8 | | | db #f2, #67, #64, #68, #7e, #66, #66, #f3 ;  |
#7ca7 | #12a7 | 8 | | | db #d8, #70, #60, #60, #66, #61, #f3, #7e ;  |
#7caf | #12af | 8 | | | db #c3, #66, #6e, #76, #56, #46, #46, #ef ;  |
#7cb7 | #12b7 | 8 | | | db #87, #62, #72, #7a, #5e, #4e, #46, #e1 ;  |
#7cbf | #12bf | 8 | | | db #18, #66, #c3, #c3, #c3, #c3, #66, #18 ;  |
#7cc7 | #12c7 | 8 | | | db #ec, #72, #63, #63, #72, #6c, #60, #f0 ;  |
#7ccf | #12cf | 8 | | | db #3c, #66, #c3, #c3, #66, #3c, #31, #1e ;  |
#7cd7 | #12d7 | 8 | | | db #ec, #72, #63, #63, #76, #6c, #66, #f1 ;  |
#7cdf | #12df | 8 | | | db #79, #86, #80, #7e, #07, #63, #c7, #7c ;  |
#7ce7 | #12e7 | 8 | | | db #01, #7f, #fe, #98, #58, #18, #18, #3c ;  |
#7cef | #12ef | 8 | | | db #f7, #62, #62, #62, #62, #62, #f2, #3c ;  |
#7cf7 | #12f7 | 8 | | | db #f3, #61, #72, #72, #32, #32, #1c, #3e ;  |
#7cff | #12ff | 8 | | | db #c3, #62, #62, #6a, #6e, #76, #66, #c3 ;  |
#7d07 | #1307 | 8 | | | db #f3, #72, #3c, #38, #1c, #3c, #4e, #cf ;  |
#7d0f | #130f | 8 | | | db #e3, #72, #34, #38, #18, #18, #18, #3c ;  |
#7d17 | #1317 | 8 | | | db #7f, #87, #0e, #1c, #38, #71, #fd, #e6 ;  |
#7d1f | #131f | | | | |
#7d1f | #131f | | | | |
#7d1f | #131f | | | | ; -------------------------------- |
#7d1f | #131f | | | | L7d1f_text_save_load_quit: |
#7d1f | #131f | 21 | | | db 0, "S-SAVE L-LOAD Q-QUIT" |
#7d34 | #1334 | | | | L7d34_text_keys: |
#7d34 | #1334 | 5 | | | db 0, "KEYS" |
#7d39 | #1339 | | | | L7d39_text_spirits: |
#7d39 | #1339 | 8 | | | db 0, "SPIRITS" |
#7d41 | #1341 | | | | L7d41_text_strength: |
#7d41 | #1341 | 9 | | | db 0, "STRENGTH" |
#7d4a | #134a | | | | L7d4a_text_collected: |
#7d4a | #134a | 16 | | | db 0, " XX COLLECTED " |
#7d5a | #135a | | | | L7d5a_text_destroyed: |
#7d5a | #135a | 16 | | | db 0, " XX DESTROYED " |
#7d6a | #136a | | | | L7d6a_text_score: |
#7d6a | #136a | 16 | | | db 1, "SCORE XXXXXXX " |
#7d7a | #137a | | | | L7d7a_text_filename: |
#7d7a | #137a | 14 | | | db 0, "FILENAME : " |
#7d88 | #1388 | | | | |
#7d88 | #1388 | | | | L7d88_action_pointer_viewport_sprite: |
#7d88 | #1388 | 4 | | | db 0, 0, 2, 9 |
#7d8c | #138c | 2 | | | dw L7e3e ; empty buffer |
#7d8e | #138e | 8 | | | dw L7dae, L7dc0, L7dd2, L7de4 ; pointer mask |
#7d96 | #1396 | 8 | | | dw L7df6, L7e08, L7e1a, L7e2c |
#7d9e | #139e | 8 | | | dw L7e50, L7e62, L7e74, L7e86 ; action/throw pointer |
#7da6 | #13a6 | 8 | | | dw L7e98, L7eaa, L7ebc, L7ece |
#7dae | #13ae | | | | L7dae: |
#7dae | #13ae | 6 | | | db #e3, #ff, #e3, #ff, #e3, #ff |
#7db4 | #13b4 | 6 | | | db #1c, #7f, #1c, #7f, #1c, #7f |
#7dba | #13ba | 6 | | | db #e3, #ff, #e3, #ff, #e3, #ff ; |
#7dc0 | #13c0 | | | | L7dc0: |
#7dc0 | #13c0 | 6 | | | db #f1, #ff, #f1, #ff, #f1, #ff |
#7dc6 | #13c6 | 6 | | | db #8e, #3f, #8e, #3f, #8e, #3f |
#7dcc | #13cc | 6 | | | db #f1, #ff, #f1, #ff, #f1, #ff ; |
#7dd2 | #13d2 | | | | L7dd2: |
#7dd2 | #13d2 | 6 | | | db #f8, #ff, #f8, #ff, #f8, #ff |
#7dd8 | #13d8 | 6 | | | db #c7, #1f, #c7, #1f, #c7, #1f |
#7dde | #13de | 6 | | | db #f8, #ff, #f8, #ff, #f8, #ff ; |
#7de4 | #13e4 | | | | L7de4: |
#7de4 | #13e4 | 6 | | | db #fc, #7f, #fc, #7f, #fc, #7f |
#7dea | #13ea | 6 | | | db #e3, #8f, #e3, #8f, #e3, #8f |
#7df0 | #13f0 | 6 | | | db #fc, #7f, #fc, #7f, #fc, #7f ; |
#7df6 | #13f6 | | | | L7df6: |
#7df6 | #13f6 | 6 | | | db #fe, #3f, #fe, #3f, #fe, #3f |
#7dfc | #13fc | 6 | | | db #f1, #c7, #f1, #c7, #f1, #c7 |
#7e02 | #1402 | 6 | | | db #fe, #3f, #fe, #3f, #fe, #3f ; |
#7e08 | #1408 | | | | L7e08: |
#7e08 | #1408 | 6 | | | db #ff, #1f, #ff, #1f, #ff, #1f |
#7e0e | #140e | 6 | | | db #f8, #e3, #f8, #e3, #f8, #e3 |
#7e14 | #1414 | 6 | | | db #ff, #1f, #ff, #1f, #ff, #1f ; |
#7e1a | #141a | | | | L7e1a: |
#7e1a | #141a | 6 | | | db #ff, #8f, #ff, #8f, #ff, #8f |
#7e20 | #1420 | 6 | | | db #fc, #71, #fc, #71, #fc, #71 |
#7e26 | #1426 | 6 | | | db #ff, #8f, #ff, #8f, #ff, #8f ; |
#7e2c | #142c | | | | L7e2c: |
#7e2c | #142c | 6 | | | db #ff, #c7, #ff, #c7, #ff, #c7 |
#7e32 | #1432 | 6 | | | db #fe, #38, #fe, #38, #fe, #38 |
#7e38 | #1438 | 6 | | | db #ff, #c7, #ff, #c7, #ff, #c7 ; |
#7e3e | #143e | | | | L7e3e: |
#7e3e | #143e | 6 | | | db #00, #00, #00, #00, #00, #00 |
#7e44 | #1444 | 6 | | | db #00, #00, #00, #00, #00, #00 |
#7e4a | #144a | 6 | | | db #00, #00, #00, #00, #00, #00 ; |
#7e50 | #1450 | | | | L7e50: |
#7e50 | #1450 | 6 | | | db #14, #00, #14, #00, #14, #00 |
#7e56 | #1456 | 6 | | | db #00, #00, #e3, #80, #00, #00 |
#7e5c | #145c | 6 | | | db #14, #00, #14, #00, #14, #00 ; |
#7e62 | #1462 | | | | L7e62: |
#7e62 | #1462 | 6 | | | db #0a, #00, #0a, #00, #0a, #00 |
#7e68 | #1468 | 6 | | | db #00, #00, #71, #c0, #00, #00 |
#7e6e | #146e | 6 | | | db #0a, #00, #0a, #00, #0a, #00 ; |
#7e74 | #1474 | | | | L7e74: |
#7e74 | #1474 | 6 | | | db #05, #00, #05, #00, #05, #00 |
#7e7a | #147a | 6 | | | db #00, #00, #38, #e0, #00, #00 |
#7e80 | #1480 | 6 | | | db #05, #00, #05, #00, #05, #00 ; |
#7e86 | #1486 | | | | L7e86: |
#7e86 | #1486 | 6 | | | db #02, #80, #02, #80, #02, #80 |
#7e8c | #148c | 6 | | | db #00, #00, #1c, #70, #00, #00 |
#7e92 | #1492 | 6 | | | db #02, #80, #02, #80, #02, #80 ; |
#7e98 | #1498 | | | | L7e98: |
#7e98 | #1498 | 6 | | | db #01, #40, #01, #40, #01, #40 |
#7e9e | #149e | 6 | | | db #00, #00, #0e, #38, #00, #00 |
#7ea4 | #14a4 | 6 | | | db #01, #40, #01, #40, #01, #40 ; |
#7eaa | #14aa | | | | L7eaa: |
#7eaa | #14aa | 6 | | | db #00, #a0, #00, #a0, #00, #a0 |
#7eb0 | #14b0 | 6 | | | db #00, #00, #07, #1c, #00, #00 |
#7eb6 | #14b6 | 6 | | | db #00, #a0, #00, #a0, #00, #a0 ; |
#7ebc | #14bc | | | | L7ebc: |
#7ebc | #14bc | 6 | | | db #00, #50, #00, #50, #00, #50 |
#7ec2 | #14c2 | 6 | | | db #00, #00, #03, #8e, #00, #00 |
#7ec8 | #14c8 | 6 | | | db #00, #50, #00, #50, #00, #50 ; |
#7ece | #14ce | | | | L7ece: |
#7ece | #14ce | 6 | | | db #00, #28, #00, #28, #00, #28 |
#7ed4 | #14d4 | 6 | | | db #00, #00, #01, #c7, #00, #00 |
#7eda | #14da | 6 | | | db #00, #28, #00, #28, #00, #28 ; |
#7ee0 | #14e0 | | | | |
#7ee0 | #14e0 | | | | |
#7ee0 | #14e0 | | | | L7ee0_stone_viewport_sprite_size1: |
#7ee0 | #14e0 | 4 | | | db 0, 0, 2, 4 |
#7ee4 | #14e4 | 2 | | | dw L7f16 ; empty buffer |
#7ee6 | #14e6 | 8 | | | dw L7f06, L7f06, L7f06, L7f06 |
#7eee | #14ee | 8 | | | dw L7f06, L7f06, L7f06, L7f06 |
#7ef6 | #14f6 | 8 | | | dw L7f0e, L7f0e, L7f0e, L7f0e |
#7efe | #14fe | 8 | | | dw L7f0e, L7f0e, L7f0e, L7f0e |
#7f06 | #1506 | | | | L7f06: |
#7f06 | #1506 | 8 | | | db #00, #3f, #00, #3f, #80, #7f, #c0, #ff ; |
#7f0e | #150e | | | | L7f0e: |
#7f0e | #150e | 8 | | | db #ff, #80, #ff, #80, #7f, #00, #3e, #00 ; |
#7f16 | #1516 | | | | L7f16: |
#7f16 | #1516 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 ; |
#7f1e | #151e | | | | |
#7f1e | #151e | | | | |
#7f1e | #151e | | | | L7f1e_stone_viewport_sprite_size2: |
#7f1e | #151e | 4 | | | db 0, 0, 2, 5 |
#7f22 | #1522 | 2 | | | dw L7fe4 ; empty buffer |
#7f24 | #1524 | 8 | | | dw L7f44, L7f4e, L7f58, L7f62 |
#7f2c | #152c | 8 | | | dw L7f6c, L7f76, L7f80, L7f8a |
#7f34 | #1534 | 8 | | | dw L7f94, L7f9e, L7fa8, L7fb2 |
#7f3c | #153c | 8 | | | dw L7fbc, L7fc6, L7fd0, L7fda |
#7f44 | #1544 | | | | L7f44: |
#7f44 | #1544 | 10 | | | db #c1, #ff, #80, #ff, #00, #7f, #80, #ff, #c1, #ff ; |
#7f4e | #154e | | | | L7f4e: |
#7f4e | #154e | 10 | | | db #e0, #ff, #c0, #7f, #80, #3f, #c0, #7f, #e0, #ff ; |
#7f58 | #1558 | | | | L7f58: |
#7f58 | #1558 | 10 | | | db #f0, #7f, #e0, #3f, #c0, #1f, #e0, #3f, #f0, #7f ; |
#7f62 | #1562 | | | | L7f62: |
#7f62 | #1562 | 10 | | | db #f8, #3f, #f0, #1f, #e0, #0f, #f0, #1f, #f8, #3f ; |
#7f6c | #156c | | | | L7f6c: |
#7f6c | #156c | 10 | | | db #fc, #1f, #f8, #0f, #f0, #07, #f8, #0f, #fc, #1f ; |
#7f76 | #1576 | | | | L7f76: |
#7f76 | #1576 | 10 | | | db #fe, #0f, #fc, #07, #f8, #03, #fc, #07, #fe, #0f ; |
#7f80 | #1580 | | | | L7f80: |
#7f80 | #1580 | 10 | | | db #ff, #07, #fe, #03, #fc, #01, #fe, #03, #ff, #07 ; |
#7f8a | #158a | | | | L7f8a: |
#7f8a | #158a | 10 | | | db #ff, #83, #ff, #01, #fe, #00, #ff, #01, #ff, #83 ; |
#7f94 | #1594 | | | | L7f94: |
#7f94 | #1594 | 10 | | | db #3c, #00, #7e, #00, #ff, #00, #7e, #00, #3c, #00 ; |
#7f9e | #159e | | | | L7f9e: |
#7f9e | #159e | 10 | | | db #1e, #00, #3f, #00, #7f, #80, #3f, #00, #1e, #00 ; |
#7fa8 | #15a8 | | | | L7fa8: |
#7fa8 | #15a8 | 10 | | | db #0f, #00, #1f, #80, #3f, #c0, #1f, #80, #0f, #00 ; |
#7fb2 | #15b2 | | | | L7fb2: |
#7fb2 | #15b2 | 10 | | | db #07, #80, #0f, #c0, #1f, #e0, #0f, #c0, #07, #80 ; |
#7fbc | #15bc | | | | L7fbc: |
#7fbc | #15bc | 10 | | | db #03, #c0, #07, #e0, #0f, #f0, #07, #e0, #03, #c0 ; |
#7fc6 | #15c6 | | | | L7fc6: |
#7fc6 | #15c6 | 10 | | | db #01, #e0, #03, #f0, #07, #f8, #03, #f0, #01, #e0 ; |
#7fd0 | #15d0 | | | | L7fd0: |
#7fd0 | #15d0 | 10 | | | db #00, #f0, #01, #f8, #03, #fc, #01, #f8, #00, #f0 ; |
#7fda | #15da | | | | L7fda: |
#7fda | #15da | 10 | | | db #00, #78, #00, #fc, #01, #fe, #00, #fc, #00, #78 ; |
#7fe4 | #15e4 | | | | L7fe4: |
#7fe4 | #15e4 | 10 | | | db #00, #00, #00, #00, #00, #00, #00, #00, #00, #00 ; |
#7fee | #15ee | | | | |
#7fee | #15ee | | | | L7fee_stone_viewport_sprite_size3: |
#7fee | #15ee | 4 | | | db 0, 0, 2, 4 |
#7ff2 | #15f2 | 2 | | | dw L8094 ; empty buffer |
#7ff4 | #15f4 | 8 | | | dw L8014, L801c, L8024, L802c |
#7ffc | #15fc | 8 | | | dw L8034, L803c, L8044, L804c |
#8004 | #1604 | 8 | | | dw L8054, L805c, L8064, L806c |
#800c | #160c | 8 | | | dw L8074, L807c, L8084, L808c |
#8014 | #1614 | | | | L8014: |
#8014 | #1614 | 8 | | | db #87, #ff, #03, #ff, #03, #ff, #87, #ff ; |
#801c | #161c | | | | L801c: |
#801c | #161c | 8 | | | db #c3, #ff, #81, #ff, #81, #ff, #c3, #ff ; |
#8024 | #1624 | | | | L8024: |
#8024 | #1624 | 8 | | | db #e1, #ff, #c0, #ff, #c0, #ff, #e1, #ff ; |
#802c | #162c | | | | L802c: |
#802c | #162c | 8 | | | db #f0, #ff, #e0, #7f, #e0, #7f, #f0, #ff ; |
#8034 | #1634 | | | | L8034: |
#8034 | #1634 | 8 | | | db #f8, #7f, #f0, #3f, #f0, #3f, #f8, #7f ; |
#803c | #163c | | | | L803c: |
#803c | #163c | 8 | | | db #fc, #3f, #f8, #1f, #f8, #1f, #fc, #3f ; |
#8044 | #1644 | | | | L8044: |
#8044 | #1644 | 8 | | | db #fe, #1f, #fc, #0f, #fc, #0f, #fe, #1f ; |
#804c | #164c | | | | L804c: |
#804c | #164c | 8 | | | db #ff, #0f, #fe, #07, #fe, #07, #ff, #0f ; |
#8054 | #1654 | | | | L8054: |
#8054 | #1654 | 8 | | | db #70, #00, #f8, #00, #f8, #00, #70, #00 ; |
#805c | #165c | | | | L805c: |
#805c | #165c | 8 | | | db #38, #00, #7c, #00, #7c, #00, #38, #00 ; |
#8064 | #1664 | | | | L8064: |
#8064 | #1664 | 8 | | | db #1c, #00, #3e, #00, #3e, #00, #1c, #00 ; |
#806c | #166c | | | | L806c: |
#806c | #166c | 8 | | | db #0e, #00, #1f, #00, #1f, #00, #0e, #00 ; |
#8074 | #1674 | | | | L8074: |
#8074 | #1674 | 8 | | | db #07, #00, #0f, #80, #0f, #80, #07, #00 ; |
#807c | #167c | | | | L807c: |
#807c | #167c | 8 | | | db #03, #80, #07, #c0, #07, #c0, #03, #80 ; |
#8084 | #1684 | | | | L8084: |
#8084 | #1684 | 8 | | | db #01, #c0, #03, #e0, #03, #e0, #01, #c0 ; |
#808c | #168c | | | | L808c: |
#808c | #168c | 8 | | | db #00, #e0, #01, #f0, #01, #f0, #00, #e0 ; |
#8094 | #1694 | | | | L8094: |
#8094 | #1694 | 8 | | | db #00, #00, #00, #00, #00, #00, #00, #00 ; |
#809c | #169c | | | | |
#809c | #169c | | | | L909c_stone_viewport_sprite_size4: |
#809c | #169c | 4 | | | db 0, 0, 2, 3 |
#80a0 | #16a0 | 2 | | | dw L8122 ; empty buffer |
#80a2 | #16a2 | 8 | | | dw L80c2, L80c8, L80ce, L80d4 |
#80aa | #16aa | 8 | | | dw L80da, L80e0, L80e6, L80ec |
#80b2 | #16b2 | 8 | | | dw L80f2, L80f8, L80fe, L8104 |
#80ba | #16ba | 8 | | | dw L810a, L8110, L8116, L811c |
#80c2 | #16c2 | | | | L80c2: |
#80c2 | #16c2 | 6 | | | db #8f, #ff, #07, #ff, #8f, #ff ; |
#80c8 | #16c8 | | | | L80c8: |
#80c8 | #16c8 | 6 | | | db #c7, #ff, #83, #ff, #c7, #ff ; |
#80ce | #16ce | | | | L80ce: |
#80ce | #16ce | 6 | | | db #e3, #ff, #c1, #ff, #e3, #ff ; |
#80d4 | #16d4 | | | | L80d4: |
#80d4 | #16d4 | 6 | | | db #f1, #ff, #e0, #ff, #f1, #ff ; |
#80da | #16da | | | | L80da: |
#80da | #16da | 6 | | | db #f8, #ff, #f0, #7f, #f8, #ff ; |
#80e0 | #16e0 | | | | L80e0: |
#80e0 | #16e0 | 6 | | | db #fc, #7f, #f8, #3f, #fc, #7f ; |
#80e6 | #16e6 | | | | L80e6: |
#80e6 | #16e6 | 6 | | | db #fe, #3f, #fc, #1f, #fe, #3f ; |
#80ec | #16ec | | | | L80ec: |
#80ec | #16ec | 6 | | | db #ff, #1f, #fe, #0f, #ff, #1f ; |
#80f2 | #16f2 | | | | L80f2: |
#80f2 | #16f2 | 6 | | | db #60, #00, #f0, #00, #60, #00 ; |
#80f8 | #16f8 | | | | L80f8: |
#80f8 | #16f8 | 6 | | | db #30, #00, #78, #00, #30, #00 ; |
#80fe | #16fe | | | | L80fe: |
#80fe | #16fe | 6 | | | db #18, #00, #3c, #00, #18, #00 ; |
#8104 | #1704 | | | | L8104: |
#8104 | #1704 | 6 | | | db #0c, #00, #1e, #00, #0c, #00 ; |
#810a | #170a | | | | L810a: |
#810a | #170a | 6 | | | db #06, #00, #0f, #00, #06, #00 ; |
#8110 | #1710 | | | | L8110: |
#8110 | #1710 | 6 | | | db #03, #00, #07, #80, #03, #00 ; |
#8116 | #1716 | | | | L8116: |
#8116 | #1716 | 6 | | | db #01, #80, #03, #c0, #01, #80 ; |
#811c | #171c | | | | L811c: |
#811c | #171c | 6 | | | db #00, #c0, #01, #e0, #00, #c0 ; |
#8122 | #1722 | | | | L8122: |
#8122 | #1722 | 6 | | | db #00, #00, #00, #00, #00, #00 ; |
#8128 | #1728 | | | | |
#8128 | #1728 | | | | |
#8128 | #1728 | | | | ; -------------------------------- |
#8128 | #1728 | | | | ; Temporary data for function 'L8132_load_or_save_to_tape' |
#8128 | #1728 | | | | L8128_initial_pressed_key: |
#8128 | #1728 | 1 | | | db #c0 |
#8129 | #1729 | | | | L8129_filename_length: |
#8129 | #1729 | 1 | | | db #01 |
#812a | #172a | | | | L812a_filename_ptr: |
#812a | #172a | 2 | | | dw #0080 |
#812c | #172c | | | | l812c_savegame_data_size: |
#812c | #172c | 2 | | | dw #01c0 |
#812e | #172e | | | | L812e_savegame_data_end_ptr: |
#812e | #172e | 2 | | | dw #00e0 |
#8130 | #1730 | | | | L8130_checksum: |
#8130 | #1730 | 2 | | | dw #00c0 |
#8132 | #1732 | | | | |
#8132 | #1732 | | | | |
#8132 | #1732 | | | | ; -------------------------------- |
#8132 | #1732 | | | | ; Asks the player to type a savegame name, and load/ssaves a game. |
#8132 | #1732 | | | | L8132_load_or_save_to_tape: |
#8132 | #1732 | 3 | 14 | 32 28 81 | ld (L8128_initial_pressed_key), a ; Remember whether we had pressed 'S' or 'L'. |
#8135 | #1735 | 3 | 18 | cd f4 c3 | call Lc3f4_read_filename |
#8138 | #1738 | 3 | 14 | 32 29 81 | ld (L8129_filename_length), a |
#813b | #173b | 3 | 17 | 22 2a 81 | ld (L812a_filename_ptr), hl |
#813e | #173e | 3 | 14 | 3a 28 81 | ld a, (L8128_initial_pressed_key) ; Restore which key was pressed to get to this menu. |
#8141 | #1741 | 2 | 8 | fe 53 | cp "S" ; Check if we wanted to save or load: |
#8143 | #1743 | 3 | 11 | c2 19 82 | jp nz, L8219_load |
#8146 | #1746 | | | | |
#8146 | #1746 | | | | ; Save game: |
#8146 | #1746 | | | | ; Copy the game data to save to the buffer: |
#8146 | #1746 | 3 | 11 | 11 bc 5c | ld de, L5cbc_render_buffer |
#8149 | #1749 | 3 | 11 | 21 ad 6a | ld hl, L6aad_player_current_x |
#814c | #174c | 3 | 11 | 01 77 00 | ld bc, L6b24_savegame_data_end - L6aad_savegame_data_start |
#814f | #174f | 2 | 23/18 | ed b0 | ldir |
#8151 | #1751 | | | | |
#8151 | #1751 | | | | ; Add area object states: |
#8151 | #1751 | 3 | 14 | 3a 82 d0 | ld a, (Ld082_n_areas) |
#8154 | #1754 | 1 | 5 | 4f | ld c, a |
#8155 | #1755 | 4 | 16 | fd 21 d1 d0 | ld iy, Ld0d1_area_offsets |
#8159 | #1759 | 1 | 5 | eb | ex de, hl ; hl = ptr to the next position in the save game data |
#815a | #175a | | | | L815a_save_game_area_loop: |
#815a | #175a | 3 | 21 | fd 5e 00 | ld e, (iy) |
#815d | #175d | 3 | 21 | fd 56 01 | ld d, (iy + 1) ; Get area pointer offset |
#8160 | #1760 | 2 | 12 | fd 23 | inc iy |
#8162 | #1762 | 2 | 12 | fd 23 | inc iy |
#8164 | #1764 | 4 | 16 | dd 21 82 d0 | ld ix, Ld082_area_reference_start |
#8168 | #1768 | 2 | 17 | dd 19 | add ix, de |
#816a | #176a | 3 | 21 | dd 46 01 | ld b, (ix + AREA_N_OBJECTS) |
#816d | #176d | 3 | 11 | 11 08 00 | ld de, 8 |
#8170 | #1770 | 2 | 17 | dd 19 | add ix, de ; skip the header |
#8172 | #1772 | | | | L8172_save_game_next_object_loop: |
#8172 | #1772 | 3 | 21 | dd 7e 00 | ld a, (ix + OBJECT_TYPE_AND_FLAGS) ; save the object state |
#8175 | #1775 | 1 | 8 | 77 | ld (hl), a |
#8176 | #1776 | 1 | 7 | 23 | inc hl |
#8177 | #1777 | 3 | 21 | dd 5e 08 | ld e, (ix + OBJECT_SIZE) |
#817a | #177a | 2 | 17 | dd 19 | add ix, de ; next object |
#817c | #177c | 2 | 14/9 | 10 f4 | djnz L8172_save_game_next_object_loop |
#817e | #177e | 1 | 5 | 0d | dec c |
#817f | #177f | 2 | 13/8 | 20 d9 | jr nz, L815a_save_game_area_loop |
#8181 | #1781 | | | | |
#8181 | #1781 | 3 | 17 | 22 2e 81 | ld (L812e_savegame_data_end_ptr), hl |
#8184 | #1784 | 3 | 11 | 11 bc 5c | ld de, L5cbc_render_buffer |
#8187 | #1787 | 1 | 5 | b7 | or a |
#8188 | #1788 | 2 | 17 | ed 52 | sbc hl, de |
#818a | #178a | 3 | 17 | 22 2c 81 | ld (l812c_savegame_data_size), hl |
#818d | #178d | 3 | 18 | cd 8c 83 | call L838c_checksum |
#8190 | #1790 | 4 | 22 | ed 43 30 81 | ld (L8130_checksum), bc |
#8194 | #1794 | | | | |
#8194 | #1794 | 4 | 22 | ed 5b 2e 81 | ld de, (L812e_savegame_data_end_ptr) |
#8198 | #1798 | | | | |
#8198 | #1798 | | | | ; Generate the savegame header (19 bytes): |
#8198 | #1798 | | | | ; - 1 byte: 30 |
#8198 | #1798 | | | | ; - 12 bytes: filename |
#8198 | #1798 | | | | ; - 2 bytes: savegame size |
#8198 | #1798 | | | | ; - 2 bytes: (Ld083_game_version) |
#8198 | #1798 | | | | ; - 2 bytes: checksum |
#8198 | #1798 | 2 | 8 | 3e 1e | ld a, 30 ; Header start |
#819a | #179a | 1 | 8 | 12 | ld (de), a |
#819b | #179b | 1 | 7 | 13 | inc de |
#819c | #179c | 3 | 17 | 2a 2a 81 | ld hl, (L812a_filename_ptr) |
#819f | #179f | 3 | 11 | 01 0c 00 | ld bc, 12 |
#81a2 | #17a2 | 2 | 23/18 | ed b0 | ldir ; Append the filename to the savegame data. |
#81a4 | #17a4 | | | | |
#81a4 | #17a4 | | | | ; Append the savegame datasize to the savegame header: |
#81a4 | #17a4 | 3 | 17 | 2a 2c 81 | ld hl, (l812c_savegame_data_size) |
#81a7 | #17a7 | 1 | 5 | eb | ex de, hl |
#81a8 | #17a8 | 1 | 8 | 73 | ld (hl), e |
#81a9 | #17a9 | 1 | 7 | 23 | inc hl |
#81aa | #17aa | 1 | 8 | 72 | ld (hl), d |
#81ab | #17ab | 1 | 7 | 23 | inc hl |
#81ac | #17ac | | | | |
#81ac | #17ac | | | | ; Append the 2 bytes at (Ld083_game_version) to the savegame header: |
#81ac | #17ac | 4 | 22 | ed 5b 83 d0 | ld de, (Ld083_game_version) |
#81b0 | #17b0 | 1 | 8 | 73 | ld (hl), e |
#81b1 | #17b1 | 1 | 7 | 23 | inc hl |
#81b2 | #17b2 | 1 | 8 | 72 | ld (hl), d |
#81b3 | #17b3 | 1 | 7 | 23 | inc hl |
#81b4 | #17b4 | | | | |
#81b4 | #17b4 | | | | ; Append the checksum to the header: |
#81b4 | #17b4 | 4 | 22 | ed 5b 30 81 | ld de, (L8130_checksum) |
#81b8 | #17b8 | 1 | 8 | 73 | ld (hl), e |
#81b9 | #17b9 | 1 | 7 | 23 | inc hl |
#81ba | #17ba | 1 | 8 | 72 | ld (hl), d |
#81bb | #17bb | | | | |
#81bb | #17bb | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#81bf | #17bf | 3 | 11 | 21 47 75 | ld hl, L7547_text_play_record |
#81c2 | #17c2 | 3 | 11 | 11 27 0d | ld de, #0d27 |
#81c5 | #17c5 | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#81c8 | #17c8 | 4 | 16 | dd 21 fa 72 | ld ix, L725c_videomem_row_pointers + 79 * 2 |
#81cc | #17cc | 3 | 11 | 21 83 75 | ld hl, L7583_text_then_any_key |
#81cf | #17cf | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#81d2 | #17d2 | | | | |
#81d2 | #17d2 | | | | ; Wait until a key is pressed & released: |
#81d2 | #17d2 | | | | L81d2_key_press_wait_loop: |
#81d2 | #17d2 | 3 | 18 | cd d4 bf | call Lbfd4_read_keyboard_and_joystick_input |
#81d5 | #17d5 | 2 | 13/8 | 38 fb | jr c, L81d2_key_press_wait_loop |
#81d7 | #17d7 | | | | L81d7_key_release_wait_loop: |
#81d7 | #17d7 | 3 | 18 | cd d4 bf | call Lbfd4_read_keyboard_and_joystick_input |
#81da | #17da | 2 | 13/8 | 30 fb | jr nc, L81d7_key_release_wait_loop |
#81dc | #17dc | | | | |
#81dc | #17dc | 3 | 11 | 21 38 75 | ld hl, L7538_text_spaces |
#81df | #17df | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#81e2 | #17e2 | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#81e6 | #17e6 | 3 | 11 | 21 92 75 | ld hl, L7592_text_saving_file |
#81e9 | #17e9 | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#81ec | #17ec | 4 | 22 | fd 2a 7d 74 | ld iy, (L747d) |
#81f0 | #17f0 | 4 | 22 | dd 2a 2e 81 | ld ix, (L812e_savegame_data_end_ptr) ; address to save |
#81f4 | #17f4 | 3 | 11 | 11 13 00 | ld de, 19 ; Size of the header |
#81f7 | #17f7 | 1 | 5 | af | xor a |
#81f8 | #17f8 | | | | ; Save the header: |
#81f8 | #17f8 | 3 | 18 | cd c6 04 | call L04c6_BIOS_CASSETTE_SAVE_NO_BREAK_TEST |
#81fb | #17fb | 3 | 11 | d2 62 83 | jp nc, L8362_done_loading_saving_with_pause |
#81fe | #17fe | 1 | 5 | fb | ei |
#81ff | #17ff | | | | ; Wait 50 interrupts: |
#81ff | #17ff | 2 | 8 | 3e 32 | ld a, 50 |
#8201 | #1801 | 3 | 14 | 32 a5 74 | ld (L74a5_interrupt_timer), a |
#8204 | #1804 | | | | L8204_pause_loop: |
#8204 | #1804 | 3 | 14 | 3a a5 74 | ld a, (L74a5_interrupt_timer) |
#8207 | #1807 | 1 | 5 | b7 | or a |
#8208 | #1808 | 2 | 13/8 | 20 fa | jr nz, L8204_pause_loop |
#820a | #180a | 4 | 16 | dd 21 bc 5c | ld ix, L5cbc_render_buffer ; address to save |
#820e | #180e | 4 | 22 | ed 5b 2c 81 | ld de, (l812c_savegame_data_size) ; amount of bytes to save |
#8212 | #1812 | 1 | 5 | 3d | dec a |
#8213 | #1813 | | | | ; Save the savegame: |
#8213 | #1813 | 3 | 18 | cd c6 04 | call L04c6_BIOS_CASSETTE_SAVE_NO_BREAK_TEST |
#8216 | #1816 | 3 | 11 | c3 62 83 | jp L8362_done_loading_saving_with_pause |
#8219 | #1819 | | | | |
#8219 | #1819 | | | | L8219_load: |
#8219 | #1819 | | | | ; Load game: |
#8219 | #1819 | 4 | 22 | fd 2a 7d 74 | ld iy, (L747d) |
#821d | #181d | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#8221 | #1821 | 3 | 11 | 21 b0 75 | ld hl, L75b0_text_searching |
#8224 | #1824 | 3 | 11 | 11 27 0e | ld de, #0e27 |
#8227 | #1827 | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#822a | #182a | | | | L822a: |
#822a | #182a | 4 | 16 | dd 21 bc 5c | ld ix, L5cbc_render_buffer ; address to load to |
#822e | #182e | 3 | 11 | 11 12 00 | ld de, 19 - 1 ; Amount of bytes to load (19) |
#8231 | #1831 | | | | ; Set the flags/values the BIOS routine expects to load: |
#8231 | #1831 | 1 | 5 | af | xor a |
#8232 | #1832 | 1 | 5 | 37 | scf |
#8233 | #1833 | 1 | 5 | 1c | inc e |
#8234 | #1834 | 1 | 5 | 08 | ex af, af' ; since we are skipping tests, we need to pre "ex" af, since the function would do this during the tests. |
#8235 | #1835 | 1 | 5 | f3 | di |
#8236 | #1836 | 3 | 18 | cd 62 05 | call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS |
#8239 | #1839 | 1 | 12 | f5 | push af |
#823a | #183a | 2 | 8 | 3e 7f | ld a, #7f |
#823c | #183c | 2 | 12 | db fe | in a, (ULA_PORT) |
#823e | #183e | 1 | 5 | 1f | rra |
#823f | #183f | 3 | 11 | d2 1d 83 | jp nc, L831d_done_loading_saving_pop ; If space (break?) was pressed, cancel. |
#8242 | #1842 | 1 | 11 | f1 | pop af |
#8243 | #1843 | 2 | 13/8 | 30 e5 | jr nc, L822a ; If load failed, retry. |
#8245 | #1845 | 4 | 16 | dd 21 bc 5c | ld ix, L5cbc_render_buffer |
#8249 | #1849 | | | | |
#8249 | #1849 | | | | ; Check header is correct: |
#8249 | #1849 | | | | ; - 1 byte: 30 |
#8249 | #1849 | | | | ; - 12 bytes: filename |
#8249 | #1849 | | | | ; - 2 bytes: savegame size |
#8249 | #1849 | | | | ; - 2 bytes: (Ld083_game_version) |
#8249 | #1849 | | | | ; - 2 bytes: checksum |
#8249 | #1849 | 2 | 8 | 3e 1e | ld a, 30 |
#824b | #184b | 3 | 21 | dd be 00 | cp (ix) |
#824e | #184e | 2 | 13/8 | 20 da | jr nz, L822a ; If the first byte is not the header start byte, retry. |
#8250 | #1850 | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#8254 | #1854 | 3 | 11 | 21 a1 75 | ld hl, L75a1_text_found |
#8257 | #1857 | 3 | 11 | 11 27 0e | ld de, #0e27 |
#825a | #185a | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#825d | #185d | | | | |
#825d | #185d | 4 | 16 | dd 21 bd 5c | ld ix, L5cbc_render_buffer + 1 |
#8261 | #1861 | 3 | 21 | dd 5e 0c | ld e, (ix + 12) |
#8264 | #1864 | 3 | 21 | dd 56 0d | ld d, (ix + 13) ; de = savegame size |
#8267 | #1867 | 4 | 21 | dd 36 0c 20 | ld (ix + 12), " " ; replace savegame size by spaces, to print to screen. |
#826b | #186b | 4 | 21 | dd 36 0d 20 | ld (ix + 13), " " |
#826f | #186f | 2 | 17 | dd e5 | push ix |
#8271 | #1871 | 1 | 12 | d5 | push de |
#8272 | #1872 | 3 | 11 | 21 bc 5c | ld hl, L5cbc_render_buffer |
#8275 | #1875 | 2 | 11 | 36 00 | ld (hl), 0 ; Replace "30" by a 0, so we can draw the string. |
#8277 | #1877 | 4 | 16 | dd 21 fa 72 | ld ix, L725c_videomem_row_pointers + 79 * 2 |
#827b | #187b | 3 | 11 | 11 27 0e | ld de, #0e27 |
#827e | #187e | 3 | 18 | cd 1c d0 | call Ld01c_draw_string ; Draw savegame name |
#8281 | #1881 | 1 | 11 | d1 | pop de |
#8282 | #1882 | 2 | 16 | dd e1 | pop ix |
#8284 | #1884 | | | | |
#8284 | #1884 | | | | ; Check if the savegame name matches what the player entered: |
#8284 | #1884 | 3 | 14 | 3a 29 81 | ld a, (L8129_filename_length) |
#8287 | #1887 | 1 | 5 | b7 | or a |
#8288 | #1888 | 2 | 13/8 | 20 07 | jr nz, L8291 |
#828a | #188a | | | | ; If player did not enter any name, accept any savegame: |
#828a | #188a | 3 | 11 | 01 0c 00 | ld bc, 12 |
#828d | #188d | 2 | 17 | dd 09 | add ix, bc |
#828f | #188f | 2 | 13 | 18 10 | jr L82a1_savegame_name_matches |
#8291 | #1891 | | | | L8291: |
#8291 | #1891 | | | | ; Check if names match: |
#8291 | #1891 | 2 | 8 | 06 0c | ld b, 12 |
#8293 | #1893 | 3 | 17 | 2a 2a 81 | ld hl, (L812a_filename_ptr) |
#8296 | #1896 | | | | L8296_savegame_name_check_loop: |
#8296 | #1896 | 3 | 21 | dd 7e 00 | ld a, (ix) |
#8299 | #1899 | 1 | 8 | be | cp (hl) |
#829a | #189a | 2 | 13/8 | 20 8e | jr nz, L822a ; If name does not match, retry |
#829c | #189c | 2 | 12 | dd 23 | inc ix |
#829e | #189e | 1 | 7 | 23 | inc hl |
#829f | #189f | 2 | 14/9 | 10 f5 | djnz L8296_savegame_name_check_loop |
#82a1 | #18a1 | | | | |
#82a1 | #18a1 | | | | L82a1_savegame_name_matches: |
#82a1 | #18a1 | 4 | 22 | ed 53 2c 81 | ld (l812c_savegame_data_size), de |
#82a5 | #18a5 | 1 | 5 | 7a | ld a, d |
#82a6 | #18a6 | 2 | 8 | e6 f0 | and 240 |
#82a8 | #18a8 | 2 | 13/8 | 20 56 | jr nz, L8300 |
#82aa | #18aa | | | | ; Check that the version matches this game: |
#82aa | #18aa | 3 | 21 | dd 5e 02 | ld e, (ix + 2) |
#82ad | #18ad | 3 | 21 | dd 56 03 | ld d, (ix + 3) |
#82b0 | #18b0 | 3 | 17 | 2a 83 d0 | ld hl, (Ld083_game_version) |
#82b3 | #18b3 | 1 | 5 | b7 | or a |
#82b4 | #18b4 | 2 | 17 | ed 52 | sbc hl, de |
#82b6 | #18b6 | 2 | 13/8 | 20 48 | jr nz, L8300 |
#82b8 | #18b8 | 3 | 21 | dd 6e 04 | ld l, (ix + 4) |
#82bb | #18bb | 3 | 21 | dd 66 05 | ld h, (ix + 5) |
#82be | #18be | 3 | 17 | 22 30 81 | ld (L8130_checksum), hl |
#82c1 | #18c1 | | | | |
#82c1 | #18c1 | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#82c5 | #18c5 | 3 | 11 | 21 74 75 | ld hl, L7574_text_loading |
#82c8 | #18c8 | 3 | 11 | 11 27 0e | ld de, #0e27 |
#82cb | #18cb | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#82ce | #18ce | | | | |
#82ce | #18ce | | | | ; Load savegame data: |
#82ce | #18ce | 4 | 16 | dd 21 bc 5c | ld ix, L5cbc_render_buffer |
#82d2 | #18d2 | 4 | 22 | ed 5b 2c 81 | ld de, (l812c_savegame_data_size) |
#82d6 | #18d6 | | | | |
#82d6 | #18d6 | | | | ; Set the flags/values the BIOS routine expects to load: |
#82d6 | #18d6 | 1 | 5 | 37 | scf |
#82d7 | #18d7 | 2 | 8 | 3e ff | ld a, 255 |
#82d9 | #18d9 | 1 | 5 | 14 | inc d |
#82da | #18da | 1 | 5 | 08 | ex af, af' |
#82db | #18db | 1 | 5 | 15 | dec d |
#82dc | #18dc | 1 | 5 | f3 | di |
#82dd | #18dd | 3 | 18 | cd 62 05 | call L0562_BIOS_READ_FROM_TAPE_SKIP_TESTS |
#82e0 | #18e0 | 1 | 12 | f5 | push af |
#82e1 | #18e1 | 2 | 8 | 3e 7f | ld a, 127 |
#82e3 | #18e3 | 2 | 12 | db fe | in a, (ULA_PORT) |
#82e5 | #18e5 | 1 | 5 | 1f | rra |
#82e6 | #18e6 | 2 | 13/8 | 30 35 | jr nc, L831d_done_loading_saving_pop ; If space (break?) was pressed, cancel. |
#82e8 | #18e8 | 1 | 11 | f1 | pop af |
#82e9 | #18e9 | 4 | 16 | dd 21 65 75 | ld ix, L7565_text_loading_error |
#82ed | #18ed | 2 | 13/8 | 30 15 | jr nc, L8304 |
#82ef | #18ef | | | | |
#82ef | #18ef | 3 | 11 | 11 bc 5c | ld de, L5cbc_render_buffer |
#82f2 | #18f2 | 3 | 17 | 2a 2c 81 | ld hl, (l812c_savegame_data_size) |
#82f5 | #18f5 | 3 | 18 | cd 8c 83 | call L838c_checksum |
#82f8 | #18f8 | 3 | 17 | 2a 30 81 | ld hl, (L8130_checksum) |
#82fb | #18fb | 1 | 5 | b7 | or a |
#82fc | #18fc | 2 | 17 | ed 42 | sbc hl, bc |
#82fe | #18fe | 2 | 13/8 | 28 20 | jr z, L8320_found_valid_savegame |
#8300 | #1900 | | | | |
#8300 | #1900 | | | | L8300: |
#8300 | #1900 | | | | ; Load error: version mismatch |
#8300 | #1900 | 4 | 16 | dd 21 56 75 | ld ix, L7556_text_invalid_file |
#8304 | #1904 | | | | L8304: |
#8304 | #1904 | | | | ; Load error |
#8304 | #1904 | 2 | 17 | dd e5 | push ix |
#8306 | #1906 | 1 | 11 | e1 | pop hl |
#8307 | #1907 | 4 | 16 | dd 21 e4 72 | ld ix, L725c_videomem_row_pointers + 68 * 2 |
#830b | #190b | 3 | 11 | 11 27 0e | ld de, #0e27 |
#830e | #190e | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#8311 | #1911 | 3 | 11 | 21 38 75 | ld hl, L7538_text_spaces |
#8314 | #1914 | 4 | 16 | dd 21 fa 72 | ld ix, L725c_videomem_row_pointers + 79 * 2 |
#8318 | #1918 | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#831b | #191b | 2 | 13 | 18 45 | jr L8362_done_loading_saving_with_pause |
#831d | #191d | | | | |
#831d | #191d | | | | L831d_done_loading_saving_pop: |
#831d | #191d | 1 | 11 | f1 | pop af |
#831e | #191e | 2 | 13 | 18 42 | jr L8362_done_loading_saving_with_pause |
#8320 | #1920 | | | | |
#8320 | #1920 | | | | L8320_found_valid_savegame: |
#8320 | #1920 | | | | ; Found a valid savegame, restore state: |
#8320 | #1920 | 3 | 11 | 21 bc 5c | ld hl, L5cbc_render_buffer |
#8323 | #1923 | 3 | 11 | 11 ad 6a | ld de, L6aad_savegame_data_start |
#8326 | #1926 | 3 | 11 | 01 77 00 | ld bc, 119 |
#8329 | #1929 | 2 | 23/18 | ed b0 | ldir |
#832b | #192b | | | | |
#832b | #192b | | | | ; Restore the additional area state information: |
#832b | #192b | 3 | 14 | 3a 82 d0 | ld a, (Ld082_n_areas) |
#832e | #192e | 1 | 5 | 4f | ld c, a |
#832f | #192f | 4 | 16 | fd 21 d1 d0 | ld iy, Ld0d1_area_offsets |
#8333 | #1933 | | | | L8333_area_loop: |
#8333 | #1933 | 3 | 21 | fd 5e 00 | ld e, (iy) |
#8336 | #1936 | 3 | 21 | fd 56 01 | ld d, (iy + 1) |
#8339 | #1939 | 2 | 12 | fd 23 | inc iy |
#833b | #193b | 2 | 12 | fd 23 | inc iy |
#833d | #193d | 4 | 16 | dd 21 82 d0 | ld ix, Ld082_area_reference_start |
#8341 | #1941 | 2 | 17 | dd 19 | add ix, de |
#8343 | #1943 | 3 | 21 | dd 46 01 | ld b, (ix + AREA_N_OBJECTS) |
#8346 | #1946 | 3 | 11 | 11 08 00 | ld de, 8 |
#8349 | #1949 | 2 | 17 | dd 19 | add ix, de |
#834b | #194b | | | | L834b: |
#834b | #194b | 1 | 8 | 7e | ld a, (hl) |
#834c | #194c | 3 | 21 | dd 77 00 | ld (ix + OBJECT_TYPE_AND_FLAGS), a |
#834f | #194f | 1 | 7 | 23 | inc hl |
#8350 | #1950 | 3 | 21 | dd 5e 08 | ld e, (ix + OBJECT_SIZE) |
#8353 | #1953 | 2 | 17 | dd 19 | add ix, de |
#8355 | #1955 | 2 | 14/9 | 10 f4 | djnz L834b |
#8357 | #1957 | 1 | 5 | 0d | dec c |
#8358 | #1958 | 2 | 13/8 | 20 d9 | jr nz, L8333_area_loop |
#835a | #195a | 1 | 5 | fb | ei |
#835b | #195b | 3 | 14 | 3a d7 6a | ld a, (L6ad7_current_border_color) |
#835e | #195e | 2 | 12 | d3 fe | out (ULA_PORT), a |
#8360 | #1960 | 2 | 13 | 18 11 | jr L8373_done_loading_saving |
#8362 | #1962 | | | | |
#8362 | #1962 | | | | L8362_done_loading_saving_with_pause: |
#8362 | #1962 | 1 | 5 | fb | ei |
#8363 | #1963 | 3 | 14 | 3a d7 6a | ld a, (L6ad7_current_border_color) |
#8366 | #1966 | 2 | 12 | d3 fe | out (ULA_PORT), a ; Set the border color. |
#8368 | #1968 | | | | ; Wait 50 interrupts: |
#8368 | #1968 | 2 | 8 | 3e 32 | ld a, 50 |
#836a | #196a | 3 | 14 | 32 a5 74 | ld (L74a5_interrupt_timer), a |
#836d | #196d | | | | L836d_pause_loop: |
#836d | #196d | 3 | 14 | 3a a5 74 | ld a, (L74a5_interrupt_timer) |
#8370 | #1970 | 1 | 5 | b7 | or a |
#8371 | #1971 | 2 | 13/8 | 20 fa | jr nz, L836d_pause_loop |
#8373 | #1973 | | | | |
#8373 | #1973 | | | | L8373_done_loading_saving: |
#8373 | #1973 | 3 | 11 | 21 fd ff | ld hl, #fffd |
#8376 | #1976 | 3 | 17 | 22 6c 74 | ld (L746c_game_flags), hl |
#8379 | #1979 | 2 | 8 | 3e 01 | ld a, 1 |
#837b | #197b | 3 | 14 | 32 66 74 | ld (L7466_need_attribute_refresh_flag), a |
#837e | #197e | 3 | 14 | 32 77 74 | ld (L7477_render_buffer_effect), a ; fade in effect when rendering |
#8381 | #1981 | 3 | 18 | cd aa 83 | call L83aa_redraw_whole_screen |
#8384 | #1984 | 1 | 5 | af | xor a |
#8385 | #1985 | 3 | 14 | 32 6c 74 | ld (L746c_game_flags), a |
#8388 | #1988 | 3 | 14 | 32 6d 74 | ld (L746c_game_flags + 1), a |
#838b | #198b | 1 | 11 | c9 | ret |
#838c | #198c | | | | |
#838c | #198c | | | | |
#838c | #198c | | | | ; -------------------------------- |
#838c | #198c | | | | ; Calculates the check sum of a block of data. |
#838c | #198c | | | | ; Input: |
#838c | #198c | | | | ; - de: ptr to the data to calculate the checksum for |
#838c | #198c | | | | ; - hl: length of the data |
#838c | #198c | | | | ; Output: |
#838c | #198c | | | | ; - bc: 16bit checksum |
#838c | #198c | | | | L838c_checksum: |
#838c | #198c | | | | ; Initialize checksum to 0: |
#838c | #198c | 1 | 5 | af | xor a |
#838d | #198d | 1 | 5 | 47 | ld b, a |
#838e | #198e | 1 | 5 | 4f | ld c, a |
#838f | #198f | | | | L838f_checksum_loop: |
#838f | #198f | | | | ; xor each pair of bytes in the data with "bc": |
#838f | #198f | 1 | 8 | 1a | ld a, (de) |
#8390 | #1990 | 1 | 5 | a8 | xor b |
#8391 | #1991 | 1 | 5 | 47 | ld b, a |
#8392 | #1992 | 1 | 7 | 13 | inc de |
#8393 | #1993 | 1 | 7 | 2b | dec hl |
#8394 | #1994 | 1 | 5 | 7d | ld a, l |
#8395 | #1995 | 1 | 5 | b4 | or h |
#8396 | #1996 | 2 | 13/8 | 28 09 | jr z, L83a1_checksum_done |
#8398 | #1998 | 1 | 8 | 1a | ld a, (de) |
#8399 | #1999 | 1 | 5 | a9 | xor c |
#839a | #199a | 1 | 5 | 4f | ld c, a |
#839b | #199b | 1 | 7 | 13 | inc de |
#839c | #199c | 1 | 7 | 2b | dec hl |
#839d | #199d | 1 | 5 | 7d | ld a, l |
#839e | #199e | 1 | 5 | b4 | or h |
#839f | #199f | 2 | 13/8 | 20 ee | jr nz, L838f_checksum_loop |
#83a1 | #19a1 | | | | L83a1_checksum_done: |
#83a1 | #19a1 | 2 | 10 | cb 20 | sla b |
#83a3 | #19a3 | 2 | 10 | cb 11 | rl c |
#83a5 | #19a5 | 2 | 10 | cb 10 | rl b |
#83a7 | #19a7 | 2 | 10 | cb 11 | rl c |
#83a9 | #19a9 | 1 | 11 | c9 | ret |
#83aa | #19aa | | | | |
#83aa | #19aa | | | | |
#83aa | #19aa | | | | ; -------------------------------- |
#83aa | #19aa | | | | ; Redraws the whole screen, including: |
#83aa | #19aa | | | | ; - UI elements |
#83aa | #19aa | | | | ; - 3d view |
#83aa | #19aa | | | | L83aa_redraw_whole_screen: |
#83aa | #19aa | 2 | 17 | dd e5 | push ix |
#83ac | #19ac | 2 | 17 | fd e5 | push iy |
#83ae | #19ae | 1 | 12 | e5 | push hl |
#83af | #19af | 1 | 12 | d5 | push de |
#83b0 | #19b0 | 1 | 12 | c5 | push bc |
#83b1 | #19b1 | 1 | 12 | f5 | push af |
#83b2 | #19b2 | 3 | 14 | 3a 74 74 | ld a, (L7474_check_if_object_crushed_player_flag) |
#83b5 | #19b5 | 1 | 5 | b7 | or a |
#83b6 | #19b6 | 2 | 13/8 | 28 07 | jr z, L83bf_no_need_to_check_crush |
#83b8 | #19b8 | 3 | 18 | cd aa ca | call Lcaaa_check_if_object_crushed_player |
#83bb | #19bb | 1 | 5 | b7 | or a |
#83bc | #19bc | 3 | 11 | c2 0b 84 | jp nz, L840b_update_ui_and_done |
#83bf | #19bf | | | | L83bf_no_need_to_check_crush: |
#83bf | #19bf | 3 | 14 | 3a 6c 74 | ld a, (L746c_game_flags) |
#83c2 | #19c2 | 2 | 10 | cb 57 | bit 2, a |
#83c4 | #19c4 | 2 | 13/8 | 28 25 | jr z, L83eb_no_need_to_reproject_objects |
#83c6 | #19c6 | 3 | 18 | cd b7 8b | call L8bb7_determine_rendering_volume |
#83c9 | #19c9 | 3 | 18 | cd de 95 | call L95de_init_rotation_matrix |
#83cc | #19cc | 1 | 5 | af | xor a |
#83cd | #19cd | 3 | 14 | 32 69 74 | ld (L7469_n_spirits_found_in_current_area), a |
#83d0 | #19d0 | 4 | 22 | dd 2a 63 74 | ld ix, (L7463_global_area_objects) |
#83d4 | #19d4 | 3 | 14 | 3a 65 74 | ld a, (L7465_global_area_n_objects) |
#83d7 | #19d7 | 1 | 5 | b7 | or a |
#83d8 | #19d8 | 3 | 18/11 | c4 31 84 | call nz, L8431_project_objects |
#83db | #19db | 4 | 22 | dd 2a d1 6a | ld ix, (L6ad1_current_area_objects) |
#83df | #19df | 3 | 14 | 3a d0 6a | ld a, (L6ad0_current_area_n_objects) |
#83e2 | #19e2 | 1 | 5 | b7 | or a |
#83e3 | #19e3 | 3 | 18/11 | c4 31 84 | call nz, L8431_project_objects |
#83e6 | #19e6 | 3 | 18 | cd 2d 9c | call L9c2d_sort_objects_for_rendering |
#83e9 | #19e9 | 2 | 13 | 18 13 | jr L83fe_rerender |
#83eb | #19eb | | | | L83eb_no_need_to_reproject_objects: |
#83eb | #19eb | | | | ; If there is a lightning, re-render for sure: |
#83eb | #19eb | 3 | 14 | 3a 0e 6b | ld a, (L6b0e_lightning_time_seconds_countdown) |
#83ee | #19ee | 1 | 5 | b7 | or a |
#83ef | #19ef | 2 | 13/8 | 20 06 | jr nz, L83f7 ; if there is no lightning, rerender only if the re-render flag is set. |
#83f1 | #19f1 | 3 | 14 | 3a 19 6b | ld a, (L6b19_current_area_flags) |
#83f4 | #19f4 | 1 | 5 | b7 | or a |
#83f5 | #19f5 | 2 | 13/8 | 20 07 | jr nz, L83fe_rerender |
#83f7 | #19f7 | | | | L83f7: |
#83f7 | #19f7 | 3 | 14 | 3a 6d 74 | ld a, (L746c_game_flags + 1) |
#83fa | #19fa | 2 | 10 | cb 5f | bit 3, a ; check if we need to re-render. |
#83fc | #19fc | 2 | 13/8 | 28 0d | jr z, L840b_update_ui_and_done ; skip re-render |
#83fe | #19fe | | | | L83fe_rerender: |
#83fe | #19fe | 3 | 18 | cd 52 bc | call Lbc52_update_UI |
#8401 | #1a01 | 3 | 18 | cd 46 9d | call L9d46_render_3d_view |
#8404 | #1a04 | 3 | 18 | cd bc 9d | call L9dbc_render_buffer_with_effects |
#8407 | #1a07 | 2 | 13 | 18 05 | jr L840e_continue |
#8409 | #1a09 | 2 | 13 | 18 03 | jr L840e_continue ; Note: unreachable? |
#840b | #1a0b | | | | L840b_update_ui_and_done: |
#840b | #1a0b | 3 | 18 | cd 52 bc | call Lbc52_update_UI |
#840e | #1a0e | | | | L840e_continue: |
#840e | #1a0e | | | | ; Check if we need to reprint the current room name: |
#840e | #1a0e | 3 | 14 | 3a 6d 74 | ld a, (L746c_game_flags + 1) |
#8411 | #1a11 | 2 | 10 | cb 6f | bit 5, a |
#8413 | #1a13 | 2 | 13/8 | 28 13 | jr z, L8428_done |
#8415 | #1a15 | | | | |
#8415 | #1a15 | | | | L8415_pause_loop: |
#8415 | #1a15 | 3 | 14 | 3a a5 74 | ld a, (L74a5_interrupt_timer) |
#8418 | #1a18 | 1 | 5 | b7 | or a |
#8419 | #1a19 | 2 | 13/8 | 20 fa | jr nz, L8415_pause_loop |
#841b | #1a1b | | | | ; Print the current room name: |
#841b | #1a1b | 3 | 11 | 21 bf 6a | ld hl, L6abf_current_area_name_string |
#841e | #1a1e | 4 | 16 | dd 21 5a 73 | ld ix, L735a_ui_message_row_pointers |
#8422 | #1a22 | 3 | 11 | 11 00 0f | ld de, #0f00 ; string length = 15, no x offset |
#8425 | #1a25 | 3 | 18 | cd 1c d0 | call Ld01c_draw_string |
#8428 | #1a28 | | | | L8428_done: |
#8428 | #1a28 | 1 | 11 | f1 | pop af |
#8429 | #1a29 | 1 | 11 | c1 | pop bc |
#842a | #1a2a | 1 | 11 | d1 | pop de |
#842b | #1a2b | 1 | 11 | e1 | pop hl |
#842c | #1a2c | 2 | 16 | fd e1 | pop iy |
#842e | #1a2e | 2 | 16 | dd e1 | pop ix |
#8430 | #1a30 | 1 | 11 | c9 | ret |
#8431 | #1a31 | | | | |
#8431 | #1a31 | | | | |
#8431 | #1a31 | | | | ; -------------------------------- |
#8431 | #1a31 | | | | ; Projects all objects from 3d coordinates to 2d coordinates, determining which ones have to be drawn. |
#8431 | #1a31 | | | | ; - When this function is called this has already happened: |
#8431 | #1a31 | | | | ; - rendering cube volume has been calculated |
#8431 | #1a31 | | | | ; - rotation matrix has already been set |
#8431 | #1a31 | | | | ; Input: |
#8431 | #1a31 | | | | ; - a: number of objects |
#8431 | #1a31 | | | | ; - ix: pointer to objects |
#8431 | #1a31 | | | | L8431_project_objects: |
#8431 | #1a31 | | | | L8431_object_loop: |
#8431 | #1a31 | 1 | 12 | f5 | push af |
#8432 | #1a32 | 4 | 22 | dd 22 9d 74 | ld (L749d_object_currently_being_processed_ptr), ix |
#8436 | #1a36 | 3 | 21 | dd 7e 00 | ld a, (ix + OBJECT_TYPE_AND_FLAGS) |
#8439 | #1a39 | 2 | 8 | e6 0f | and #0f |
#843b | #1a3b | 3 | 11 | ca fb 84 | jp z, L84fb_next_object |
#843e | #1a3e | 4 | 22 | dd cb 00 76 | bit 6, (ix + OBJECT_TYPE_AND_FLAGS) |
#8442 | #1a42 | 3 | 11 | c2 fb 84 | jp nz, L84fb_next_object |
#8445 | #1a45 | 2 | 8 | fe 02 | cp 2 ; Check if it's a spirit |
#8447 | #1a47 | 2 | 13/8 | 20 07 | jr nz, L8450_not_a_spirit |
#8449 | #1a49 | | | | ; It is a spirit, increment the counter of spirits found: |
#8449 | #1a49 | 3 | 11 | 21 69 74 | ld hl, L7469_n_spirits_found_in_current_area |
#844c | #1a4c | 1 | 12 | 34 | inc (hl) |
#844d | #1a4d | 3 | 11 | c3 fb 84 | jp L84fb_next_object |
#8450 | #1a50 | | | | L8450_not_a_spirit: |
#8450 | #1a50 | 3 | 14 | 3a bd 6a | ld a, (L6abd_cull_by_rendering_volume_flag) |
#8453 | #1a53 | 1 | 5 | b7 | or a |
#8454 | #1a54 | 2 | 13/8 | 20 1b | jr nz, L8471_skip_rendering_volume_cull_check |
#8456 | #1a56 | | | | |
#8456 | #1a56 | | | | ; Rendering cube cull check: |
#8456 | #1a56 | | | | ; Check if the object intersects with the rendering volume: |
#8456 | #1a56 | 3 | 11 | 21 5d 74 | ld hl, L745d_rendering_cube_volume |
#8459 | #1a59 | 2 | 8 | 06 03 | ld b, 3 ; 3 iterations, one for X, one for Y, one for Z |
#845b | #1a5b | | | | L845b_rendering_volume_cull_check_loop: |
#845b | #1a5b | 3 | 21 | dd 7e 01 | ld a, (ix + OBJECT_X) |
#845e | #1a5e | 1 | 8 | be | cp (hl) |
#845f | #1a5f | 2 | 13/8 | 28 03 | jr z, L8464 |
#8461 | #1a61 | 3 | 11 | f2 fb 84 | jp p, L84fb_next_object ; Outside of rendering volume |
#8464 | #1a64 | | | | L8464: |
#8464 | #1a64 | 3 | 21 | dd 86 04 | add a, (ix + OBJECT_SIZE_X) |
#8467 | #1a67 | 1 | 7 | 23 | inc hl |
#8468 | #1a68 | 1 | 8 | be | cp (hl) |
#8469 | #1a69 | 3 | 11 | fa fb 84 | jp m, L84fb_next_object ; Outside of rendering volume |
#846c | #1a6c | 2 | 12 | dd 23 | inc ix |
#846e | #1a6e | 1 | 7 | 23 | inc hl |
#846f | #1a6f | 2 | 14/9 | 10 ea | djnz L845b_rendering_volume_cull_check_loop |
#8471 | #1a71 | | | | |
#8471 | #1a71 | | | | ; Passed the cull check, object intersects with the rendering volume! |
#8471 | #1a71 | | | | L8471_skip_rendering_volume_cull_check: |
#8471 | #1a71 | 4 | 22 | ed 5b 99 74 | ld de, (L7499_3d_object_bounding_box_relative_to_player_ptr) |
#8475 | #1a75 | 1 | 5 | af | xor a |
#8476 | #1a76 | 4 | 22 | dd 2a 9d 74 | ld ix, (L749d_object_currently_being_processed_ptr) |
#847a | #1a7a | 3 | 11 | 21 ad 6a | ld hl, L6aad_player_current_x |
#847d | #1a7d | 2 | 8 | 06 03 | ld b, 3 |
#847f | #1a7f | | | | ; This loop iterates 3 times, one for x, one for y and one for z: |
#847f | #1a7f | | | | ; It is used to: |
#847f | #1a7f | | | | ; - check if the player is within the bounding box defined by the object (stored in L5e62_player_collision_with_object_flags). |
#847f | #1a7f | | | | ; - store the relative bounding box coordinates relative to the player in the pointer in L7499_3d_object_bounding_box_relative_to_player_ptr. |
#847f | #1a7f | | | | L847f_player_coordinate_loop: |
#847f | #1a7f | 1 | 12 | c5 | push bc |
#8480 | #1a80 | 1 | 8 | 4e | ld c, (hl) |
#8481 | #1a81 | 1 | 7 | 23 | inc hl |
#8482 | #1a82 | 1 | 8 | 46 | ld b, (hl) ; bc = player coordinate (x, y or z) |
#8483 | #1a83 | 1 | 7 | 23 | inc hl |
#8484 | #1a84 | 1 | 12 | e5 | push hl |
#8485 | #1a85 | 2 | 8 | 2e 00 | ld l, 0 |
#8487 | #1a87 | 3 | 21 | dd 66 01 | ld h, (ix + OBJECT_X) |
#848a | #1a8a | 2 | 10 | cb 3c | srl h |
#848c | #1a8c | 2 | 10 | cb 1d | rr l |
#848e | #1a8e | 2 | 10 | cb 3c | srl h |
#8490 | #1a90 | 2 | 10 | cb 1d | rr l ; hl = object coordinate * 64 |
#8492 | #1a92 | 1 | 5 | b7 | or a |
#8493 | #1a93 | 2 | 17 | ed 42 | sbc hl, bc ; hl = object coordinate * 64 - player coordinate |
#8495 | #1a95 | 2 | 13/8 | 28 05 | jr z, L849c |
#8497 | #1a97 | 3 | 11 | fa 9c 84 | jp m, L849c |
#849a | #1a9a | | | | ; player coordinate < object coordinate 1 |
#849a | #1a9a | 2 | 10 | cb f7 | set 6, a |
#849c | #1a9c | | | | L849c: |
#849c | #1a9c | 2 | 10 | cb 3f | srl a |
#849e | #1a9e | | | | ; save the object coordinate - player coordinate to (de) |
#849e | #1a9e | 1 | 5 | eb | ex de, hl |
#849f | #1a9f | 1 | 8 | 73 | ld (hl), e |
#84a0 | #1aa0 | 1 | 7 | 23 | inc hl |
#84a1 | #1aa1 | 1 | 8 | 72 | ld (hl), d |
#84a2 | #1aa2 | 1 | 7 | 23 | inc hl |
#84a3 | #1aa3 | 1 | 5 | eb | ex de, hl |
#84a4 | #1aa4 | | | | |
#84a4 | #1aa4 | 2 | 8 | 0e 00 | ld c, 0 |
#84a6 | #1aa6 | 3 | 21 | dd 46 04 | ld b, (ix + OBJECT_SIZE_X) |
#84a9 | #1aa9 | 2 | 10 | cb 38 | srl b |
#84ab | #1aab | 2 | 10 | cb 19 | rr c |
#84ad | #1aad | 2 | 10 | cb 38 | srl b |
#84af | #1aaf | 2 | 10 | cb 19 | rr c ; bc = object size * 64 |
#84b1 | #1ab1 | 1 | 5 | b7 | or a |
#84b2 | #1ab2 | 2 | 17 | ed 4a | adc hl, bc ; hl = (coordinate + size) * 64 - player coordinate |
#84b4 | #1ab4 | 3 | 11 | f2 b9 84 | jp p, L84b9 |
#84b7 | #1ab7 | | | | ; player coordinate > object coordinate 2 |
#84b7 | #1ab7 | 2 | 10 | cb f7 | set 6, a |
#84b9 | #1ab9 | | | | L84b9: |
#84b9 | #1ab9 | 2 | 10 | cb 3f | srl a |
#84bb | #1abb | | | | ; save the object coordinate 2 - player coordinate to (de) |
#84bb | #1abb | 1 | 5 | eb | ex de, hl |
#84bc | #1abc | 1 | 8 | 73 | ld (hl), e |
#84bd | #1abd | 1 | 7 | 23 | inc hl |
#84be | #1abe | 1 | 8 | 72 | ld (hl), d |
#84bf | #1abf | 1 | 7 | 23 | inc hl |
#84c0 | #1ac0 | 1 | 5 | eb | ex de, hl |
#84c1 | #1ac1 | 2 | 12 | dd 23 | inc ix |
#84c3 | #1ac3 | 1 | 11 | e1 | pop hl |
#84c4 | #1ac4 | 1 | 11 | c1 | pop bc |
#84c5 | #1ac5 | 2 | 14/9 | 10 b8 | djnz L847f_player_coordinate_loop |
#84c7 | #1ac7 | | | | ; If player is inside of the bounding box, we will have a = #3f |
#84c7 | #1ac7 | | | | ; Each of the 6 bits represents a collision in one of the 6 directions one can collide with a cube, |
#84c7 | #1ac7 | | | | ; If this is 0, it means collision, any other thing than 0 is NO collision. |
#84c7 | #1ac7 | 3 | 14 | 32 62 5e | ld (L5e62_player_collision_with_object_flags), a |
#84ca | #1aca | 4 | 22 | dd 2a 9d 74 | ld ix, (L749d_object_currently_being_processed_ptr) |
#84ce | #1ace | 3 | 21 | dd 7e 07 | ld a, (ix + OBJECT_ID) |
#84d1 | #1ad1 | 3 | 14 | 32 68 74 | ld (L7468_focus_object_id), a |
#84d4 | #1ad4 | 3 | 21 | dd 7e 00 | ld a, (ix + OBJECT_TYPE_AND_FLAGS) |
#84d7 | #1ad7 | 2 | 8 | e6 0f | and #0f |
#84d9 | #1ad9 | 3 | 14 | 32 61 5e | ld (L5e61_object_currently_being_processed_type), a |
#84dc | #1adc | 2 | 8 | fe 01 | cp OBJECT_TYPE_CUBE |
#84de | #1ade | 2 | 13/8 | 20 05 | jr nz, L84e5 |
#84e0 | #1ae0 | 3 | 18 | cd 61 96 | call L9661_project_cube_objects |
#84e3 | #1ae3 | 2 | 13 | 18 16 | jr L84fb_next_object |
#84e5 | #1ae5 | | | | L84e5: |
#84e5 | #1ae5 | 2 | 8 | fe 03 | cp OBJECT_TYPE_RECTANGLE |
#84e7 | #1ae7 | 2 | 13/8 | 20 05 | jr nz, L84ee |
#84e9 | #1ae9 | 3 | 18 | cd 5b 9b | call L9b5b_project_rectangle_objects |
#84ec | #1aec | 2 | 13 | 18 0d | jr L84fb_next_object |
#84ee | #1aee | | | | L84ee: |
#84ee | #1aee | 2 | 8 | fe 0a | cp OBJECT_TYPE_LINE |
#84f0 | #1af0 | 3 | 11 | f2 f8 84 | jp p, L84f8 |
#84f3 | #1af3 | 3 | 18 | cd bb 97 | call L97bb_project_other_solids |
#84f6 | #1af6 | 2 | 13 | 18 03 | jr L84fb_next_object |
#84f8 | #1af8 | | | | L84f8: |
#84f8 | #1af8 | | | | ; Objects with ID >= 10 means that they are basic shapes (line, triangle, quad, pentagon, hexagon.): |
#84f8 | #1af8 | | | | ; - they have ID - 8 vertices in their geometry. |
#84f8 | #1af8 | 3 | 18 | cd c5 9a | call L9ac5_project_flat_shape_object |
#84fb | #1afb | | | | L84fb_next_object: |
#84fb | #1afb | | | | ; Get the pointer to the next object, and loop: |
#84fb | #1afb | 4 | 22 | dd 2a 9d 74 | ld ix, (L749d_object_currently_being_processed_ptr) |
#84ff | #1aff | 3 | 21 | dd 5e 08 | ld e, (ix + OBJECT_SIZE) |
#8502 | #1b02 | 2 | 8 | 16 00 | ld d, 0 |
#8504 | #1b04 | 2 | 17 | dd 19 | add ix, de |
#8506 | #1b06 | 1 | 11 | f1 | pop af |
#8507 | #1b07 | 1 | 5 | 3d | dec a |
#8508 | #1b08 | 3 | 11 | c2 31 84 | jp nz, L8431_object_loop |
#850b | #1b0b | 1 | 11 | c9 | ret |
#850c | #1b0c | | | | |
#850c | #1b0c | | | | |
#850c | #1b0c | | | | ; -------------------------------- |
#850c | #1b0c | | | | ; Auxiliary variables for L850f_apply_rotation_matrix_to_object_vertices |
#850c | #1b0c | | | | L850c_vertex_times_matrix_24bit_accumulator: ; 24 bit number buffer |
#850c | #1b0c | 3 | | | db #00, #00, #00 |
#850f | #1b0f | | | | |
#850f | #1b0f | | | | |
#850f | #1b0f | | | | ; -------------------------------- |
#850f | #1b0f | | | | ; Given object vertex coordinates already relative to the player, |
#850f | #1b0f | | | | ; stored in (L5e63_3d_vertex_coordinates_relative_to_player), this |
#850f | #1b0f | | | | ; method multiplies them by the rotation matrix (L5e55_rotation_matrix), |
#850f | #1b0f | | | | ; and stores the results in (L5e9f_3d_vertex_coordinates_after_rotation_matrix). |
#850f | #1b0f | | | | L850f_apply_rotation_matrix_to_object_vertices: |
#850f | #1b0f | 4 | 16 | fd 21 63 5e | ld iy, L5e63_3d_vertex_coordinates_relative_to_player |
#8513 | #1b13 | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8516 | #1b16 | 3 | 14 | 3a 96 74 | ld a, (L7496_current_drawing_primitive_n_vertices) |
#8519 | #1b19 | 1 | 5 | 4f | ld c, a |
#851a | #1b1a | | | | L851a_vertex_loop: |
#851a | #1b1a | | | | ; Multiply the vertex 3d vector by the rotation matrix: |
#851a | #1b1a | 4 | 16 | dd 21 55 5e | ld ix, L5e55_rotation_matrix |
#851e | #1b1e | 2 | 8 | 06 03 | ld b, 3 |
#8520 | #1b20 | | | | L8520_coordinate_loop: |
#8520 | #1b20 | 1 | 12 | e5 | push hl |
#8521 | #1b21 | | | | ; Zero out the 24bit accumulator: |
#8521 | #1b21 | 1 | 5 | af | xor a |
#8522 | #1b22 | 3 | 14 | 32 0c 85 | ld (L850c_vertex_times_matrix_24bit_accumulator), a |
#8525 | #1b25 | 3 | 14 | 32 0d 85 | ld (L850c_vertex_times_matrix_24bit_accumulator + 1), a |
#8528 | #1b28 | 3 | 14 | 32 0e 85 | ld (L850c_vertex_times_matrix_24bit_accumulator + 2), a |
#852b | #1b2b | | | | ; x * matrix[b][0] |
#852b | #1b2b | 3 | 21 | dd 7e 00 | ld a, (ix) ; ix points to the rotation matrix |
#852e | #1b2e | 2 | 12 | dd 23 | inc ix |
#8530 | #1b30 | 1 | 5 | b7 | or a |
#8531 | #1b31 | 2 | 13/8 | 28 0f | jr z, L8542_multiply_by_0 |
#8533 | #1b33 | 3 | 21 | fd 6e 00 | ld l, (iy) |
#8536 | #1b36 | 3 | 21 | fd 66 01 | ld h, (iy + 1) ; Get "x" vertex coordinate |
#8539 | #1b39 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#853c | #1b3c | 3 | 14 | 32 0e 85 | ld (L850c_vertex_times_matrix_24bit_accumulator + 2), a |
#853f | #1b3f | 3 | 17 | 22 0c 85 | ld (L850c_vertex_times_matrix_24bit_accumulator), hl |
#8542 | #1b42 | | | | L8542_multiply_by_0: |
#8542 | #1b42 | | | | ; y * matrix[b][1] |
#8542 | #1b42 | 3 | 21 | dd 7e 00 | ld a, (ix) |
#8545 | #1b45 | 2 | 12 | dd 23 | inc ix |
#8547 | #1b47 | 1 | 5 | b7 | or a |
#8548 | #1b48 | 2 | 13/8 | 28 19 | jr z, L8563_multiply_by_0 |
#854a | #1b4a | 3 | 21 | fd 6e 02 | ld l, (iy + 2) |
#854d | #1b4d | 3 | 21 | fd 66 03 | ld h, (iy + 3) ; Get "y" vertex coordinate |
#8550 | #1b50 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#8553 | #1b53 | | | | ; Add to the 24 bit accumulator: |
#8553 | #1b53 | 4 | 22 | ed 5b 0c 85 | ld de, (L850c_vertex_times_matrix_24bit_accumulator) |
#8557 | #1b57 | 1 | 12 | 19 | add hl, de |
#8558 | #1b58 | 3 | 17 | 22 0c 85 | ld (L850c_vertex_times_matrix_24bit_accumulator), hl |
#855b | #1b5b | 1 | 5 | 5f | ld e, a |
#855c | #1b5c | 3 | 14 | 3a 0e 85 | ld a, (L850c_vertex_times_matrix_24bit_accumulator + 2) |
#855f | #1b5f | 1 | 5 | 8b | adc a, e |
#8560 | #1b60 | 3 | 14 | 32 0e 85 | ld (L850c_vertex_times_matrix_24bit_accumulator + 2), a |
#8563 | #1b63 | | | | L8563_multiply_by_0: |
#8563 | #1b63 | | | | ; z * matrix[b][2] |
#8563 | #1b63 | 3 | 21 | dd 7e 00 | ld a, (ix) |
#8566 | #1b66 | 2 | 12 | dd 23 | inc ix |
#8568 | #1b68 | 1 | 5 | b7 | or a |
#8569 | #1b69 | 2 | 13/8 | 28 19 | jr z, L8584_multiply_by_0 |
#856b | #1b6b | 3 | 21 | fd 6e 04 | ld l, (iy + 4) |
#856e | #1b6e | 3 | 21 | fd 66 05 | ld h, (iy + 5) ; Get "z" vertex coordinate |
#8571 | #1b71 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#8574 | #1b74 | | | | ; Add to the 24 bit accumulator: |
#8574 | #1b74 | 4 | 22 | ed 5b 0c 85 | ld de, (L850c_vertex_times_matrix_24bit_accumulator) |
#8578 | #1b78 | 1 | 12 | 19 | add hl, de |
#8579 | #1b79 | 3 | 17 | 22 0c 85 | ld (L850c_vertex_times_matrix_24bit_accumulator), hl |
#857c | #1b7c | 1 | 5 | 5f | ld e, a |
#857d | #1b7d | 3 | 14 | 3a 0e 85 | ld a, (L850c_vertex_times_matrix_24bit_accumulator + 2) |
#8580 | #1b80 | 1 | 5 | 8b | adc a, e |
#8581 | #1b81 | 3 | 14 | 32 0e 85 | ld (L850c_vertex_times_matrix_24bit_accumulator + 2), a |
#8584 | #1b84 | | | | L8584_multiply_by_0: |
#8584 | #1b84 | 3 | 17 | 2a 0c 85 | ld hl, (L850c_vertex_times_matrix_24bit_accumulator) |
#8587 | #1b87 | 3 | 14 | 3a 0e 85 | ld a, (L850c_vertex_times_matrix_24bit_accumulator + 2) |
#858a | #1b8a | | | | ; (a, e) = (a, hl) / 64 |
#858a | #1b8a | 1 | 12 | 29 | add hl, hl |
#858b | #1b8b | 1 | 5 | 17 | rla |
#858c | #1b8c | 1 | 12 | 29 | add hl, hl |
#858d | #1b8d | 1 | 5 | 17 | rla |
#858e | #1b8e | 1 | 5 | 5c | ld e, h |
#858f | #1b8f | 1 | 11 | e1 | pop hl |
#8590 | #1b90 | 1 | 8 | 73 | ld (hl), e |
#8591 | #1b91 | 1 | 7 | 23 | inc hl |
#8592 | #1b92 | 1 | 8 | 77 | ld (hl), a |
#8593 | #1b93 | 1 | 7 | 23 | inc hl |
#8594 | #1b94 | 2 | 14/9 | 10 8a | djnz L8520_coordinate_loop |
#8596 | #1b96 | | | | ; next vertex: |
#8596 | #1b96 | 3 | 11 | 11 06 00 | ld de, 6 |
#8599 | #1b99 | 2 | 17 | fd 19 | add iy, de |
#859b | #1b9b | 1 | 5 | 0d | dec c |
#859c | #1b9c | 3 | 11 | c2 1a 85 | jp nz, L851a_vertex_loop |
#859f | #1b9f | 1 | 11 | c9 | ret |
#85a0 | #1ba0 | | | | |
#85a0 | #1ba0 | | | | |
#85a0 | #1ba0 | | | | ; -------------------------------- |
#85a0 | #1ba0 | | | | ; Auxiliary variables for L85ae_clip_edge |
#85a0 | #1ba0 | | | | L85a0_vertex1_coordinates: |
#85a0 | #1ba0 | 6 | | | dw #0000, #0000, #0000 |
#85a6 | #1ba6 | | | | L85a6_vertex2_coordinates: |
#85a6 | #1ba6 | 6 | | | dw #0000, #0000, #0000 |
#85ac | #1bac | | | | L85ac_vertex_frustum_checks: |
#85ac | #1bac | 2 | | | db #00, #00 |
#85ae | #1bae | | | | |
#85ae | #1bae | | | | |
#85ae | #1bae | | | | ; -------------------------------- |
#85ae | #1bae | | | | ; This function clips an edge to make sure both vertices are inside of the viewing area. |
#85ae | #1bae | | | | ; - If both fail the same frustum visibility check, the edge is discarded. |
#85ae | #1bae | | | | ; - Otherwise, for each failed test, a point that intersects with the viewing volume is calculated and the |
#85ae | #1bae | | | | ; point that was outside of the volume is replaced. |
#85ae | #1bae | | | | ; - At the end, if all 5 frustum checks were able to be successfully passed, the points are |
#85ae | #1bae | | | | ; projected. |
#85ae | #1bae | | | | ; Note: I think this method contains several bugs, that might be hard to detect, as |
#85ae | #1bae | | | | ; they might only show up in certain corner cases. But this should be verified. |
#85ae | #1bae | | | | ; I am, of course, not 100% sure. |
#85ae | #1bae | | | | ; Input: |
#85ae | #1bae | | | | ; - ix: ptr to "L5ee8_already_projected_vertex_coordinates" entry for this edge (+ 1) |
#85ae | #1bae | | | | ; - hl: pointer to 3d vertex 1 (after rotation matrix) |
#85ae | #1bae | | | | ; - iy: pointer to 3d vertex 2 (after rotation matrix) |
#85ae | #1bae | | | | ; - c: frustum checks of vertex 1 |
#85ae | #1bae | | | | ; - b: frustum checks of vertex 2 |
#85ae | #1bae | | | | L85ae_clip_edge: |
#85ae | #1bae | | | | ; Save the vertex info to local variables: |
#85ae | #1bae | 4 | 22 | ed 43 ac 85 | ld (L85ac_vertex_frustum_checks), bc |
#85b2 | #1bb2 | 3 | 11 | 01 06 00 | ld bc, 6 |
#85b5 | #1bb5 | 3 | 11 | 11 a0 85 | ld de, L85a0_vertex1_coordinates |
#85b8 | #1bb8 | 2 | 23/18 | ed b0 | ldir |
#85ba | #1bba | 2 | 8 | 0e 06 | ld c, 6 |
#85bc | #1bbc | 2 | 17 | fd e5 | push iy |
#85be | #1bbe | 1 | 11 | e1 | pop hl |
#85bf | #1bbf | 2 | 23/18 | ed b0 | ldir |
#85c1 | #1bc1 | | | | |
#85c1 | #1bc1 | 2 | 17 | dd e5 | push ix |
#85c3 | #1bc3 | 2 | 16 | fd e1 | pop iy ; iy = ptr to "L5ee8_already_projected_vertex_coordinates" entry for this edge (+ 1) |
#85c5 | #1bc5 | 4 | 22 | ed 4b ac 85 | ld bc, (L85ac_vertex_frustum_checks) |
#85c9 | #1bc9 | 2 | 10 | cb 41 | bit 0, c |
#85cb | #1bcb | 2 | 13/8 | 20 07 | jr nz, L85d4 |
#85cd | #1bcd | | | | ; First vertex is behind the camera |
#85cd | #1bcd | 2 | 10 | cb 40 | bit 0, b |
#85cf | #1bcf | 3 | 11 | ca cb 88 | jp z, L88cb_mark_as_processed_and_return ; if both are behind the camera, this edge projects no points. |
#85d2 | #1bd2 | 2 | 13 | 18 05 | jr L85d9 |
#85d4 | #1bd4 | | | | |
#85d4 | #1bd4 | | | | L85d4: |
#85d4 | #1bd4 | | | | ; First point is in front of the camera |
#85d4 | #1bd4 | 2 | 10 | cb 40 | bit 0, b |
#85d6 | #1bd6 | 3 | 11 | c2 66 86 | jp nz, L8666 |
#85d9 | #1bd9 | | | | |
#85d9 | #1bd9 | | | | L85d9: |
#85d9 | #1bd9 | | | | ; One point is behind the camera, and one in front: |
#85d9 | #1bd9 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) ; hl = v1.z |
#85dc | #1bdc | 4 | 22 | ed 5b aa 85 | ld de, (L85a6_vertex2_coordinates + 2 * 2) ; de = v2.z |
#85e0 | #1be0 | 1 | 5 | af | xor a |
#85e1 | #1be1 | 2 | 17 | ed 52 | sbc hl, de ; hl = (v1.z - v2.z) |
#85e3 | #1be3 | 1 | 12 | e5 | push hl |
#85e4 | #1be4 | 1 | 5 | 44 | ld b, h ; bc = (v1.z - v2.z) |
#85e5 | #1be5 | 1 | 5 | 4d | ld c, l |
#85e6 | #1be6 | 3 | 17 | 2a a6 85 | ld hl, (L85a6_vertex2_coordinates) ; hl = v1.x |
#85e9 | #1be9 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) ; de = v2.x |
#85ed | #1bed | 1 | 5 | b7 | or a |
#85ee | #1bee | 2 | 17 | ed 52 | sbc hl, de ; hl = v1.x - v2.x |
#85f0 | #1bf0 | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) ; d2 = v1.z |
#85f4 | #1bf4 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = v1.z * (v1.x - v2.x) |
#85f7 | #1bf7 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed ; (de, hl) = (v1.z * (v1.x - v2.x)) / (v1.z - v2.z) |
#85fa | #1bfa | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) ; v1.x |
#85fe | #1bfe | 1 | 12 | 19 | add hl, de ; hl = v1.z * (v1.x - v2.x) / (v1.z - v2.z) + v1.x |
#85ff | #1bff | 1 | 11 | c1 | pop bc ; bc = (v1.z - v2.z) |
#8600 | #1c00 | 1 | 12 | e5 | push hl |
#8601 | #1c01 | 3 | 17 | 2a a8 85 | ld hl, (L85a6_vertex2_coordinates + 1 * 2) |
#8604 | #1c04 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#8608 | #1c08 | 1 | 5 | b7 | or a |
#8609 | #1c09 | 2 | 17 | ed 52 | sbc hl, de ; hl = v2.y - v1.y |
#860b | #1c0b | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) |
#860f | #1c0f | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = v1.z * (v2.y - v1.y) |
#8612 | #1c12 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed ; (de, hl) = v1.z * (v2.y - v1.y) / (v1.z - v2.z) |
#8615 | #1c15 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#8619 | #1c19 | 1 | 12 | 19 | add hl, de ; (de, hl) = v1.z * (v2.y - v1.y) / (v1.z - v2.z) + v1.y |
#861a | #1c1a | 3 | 11 | 11 00 00 | ld de, 0 |
#861d | #1c1d | 3 | 14 | 3a ac 85 | ld a, (L85ac_vertex_frustum_checks) |
#8620 | #1c20 | 2 | 10 | cb 47 | bit 0, a |
#8622 | #1c22 | 2 | 13/8 | 20 0d | jr nz, L8631_overwrite_vertex2 |
#8624 | #1c24 | | | | ; Overwrite vertex 1: |
#8624 | #1c24 | | | | ; BUG? I think y and z are flipped here and this is wrongly calculated |
#8624 | #1c24 | 3 | 17 | 22 a2 85 | ld (L85a0_vertex1_coordinates + 1 * 2), hl ; v1.y = 0 |
#8627 | #1c27 | 1 | 11 | e1 | pop hl |
#8628 | #1c28 | 3 | 17 | 22 a0 85 | ld (L85a0_vertex1_coordinates), hl ; v1.x = v1.z * (v1.x - v2.x) / (v1.z - v2.z) + v1.x |
#862b | #1c2b | 4 | 22 | ed 53 a4 85 | ld (L85a0_vertex1_coordinates + 2 * 2), de ; v1.z = v1.z * (v2.y - v1.y) / (v1.z - v2.z) + v1.y |
#862f | #1c2f | 2 | 13 | 18 0b | jr L863c_both_vertices_in_front_of_camera |
#8631 | #1c31 | | | | L8631_overwrite_vertex2: |
#8631 | #1c31 | | | | ; BUG? I think y and z are flipped here and this is wrongly calculated |
#8631 | #1c31 | 3 | 17 | 22 a8 85 | ld (L85a6_vertex2_coordinates + 1 * 2), hl |
#8634 | #1c34 | 1 | 11 | e1 | pop hl |
#8635 | #1c35 | 3 | 17 | 22 a6 85 | ld (L85a6_vertex2_coordinates), hl |
#8638 | #1c38 | 4 | 22 | ed 53 aa 85 | ld (L85a6_vertex2_coordinates + 2 * 2), de |
#863c | #1c3c | | | | |
#863c | #1c3c | | | | L863c_both_vertices_in_front_of_camera: |
#863c | #1c3c | | | | ; Update bit 1 of the frustum checks for the new points: |
#863c | #1c3c | 4 | 22 | ed 4b ac 85 | ld bc, (L85ac_vertex_frustum_checks) |
#8640 | #1c40 | | | | ; BUG? bit "1" was "x - z" check in "L9246_object_visibility_check", but here |
#8640 | #1c40 | | | | ; the code is doing "y - z" instead, which should be bit 2. |
#8640 | #1c40 | 2 | 10 | cb c8 | set 1, b |
#8642 | #1c42 | 2 | 10 | cb c9 | set 1, c |
#8644 | #1c44 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) ; v1.z |
#8647 | #1c47 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) ; v1.y |
#864b | #1c4b | 1 | 5 | b7 | or a |
#864c | #1c4c | 2 | 17 | ed 52 | sbc hl, de ; hl = v1.y - v1.z |
#864e | #1c4e | 3 | 11 | f2 53 86 | jp p, L8653 |
#8651 | #1c51 | 2 | 10 | cb 89 | res 1, c |
#8653 | #1c53 | | | | L8653: |
#8653 | #1c53 | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) ; v2.z |
#8656 | #1c56 | 4 | 22 | ed 5b a8 85 | ld de, (L85a6_vertex2_coordinates + 1 * 2) ; v2.y |
#865a | #1c5a | 1 | 5 | b7 | or a |
#865b | #1c5b | 2 | 17 | ed 52 | sbc hl, de ; hl = v2.y - v2.z |
#865d | #1c5d | 3 | 11 | f2 62 86 | jp p, L8662 |
#8660 | #1c60 | 2 | 10 | cb 88 | res 1, b |
#8662 | #1c62 | | | | L8662: |
#8662 | #1c62 | 4 | 22 | ed 43 ac 85 | ld (L85ac_vertex_frustum_checks), bc |
#8666 | #1c66 | | | | |
#8666 | #1c66 | | | | ; The remainder of this function is made out of 4 blocks analogous to the one above, |
#8666 | #1c66 | | | | ; in each block, if both vertexes are found to fail the same frustum check, the edge is |
#8666 | #1c66 | | | | ; ignored, otherwise, if only one of them fails it, a point that intersects with the plane |
#8666 | #1c66 | | | | ; that defines the frustum check in question is found, and the point that failed the check |
#8666 | #1c66 | | | | ; is overwritten. This is done for all 4 remaining frustum checks, and at the end, |
#8666 | #1c66 | | | | ; we can be sure that both points are inside the viewing area. |
#8666 | #1c66 | | | | ; Ensure both vertices pass frustum check 1: |
#8666 | #1c66 | | | | L8666: |
#8666 | #1c66 | 2 | 10 | cb 49 | bit 1, c |
#8668 | #1c68 | 2 | 13/8 | 20 07 | jr nz, L8671 |
#866a | #1c6a | 2 | 10 | cb 48 | bit 1, b |
#866c | #1c6c | 3 | 11 | ca cb 88 | jp z, L88cb_mark_as_processed_and_return |
#866f | #1c6f | 2 | 13 | 18 05 | jr L8676 |
#8671 | #1c71 | | | | L8671: |
#8671 | #1c71 | 2 | 10 | cb 48 | bit 1, b |
#8673 | #1c73 | 3 | 11 | c2 e6 86 | jp nz, L86e6_both_vertices_pass_frustum_check1 |
#8676 | #1c76 | | | | L8676: |
#8676 | #1c76 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) |
#8679 | #1c79 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#867d | #1c7d | 1 | 5 | af | xor a |
#867e | #1c7e | 2 | 17 | ed 52 | sbc hl, de |
#8680 | #1c80 | 1 | 12 | e5 | push hl |
#8681 | #1c81 | 3 | 17 | 2a a8 85 | ld hl, (L85a6_vertex2_coordinates + 1 * 2) |
#8684 | #1c84 | 4 | 16 | dd 21 b3 86 | ld ix, L86b3 |
#8688 | #1c88 | | | | L8688: |
#8688 | #1c88 | 1 | 5 | af | xor a |
#8689 | #1c89 | 2 | 17 | ed 52 | sbc hl, de |
#868b | #1c8b | 4 | 22 | ed 5b aa 85 | ld de, (L85a6_vertex2_coordinates + 2 * 2) |
#868f | #1c8f | 1 | 5 | af | xor a |
#8690 | #1c90 | 2 | 17 | ed 52 | sbc hl, de |
#8692 | #1c92 | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) |
#8696 | #1c96 | 1 | 12 | 19 | add hl, de |
#8697 | #1c97 | 1 | 5 | 44 | ld b, h |
#8698 | #1c98 | 1 | 5 | 4d | ld c, l |
#8699 | #1c99 | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) |
#869c | #1c9c | 1 | 5 | b7 | or a |
#869d | #1c9d | 2 | 17 | ed 52 | sbc hl, de |
#869f | #1c9f | 1 | 11 | d1 | pop de |
#86a0 | #1ca0 | 1 | 12 | d5 | push de |
#86a1 | #1ca1 | 1 | 12 | c5 | push bc |
#86a2 | #1ca2 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#86a5 | #1ca5 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#86a8 | #1ca8 | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) |
#86ac | #1cac | 1 | 12 | 19 | add hl, de |
#86ad | #1cad | 1 | 11 | c1 | pop bc |
#86ae | #1cae | 1 | 11 | d1 | pop de |
#86af | #1caf | 1 | 12 | e5 | push hl |
#86b0 | #1cb0 | 1 | 12 | d5 | push de |
#86b1 | #1cb1 | 2 | 10 | dd e9 | jp ix |
#86b3 | #1cb3 | | | | L86b3: |
#86b3 | #1cb3 | 3 | 17 | 2a a6 85 | ld hl, (L85a6_vertex2_coordinates) |
#86b6 | #1cb6 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#86ba | #1cba | 1 | 5 | af | xor a |
#86bb | #1cbb | 2 | 17 | ed 52 | sbc hl, de |
#86bd | #1cbd | 1 | 11 | d1 | pop de |
#86be | #1cbe | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#86c1 | #1cc1 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#86c4 | #1cc4 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#86c8 | #1cc8 | 1 | 12 | 19 | add hl, de |
#86c9 | #1cc9 | 3 | 14 | 3a ac 85 | ld a, (L85ac_vertex_frustum_checks) |
#86cc | #1ccc | 2 | 10 | cb 4f | bit 1, a |
#86ce | #1cce | 2 | 13/8 | 20 0c | jr nz, L86dc |
#86d0 | #1cd0 | 3 | 17 | 22 a0 85 | ld (L85a0_vertex1_coordinates), hl |
#86d3 | #1cd3 | 1 | 11 | e1 | pop hl |
#86d4 | #1cd4 | 3 | 17 | 22 a2 85 | ld (L85a0_vertex1_coordinates + 1 * 2), hl |
#86d7 | #1cd7 | 3 | 17 | 22 a4 85 | ld (L85a0_vertex1_coordinates + 2 * 2), hl |
#86da | #1cda | 2 | 13 | 18 0a | jr L86e6_both_vertices_pass_frustum_check1 |
#86dc | #1cdc | | | | L86dc: |
#86dc | #1cdc | 3 | 17 | 22 a6 85 | ld (L85a6_vertex2_coordinates), hl |
#86df | #1cdf | 1 | 11 | e1 | pop hl |
#86e0 | #1ce0 | 3 | 17 | 22 a8 85 | ld (L85a6_vertex2_coordinates + 1 * 2), hl |
#86e3 | #1ce3 | 3 | 17 | 22 aa 85 | ld (L85a6_vertex2_coordinates + 2 * 2), hl |
#86e6 | #1ce6 | | | | |
#86e6 | #1ce6 | | | | L86e6_both_vertices_pass_frustum_check1: |
#86e6 | #1ce6 | | | | ; BUG? Same as above, I think these are flipped! |
#86e6 | #1ce6 | | | | ; bit "2" was "y - z" check in "L9246_object_visibility_check", but here |
#86e6 | #1ce6 | | | | ; the code is doing "x - z" instead, which should be bit 1. |
#86e6 | #1ce6 | 4 | 22 | ed 4b ac 85 | ld bc, (L85ac_vertex_frustum_checks) |
#86ea | #1cea | 2 | 10 | cb d0 | set 2, b |
#86ec | #1cec | 2 | 10 | cb d1 | set 2, c |
#86ee | #1cee | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) ; v1.z |
#86f1 | #1cf1 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) ; v1.x |
#86f5 | #1cf5 | 1 | 5 | b7 | or a |
#86f6 | #1cf6 | 2 | 17 | ed 52 | sbc hl, de |
#86f8 | #1cf8 | 3 | 11 | f2 fd 86 | jp p, L86fd |
#86fb | #1cfb | 2 | 10 | cb 91 | res 2, c |
#86fd | #1cfd | | | | L86fd: |
#86fd | #1cfd | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) ; v2.z |
#8700 | #1d00 | 4 | 22 | ed 5b a6 85 | ld de, (L85a6_vertex2_coordinates) ; v2.x |
#8704 | #1d04 | 1 | 5 | b7 | or a |
#8705 | #1d05 | 2 | 17 | ed 52 | sbc hl, de |
#8707 | #1d07 | 3 | 11 | f2 0c 87 | jp p, L870c |
#870a | #1d0a | 2 | 10 | cb 90 | res 2, b |
#870c | #1d0c | | | | L870c: |
#870c | #1d0c | 4 | 22 | ed 43 ac 85 | ld (L85ac_vertex_frustum_checks), bc |
#8710 | #1d10 | 2 | 10 | cb 51 | bit 2, c |
#8712 | #1d12 | 2 | 13/8 | 20 07 | jr nz, L871b |
#8714 | #1d14 | 2 | 10 | cb 50 | bit 2, b |
#8716 | #1d16 | 3 | 11 | ca cb 88 | jp z, L88cb_mark_as_processed_and_return |
#8719 | #1d19 | 2 | 13 | 18 05 | jr L8720 |
#871b | #1d1b | | | | L871b: |
#871b | #1d1b | 2 | 10 | cb 50 | bit 2, b |
#871d | #1d1d | 3 | 11 | c2 68 87 | jp nz, L8768_both_vertices_pass_frustum_check2 |
#8720 | #1d20 | | | | L8720: |
#8720 | #1d20 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) |
#8723 | #1d23 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#8727 | #1d27 | 1 | 5 | af | xor a |
#8728 | #1d28 | 2 | 17 | ed 52 | sbc hl, de |
#872a | #1d2a | 1 | 12 | e5 | push hl |
#872b | #1d2b | 3 | 17 | 2a a6 85 | ld hl, (L85a6_vertex2_coordinates) |
#872e | #1d2e | 4 | 16 | dd 21 35 87 | ld ix, L8735 |
#8732 | #1d32 | 3 | 11 | c3 88 86 | jp L8688 |
#8735 | #1d35 | | | | L8735: |
#8735 | #1d35 | 3 | 17 | 2a a8 85 | ld hl, (L85a6_vertex2_coordinates + 1 * 2) |
#8738 | #1d38 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#873c | #1d3c | 1 | 5 | af | xor a |
#873d | #1d3d | 2 | 17 | ed 52 | sbc hl, de |
#873f | #1d3f | 1 | 11 | d1 | pop de |
#8740 | #1d40 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#8743 | #1d43 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#8746 | #1d46 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#874a | #1d4a | 1 | 12 | 19 | add hl, de |
#874b | #1d4b | 3 | 14 | 3a ac 85 | ld a, (L85ac_vertex_frustum_checks) |
#874e | #1d4e | 2 | 10 | cb 57 | bit 2, a |
#8750 | #1d50 | 2 | 13/8 | 20 0c | jr nz, L875e |
#8752 | #1d52 | 3 | 17 | 22 a2 85 | ld (L85a0_vertex1_coordinates + 1 * 2), hl |
#8755 | #1d55 | 1 | 11 | e1 | pop hl |
#8756 | #1d56 | 3 | 17 | 22 a0 85 | ld (L85a0_vertex1_coordinates), hl |
#8759 | #1d59 | 3 | 17 | 22 a4 85 | ld (L85a0_vertex1_coordinates + 2 * 2), hl |
#875c | #1d5c | 2 | 13 | 18 0a | jr L8768_both_vertices_pass_frustum_check2 |
#875e | #1d5e | | | | L875e: |
#875e | #1d5e | 3 | 17 | 22 a8 85 | ld (L85a6_vertex2_coordinates + 1 * 2), hl |
#8761 | #1d61 | 1 | 11 | e1 | pop hl |
#8762 | #1d62 | 3 | 17 | 22 a6 85 | ld (L85a6_vertex2_coordinates), hl |
#8765 | #1d65 | 3 | 17 | 22 aa 85 | ld (L85a6_vertex2_coordinates + 2 * 2), hl |
#8768 | #1d68 | | | | |
#8768 | #1d68 | | | | L8768_both_vertices_pass_frustum_check2: |
#8768 | #1d68 | 4 | 22 | ed 4b ac 85 | ld bc, (L85ac_vertex_frustum_checks) |
#876c | #1d6c | 2 | 10 | cb d8 | set 3, b |
#876e | #1d6e | 2 | 10 | cb d9 | set 3, c |
#8770 | #1d70 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) ; v1.z |
#8773 | #1d73 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) ; v1.y |
#8777 | #1d77 | 1 | 5 | b7 | or a |
#8778 | #1d78 | 2 | 17 | ed 5a | adc hl, de |
#877a | #1d7a | 3 | 11 | f2 7f 87 | jp p, L877f |
#877d | #1d7d | 2 | 10 | cb 99 | res 3, c |
#877f | #1d7f | | | | L877f: |
#877f | #1d7f | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) ; v2.z |
#8782 | #1d82 | 4 | 22 | ed 5b a8 85 | ld de, (L85a6_vertex2_coordinates + 1 * 2) ; v2.y |
#8786 | #1d86 | 1 | 5 | b7 | or a |
#8787 | #1d87 | 2 | 17 | ed 5a | adc hl, de |
#8789 | #1d89 | 3 | 11 | f2 8e 87 | jp p, L878e |
#878c | #1d8c | 2 | 10 | cb 98 | res 3, b |
#878e | #1d8e | | | | L878e: |
#878e | #1d8e | 4 | 22 | ed 43 ac 85 | ld (L85ac_vertex_frustum_checks), bc |
#8792 | #1d92 | 2 | 10 | cb 59 | bit 3, c |
#8794 | #1d94 | 2 | 13/8 | 20 07 | jr nz, L879d |
#8796 | #1d96 | 2 | 10 | cb 58 | bit 3, b |
#8798 | #1d98 | 3 | 11 | ca cb 88 | jp z, L88cb_mark_as_processed_and_return |
#879b | #1d9b | 2 | 13 | 18 05 | jr L87a2 |
#879d | #1d9d | | | | L879d: |
#879d | #1d9d | 2 | 10 | cb 58 | bit 3, b |
#879f | #1d9f | 3 | 11 | c2 1b 88 | jp nz, L881b_both_vertices_pass_frustum_check3 |
#87a2 | #1da2 | | | | L87a2: |
#87a2 | #1da2 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) |
#87a5 | #1da5 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#87a9 | #1da9 | 1 | 12 | 19 | add hl, de |
#87aa | #1daa | 1 | 12 | e5 | push hl |
#87ab | #1dab | 3 | 17 | 2a a8 85 | ld hl, (L85a6_vertex2_coordinates + 1 * 2) |
#87ae | #1dae | 4 | 16 | dd 21 de 87 | ld ix, L87de |
#87b2 | #1db2 | | | | L87b2: |
#87b2 | #1db2 | 1 | 5 | eb | ex de, hl |
#87b3 | #1db3 | 1 | 5 | af | xor a |
#87b4 | #1db4 | 2 | 17 | ed 52 | sbc hl, de |
#87b6 | #1db6 | 4 | 22 | ed 5b aa 85 | ld de, (L85a6_vertex2_coordinates + 2 * 2) |
#87ba | #1dba | 1 | 5 | af | xor a |
#87bb | #1dbb | 2 | 17 | ed 52 | sbc hl, de |
#87bd | #1dbd | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) |
#87c1 | #1dc1 | 1 | 12 | 19 | add hl, de |
#87c2 | #1dc2 | 1 | 5 | 44 | ld b, h |
#87c3 | #1dc3 | 1 | 5 | 4d | ld c, l |
#87c4 | #1dc4 | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) |
#87c7 | #1dc7 | 1 | 5 | b7 | or a |
#87c8 | #1dc8 | 2 | 17 | ed 52 | sbc hl, de |
#87ca | #1dca | 1 | 11 | d1 | pop de |
#87cb | #1dcb | 1 | 12 | d5 | push de |
#87cc | #1dcc | 1 | 12 | c5 | push bc |
#87cd | #1dcd | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#87d0 | #1dd0 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#87d3 | #1dd3 | 4 | 22 | ed 5b a4 85 | ld de, (L85a0_vertex1_coordinates + 2 * 2) |
#87d7 | #1dd7 | 1 | 12 | 19 | add hl, de |
#87d8 | #1dd8 | 1 | 11 | c1 | pop bc |
#87d9 | #1dd9 | 1 | 11 | d1 | pop de |
#87da | #1dda | 1 | 12 | e5 | push hl |
#87db | #1ddb | 1 | 12 | d5 | push de |
#87dc | #1ddc | 2 | 10 | dd e9 | jp ix |
#87de | #1dde | | | | L87de: |
#87de | #1dde | 3 | 17 | 2a a6 85 | ld hl, (L85a6_vertex2_coordinates) |
#87e1 | #1de1 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#87e5 | #1de5 | 1 | 5 | af | xor a |
#87e6 | #1de6 | 2 | 17 | ed 52 | sbc hl, de |
#87e8 | #1de8 | 1 | 11 | d1 | pop de |
#87e9 | #1de9 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#87ec | #1dec | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#87ef | #1def | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#87f3 | #1df3 | 1 | 12 | 19 | add hl, de |
#87f4 | #1df4 | 1 | 11 | d1 | pop de |
#87f5 | #1df5 | 1 | 5 | 7b | ld a, e |
#87f6 | #1df6 | 1 | 5 | 2f | cpl |
#87f7 | #1df7 | 1 | 5 | 4f | ld c, a |
#87f8 | #1df8 | 1 | 5 | 7a | ld a, d |
#87f9 | #1df9 | 1 | 5 | 2f | cpl |
#87fa | #1dfa | 1 | 5 | 47 | ld b, a |
#87fb | #1dfb | 1 | 7 | 03 | inc bc |
#87fc | #1dfc | 3 | 14 | 3a ac 85 | ld a, (L85ac_vertex_frustum_checks) |
#87ff | #1dff | 2 | 10 | cb 5f | bit 3, a |
#8801 | #1e01 | 2 | 13/8 | 20 0d | jr nz, L8810 |
#8803 | #1e03 | 3 | 17 | 22 a0 85 | ld (L85a0_vertex1_coordinates), hl |
#8806 | #1e06 | 4 | 22 | ed 43 a2 85 | ld (L85a0_vertex1_coordinates + 1 * 2), bc |
#880a | #1e0a | 4 | 22 | ed 53 a4 85 | ld (L85a0_vertex1_coordinates + 2 * 2), de |
#880e | #1e0e | 2 | 13 | 18 0b | jr L881b_both_vertices_pass_frustum_check3 |
#8810 | #1e10 | | | | L8810: |
#8810 | #1e10 | 3 | 17 | 22 a6 85 | ld (L85a6_vertex2_coordinates), hl |
#8813 | #1e13 | 4 | 22 | ed 43 a8 85 | ld (L85a6_vertex2_coordinates + 1 * 2), bc |
#8817 | #1e17 | 4 | 22 | ed 53 aa 85 | ld (L85a6_vertex2_coordinates + 2 * 2), de |
#881b | #1e1b | | | | |
#881b | #1e1b | | | | L881b_both_vertices_pass_frustum_check3: |
#881b | #1e1b | 4 | 22 | ed 4b ac 85 | ld bc, (L85ac_vertex_frustum_checks) |
#881f | #1e1f | 2 | 10 | cb e0 | set 4, b |
#8821 | #1e21 | 2 | 10 | cb e1 | set 4, c |
#8823 | #1e23 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) |
#8826 | #1e26 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#882a | #1e2a | 1 | 5 | b7 | or a |
#882b | #1e2b | 2 | 17 | ed 5a | adc hl, de |
#882d | #1e2d | 3 | 11 | f2 32 88 | jp p, L8832 |
#8830 | #1e30 | 2 | 10 | cb a1 | res 4, c |
#8832 | #1e32 | | | | L8832: |
#8832 | #1e32 | 3 | 17 | 2a aa 85 | ld hl, (L85a6_vertex2_coordinates + 2 * 2) |
#8835 | #1e35 | 4 | 22 | ed 5b a6 85 | ld de, (L85a6_vertex2_coordinates) |
#8839 | #1e39 | 1 | 5 | b7 | or a |
#883a | #1e3a | 2 | 17 | ed 5a | adc hl, de |
#883c | #1e3c | 3 | 11 | f2 41 88 | jp p, L8841 |
#883f | #1e3f | 2 | 10 | cb a0 | res 4, b |
#8841 | #1e41 | | | | L8841: |
#8841 | #1e41 | 4 | 22 | ed 43 ac 85 | ld (L85ac_vertex_frustum_checks), bc |
#8845 | #1e45 | 2 | 10 | cb 61 | bit 4, c |
#8847 | #1e47 | 2 | 13/8 | 20 07 | jr nz, L8850 |
#8849 | #1e49 | 2 | 10 | cb 60 | bit 4, b |
#884b | #1e4b | 3 | 11 | ca cb 88 | jp z, L88cb_mark_as_processed_and_return |
#884e | #1e4e | 2 | 13 | 18 05 | jr L8855 |
#8850 | #1e50 | | | | L8850: |
#8850 | #1e50 | 2 | 10 | cb 60 | bit 4, b |
#8852 | #1e52 | 3 | 11 | c2 a5 88 | jp nz, L88a5_both_vertices_pass_frustum_check4 |
#8855 | #1e55 | | | | L8855: |
#8855 | #1e55 | 3 | 17 | 2a a4 85 | ld hl, (L85a0_vertex1_coordinates + 2 * 2) |
#8858 | #1e58 | 4 | 22 | ed 5b a0 85 | ld de, (L85a0_vertex1_coordinates) |
#885c | #1e5c | 1 | 12 | 19 | add hl, de |
#885d | #1e5d | 1 | 12 | e5 | push hl |
#885e | #1e5e | 3 | 17 | 2a a6 85 | ld hl, (L85a6_vertex2_coordinates) |
#8861 | #1e61 | 4 | 16 | dd 21 68 88 | ld ix, L8868 |
#8865 | #1e65 | 3 | 11 | c3 b2 87 | jp L87b2 |
#8868 | #1e68 | | | | L8868: |
#8868 | #1e68 | 3 | 17 | 2a a8 85 | ld hl, (L85a6_vertex2_coordinates + 1 * 2) |
#886b | #1e6b | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#886f | #1e6f | 1 | 5 | af | xor a |
#8870 | #1e70 | 2 | 17 | ed 52 | sbc hl, de |
#8872 | #1e72 | 1 | 11 | d1 | pop de |
#8873 | #1e73 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#8876 | #1e76 | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#8879 | #1e79 | 4 | 22 | ed 5b a2 85 | ld de, (L85a0_vertex1_coordinates + 1 * 2) |
#887d | #1e7d | 1 | 12 | 19 | add hl, de |
#887e | #1e7e | 1 | 11 | d1 | pop de |
#887f | #1e7f | 1 | 5 | 7b | ld a, e |
#8880 | #1e80 | 1 | 5 | 2f | cpl |
#8881 | #1e81 | 1 | 5 | 4f | ld c, a |
#8882 | #1e82 | 1 | 5 | 7a | ld a, d |
#8883 | #1e83 | 1 | 5 | 2f | cpl |
#8884 | #1e84 | 1 | 5 | 47 | ld b, a |
#8885 | #1e85 | 1 | 7 | 03 | inc bc |
#8886 | #1e86 | 3 | 14 | 3a ac 85 | ld a, (L85ac_vertex_frustum_checks) |
#8889 | #1e89 | 2 | 10 | cb 67 | bit 4, a |
#888b | #1e8b | 2 | 13/8 | 20 0d | jr nz, L889a |
#888d | #1e8d | 4 | 22 | ed 43 a0 85 | ld (L85a0_vertex1_coordinates), bc |
#8891 | #1e91 | 3 | 17 | 22 a2 85 | ld (L85a0_vertex1_coordinates + 1 * 2), hl |
#8894 | #1e94 | 4 | 22 | ed 53 a4 85 | ld (L85a0_vertex1_coordinates + 2 * 2), de |
#8898 | #1e98 | 2 | 13 | 18 0b | jr L88a5_both_vertices_pass_frustum_check4 |
#889a | #1e9a | | | | L889a: |
#889a | #1e9a | 4 | 22 | ed 43 a6 85 | ld (L85a6_vertex2_coordinates), bc |
#889e | #1e9e | 3 | 17 | 22 a8 85 | ld (L85a6_vertex2_coordinates + 1 * 2), hl |
#88a1 | #1ea1 | 4 | 22 | ed 53 aa 85 | ld (L85a6_vertex2_coordinates + 2 * 2), de |
#88a5 | #1ea5 | | | | |
#88a5 | #1ea5 | | | | L88a5_both_vertices_pass_frustum_check4: |
#88a5 | #1ea5 | | | | ; We are done clipping the edge, now project whichever vertex needs |
#88a5 | #1ea5 | | | | ; projecting: |
#88a5 | #1ea5 | 2 | 8 | 3e ff | ld a, #ff |
#88a7 | #1ea7 | 3 | 21 | fd be 00 | cp (iy) |
#88aa | #1eaa | 2 | 13/8 | 20 0d | jr nz, L88b9 |
#88ac | #1eac | | | | ; Vertex 1 needs projecting: |
#88ac | #1eac | 4 | 16 | dd 21 a0 85 | ld ix, L85a0_vertex1_coordinates |
#88b0 | #1eb0 | 3 | 18 | cd fc 90 | call L90fc_project_one_vertex |
#88b3 | #1eb3 | 3 | 21 | fd 71 00 | ld (iy), c ; x |
#88b6 | #1eb6 | 3 | 21 | fd 70 01 | ld (iy + 1), b ; y |
#88b9 | #1eb9 | | | | L88b9: |
#88b9 | #1eb9 | 3 | 21 | fd be 02 | cp (iy + 2) |
#88bc | #1ebc | 2 | 13/8 | 20 0d | jr nz, L88cb_mark_as_processed_and_return |
#88be | #1ebe | | | | ; Vertex 2 needs projecting: |
#88be | #1ebe | 4 | 16 | dd 21 a6 85 | ld ix, L85a6_vertex2_coordinates |
#88c2 | #1ec2 | 3 | 18 | cd fc 90 | call L90fc_project_one_vertex |
#88c5 | #1ec5 | 3 | 21 | fd 71 02 | ld (iy + 2), c ; x |
#88c8 | #1ec8 | 3 | 21 | fd 70 03 | ld (iy + 3), b ; y |
#88cb | #1ecb | | | | L88cb_mark_as_processed_and_return: |
#88cb | #1ecb | 2 | 8 | 3e 01 | ld a, 1 |
#88cd | #1ecd | 3 | 21 | fd 77 ffff | ld (iy - 1), a ; mark edge as processed |
#88d0 | #1ed0 | 1 | 11 | c9 | ret |
#88d1 | #1ed1 | | | | |
#88d1 | #1ed1 | | | | |
#88d1 | #1ed1 | | | | ; -------------------------------- |
#88d1 | #1ed1 | | | | ; Checks if the normal of a face points away from the camera (and potentially we do not need to draw the face). |
#88d1 | #1ed1 | | | | ; Input: |
#88d1 | #1ed1 | | | | ; - iy: pointer to the vertex indexes of this face |
#88d1 | #1ed1 | | | | ; Output: |
#88d1 | #1ed1 | | | | ; - a: 1 (back face), 0 (front face). |
#88d1 | #1ed1 | | | | ; - carry flag set (same as "a"): back face. |
#88d1 | #1ed1 | | | | L88d1_normal_direction_check: |
#88d1 | #1ed1 | 2 | 17 | dd e5 | push ix |
#88d3 | #1ed3 | 1 | 12 | e5 | push hl |
#88d4 | #1ed4 | 1 | 12 | d5 | push de |
#88d5 | #1ed5 | 1 | 12 | c5 | push bc |
#88d6 | #1ed6 | 4 | 22 | dd 2a 24 5f | ld ix, (L5f24_shape_edges_ptr) |
#88da | #1eda | 2 | 12 | dd 23 | inc ix ; skip the number of edges |
#88dc | #1edc | 2 | 17 | dd e5 | push ix |
#88de | #1ede | 3 | 21 | fd 7e 00 | ld a, (iy) |
#88e1 | #1ee1 | 1 | 5 | 6f | ld l, a |
#88e2 | #1ee2 | 2 | 8 | e6 7f | and #7f ; get the index (remove a potential flag in the msb) |
#88e4 | #1ee4 | 1 | 5 | 4f | ld c, a |
#88e5 | #1ee5 | 2 | 8 | 06 00 | ld b, 0 |
#88e7 | #1ee7 | 2 | 10 | cb 21 | sla c |
#88e9 | #1ee9 | 2 | 17 | dd 09 | add ix, bc ; ix = ptr to the edge |
#88eb | #1eeb | 3 | 21 | dd 4e 00 | ld c, (ix) ; c = vertex index 1 |
#88ee | #1eee | 3 | 21 | dd 7e 01 | ld a, (ix + 1) ; a = vertex index 2 |
#88f1 | #1ef1 | 2 | 10 | cb 7d | bit 7, l ; vertex index flag check |
#88f3 | #1ef3 | 2 | 13/8 | 28 03 | jr z, L88f8 |
#88f5 | #1ef5 | | | | ; Invert the vertexes in the current edge: |
#88f5 | #1ef5 | 1 | 5 | 61 | ld h, c |
#88f6 | #1ef6 | 1 | 5 | 4f | ld c, a |
#88f7 | #1ef7 | 1 | 5 | 7c | ld a, h |
#88f8 | #1ef8 | | | | L88f8: |
#88f8 | #1ef8 | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#88fb | #1efb | 2 | 10 | cb 21 | sla c |
#88fd | #1efd | 1 | 12 | 09 | add hl, bc |
#88fe | #1efe | 2 | 10 | cb 21 | sla c |
#8900 | #1f00 | 1 | 12 | 09 | add hl, bc ; hl += 6 * vertex index 1 |
#8901 | #1f01 | 3 | 11 | 11 63 5e | ld de, L5e63_3d_vertex_coordinates_relative_to_player |
#8904 | #1f04 | | | | ; Copy vertex 1: |
#8904 | #1f04 | 2 | 8 | 0e 06 | ld c, 6 |
#8906 | #1f06 | 2 | 23/18 | ed b0 | ldir |
#8908 | #1f08 | 1 | 5 | 4f | ld c, a |
#8909 | #1f09 | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#890c | #1f0c | 2 | 10 | cb 21 | sla c |
#890e | #1f0e | 1 | 12 | 09 | add hl, bc |
#890f | #1f0f | 2 | 10 | cb 21 | sla c |
#8911 | #1f11 | 1 | 12 | 09 | add hl, bc ; hl += 6 * vertex index 2 |
#8912 | #1f12 | | | | ; Copy vertex 2: |
#8912 | #1f12 | 2 | 8 | 0e 06 | ld c, 6 |
#8914 | #1f14 | 2 | 23/18 | ed b0 | ldir |
#8916 | #1f16 | 3 | 21 | fd 7e 01 | ld a, (iy + 1) |
#8919 | #1f19 | 1 | 5 | 6f | ld l, a |
#891a | #1f1a | 2 | 8 | e6 7f | and #7f ; get the index (remove a potential flag in the msb) |
#891c | #1f1c | 2 | 16 | dd e1 | pop ix |
#891e | #1f1e | 1 | 5 | 4f | ld c, a |
#891f | #1f1f | 2 | 10 | cb 21 | sla c |
#8921 | #1f21 | 2 | 17 | dd 09 | add ix, bc ; ix = ptr to the edge |
#8923 | #1f23 | 3 | 21 | dd 4e 00 | ld c, (ix) |
#8926 | #1f26 | 2 | 10 | cb 7d | bit 7, l |
#8928 | #1f28 | 2 | 13/8 | 20 03 | jr nz, L892d |
#892a | #1f2a | 3 | 21 | dd 4e 01 | ld c, (ix + 1) ; if edge flip flag is 1, get the other vertex. |
#892d | #1f2d | | | | L892d: |
#892d | #1f2d | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8930 | #1f30 | 2 | 10 | cb 21 | sla c |
#8932 | #1f32 | 1 | 12 | 09 | add hl, bc |
#8933 | #1f33 | 2 | 10 | cb 21 | sla c |
#8935 | #1f35 | 1 | 12 | 09 | add hl, bc ; hl += 6 * vertex index 1 |
#8936 | #1f36 | | | | ; Copy vertex 3: |
#8936 | #1f36 | 2 | 8 | 0e 06 | ld c, 6 |
#8938 | #1f38 | 2 | 23/18 | ed b0 | ldir |
#893a | #1f3a | | | | |
#893a | #1f3a | | | | ; At this point we have picked the first 3 vertices of the face. |
#893a | #1f3a | | | | ; We now calculate the normal vector: |
#893a | #1f3a | | | | ; OPTIMIZATION: faces should have the normal pre-calculated, rather than doing all this calculation each time. |
#893a | #1f3a | | | | ; Just one additional point to be ran through the rotation matrix, and we avoid all of this. |
#893a | #1f3a | 1 | 5 | 60 | ld h, b |
#893b | #1f3b | 1 | 5 | 69 | ld l, c ; hl = 0 |
#893c | #1f3c | 3 | 17 | 22 75 5e | ld (L5e75_48_bit_accumulator), hl |
#893f | #1f3f | 3 | 17 | 22 77 5e | ld (L5e75_48_bit_accumulator + 2), hl |
#8942 | #1f42 | 3 | 17 | 22 79 5e | ld (L5e75_48_bit_accumulator + 4), hl |
#8945 | #1f45 | 3 | 17 | 2a 67 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 2 * 2) ; z vertex 1 |
#8948 | #1f48 | 4 | 22 | ed 5b 6d 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 5 * 2) ; z vertex 2 |
#894c | #1f4c | 1 | 5 | b7 | or a |
#894d | #1f4d | 2 | 17 | ed 52 | sbc hl, de ; hl = z1 - z2 |
#894f | #1f4f | 1 | 12 | e5 | push hl |
#8950 | #1f50 | 3 | 17 | 2a 71 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 7 * 2) ; y vertex 3 |
#8953 | #1f53 | 4 | 22 | ed 5b 6b 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 4 * 2) ; y vertex 2 |
#8957 | #1f57 | 1 | 5 | b7 | or a |
#8958 | #1f58 | 2 | 17 | ed 52 | sbc hl, de ; hl = y3 - y2 |
#895a | #1f5a | 1 | 11 | d1 | pop de |
#895b | #1f5b | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = (z1 - z2) * (y3 - y2) |
#895e | #1f5e | 1 | 12 | d5 | push de |
#895f | #1f5f | 1 | 12 | e5 | push hl |
#8960 | #1f60 | 3 | 17 | 2a 65 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 1 * 2) ; y vertex 1 |
#8963 | #1f63 | 4 | 22 | ed 5b 6b 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 4 * 2) ; y vertex 2 |
#8967 | #1f67 | 1 | 5 | b7 | or a |
#8968 | #1f68 | 2 | 17 | ed 52 | sbc hl, de |
#896a | #1f6a | 1 | 12 | e5 | push hl |
#896b | #1f6b | 3 | 17 | 2a 73 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 8 * 2) ; z vertex 3 |
#896e | #1f6e | 4 | 22 | ed 5b 6d 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 5 * 2) ; z vertex 2 |
#8972 | #1f72 | 1 | 5 | b7 | or a |
#8973 | #1f73 | 2 | 17 | ed 52 | sbc hl, de |
#8975 | #1f75 | 1 | 11 | d1 | pop de |
#8976 | #1f76 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#8979 | #1f79 | 1 | 11 | c1 | pop bc |
#897a | #1f7a | 1 | 5 | af | xor a |
#897b | #1f7b | 2 | 17 | ed 42 | sbc hl, bc |
#897d | #1f7d | 1 | 11 | c1 | pop bc |
#897e | #1f7e | 1 | 5 | eb | ex de, hl |
#897f | #1f7f | 2 | 17 | ed 42 | sbc hl, bc |
#8981 | #1f81 | 1 | 5 | eb | ex de, hl |
#8982 | #1f82 | 4 | 22 | ed 4b 69 5e | ld bc, (L5e63_3d_vertex_coordinates_relative_to_player + 3 * 2) ; x vertex 2 |
#8986 | #1f86 | 3 | 18 | cd 30 8a | call L8a30_48bitmul_add |
#8989 | #1f89 | 3 | 17 | 2a 63 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player) ; x vertex 1 |
#898c | #1f8c | 4 | 22 | ed 5b 69 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 3 * 2) ; x vertex 2 |
#8990 | #1f90 | 1 | 5 | b7 | or a |
#8991 | #1f91 | 2 | 17 | ed 52 | sbc hl, de |
#8993 | #1f93 | 1 | 12 | e5 | push hl |
#8994 | #1f94 | 3 | 17 | 2a 73 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 8 * 2) ; z vertex 3 |
#8997 | #1f97 | 4 | 22 | ed 5b 6d 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 5 * 2) ; z vertex 2 |
#899b | #1f9b | 1 | 5 | b7 | or a |
#899c | #1f9c | 2 | 17 | ed 52 | sbc hl, de |
#899e | #1f9e | 1 | 11 | d1 | pop de |
#899f | #1f9f | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#89a2 | #1fa2 | 1 | 12 | d5 | push de |
#89a3 | #1fa3 | 1 | 12 | e5 | push hl |
#89a4 | #1fa4 | 3 | 17 | 2a 67 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 2 * 2) ; z vertex 1 |
#89a7 | #1fa7 | 4 | 22 | ed 5b 6d 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 5 * 2) ; z vertex 2 |
#89ab | #1fab | 1 | 5 | b7 | or a |
#89ac | #1fac | 2 | 17 | ed 52 | sbc hl, de |
#89ae | #1fae | 1 | 12 | e5 | push hl |
#89af | #1faf | 3 | 17 | 2a 6f 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 6 * 2) ; x vertex 3 |
#89b2 | #1fb2 | 4 | 22 | ed 5b 69 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 3 * 2) ; x vertex 2 |
#89b6 | #1fb6 | 1 | 5 | b7 | or a |
#89b7 | #1fb7 | 2 | 17 | ed 52 | sbc hl, de |
#89b9 | #1fb9 | 1 | 11 | d1 | pop de |
#89ba | #1fba | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed |
#89bd | #1fbd | 1 | 11 | c1 | pop bc |
#89be | #1fbe | 1 | 5 | af | xor a |
#89bf | #1fbf | 2 | 17 | ed 42 | sbc hl, bc |
#89c1 | #1fc1 | 1 | 11 | c1 | pop bc |
#89c2 | #1fc2 | 1 | 5 | eb | ex de, hl |
#89c3 | #1fc3 | 2 | 17 | ed 42 | sbc hl, bc |
#89c5 | #1fc5 | 1 | 5 | eb | ex de, hl |
#89c6 | #1fc6 | 4 | 22 | ed 4b 6b 5e | ld bc, (L5e63_3d_vertex_coordinates_relative_to_player + 4 * 2) |
#89ca | #1fca | 3 | 18 | cd 30 8a | call L8a30_48bitmul_add |
#89cd | #1fcd | 3 | 17 | 2a 65 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 2) |
#89d0 | #1fd0 | 4 | 22 | ed 5b 6b 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 4 * 2) |
#89d4 | #1fd4 | 1 | 5 | b7 | or a |
#89d5 | #1fd5 | 2 | 17 | ed 52 | sbc hl, de |
#89d7 | #1fd7 | 1 | 12 | e5 | push hl |
#89d8 | #1fd8 | 3 | 17 | 2a 6f 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 6 * 2) |
#89db | #1fdb | 4 | 22 | ed 5b 69 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 3 * 2) |
#89df | #1fdf | 1 | 5 | b7 | or a |
#89e0 | #1fe0 | 2 | 17 | ed 52 | sbc hl, de |
#89e2 | #1fe2 | 1 | 11 | d1 | pop de |
#89e3 | #1fe3 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = (z v1 - y v2) * (x v3 - x v2) |
#89e6 | #1fe6 | 1 | 12 | d5 | push de |
#89e7 | #1fe7 | 1 | 12 | e5 | push hl |
#89e8 | #1fe8 | 3 | 17 | 2a 63 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player) |
#89eb | #1feb | 4 | 22 | ed 5b 69 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 3 * 2) |
#89ef | #1fef | 1 | 5 | b7 | or a |
#89f0 | #1ff0 | 2 | 17 | ed 52 | sbc hl, de |
#89f2 | #1ff2 | 1 | 12 | e5 | push hl |
#89f3 | #1ff3 | 3 | 17 | 2a 71 5e | ld hl, (L5e63_3d_vertex_coordinates_relative_to_player + 7 * 2) |
#89f6 | #1ff6 | 4 | 22 | ed 5b 6b 5e | ld de, (L5e63_3d_vertex_coordinates_relative_to_player + 4 * 2) |
#89fa | #1ffa | 1 | 5 | b7 | or a |
#89fb | #1ffb | 2 | 17 | ed 52 | sbc hl, de |
#89fd | #1ffd | 1 | 11 | d1 | pop de |
#89fe | #1ffe | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = (x v1 - x v2) * (y v3 - y v2) |
#8a01 | #2001 | 1 | 11 | c1 | pop bc |
#8a02 | #2002 | 1 | 5 | af | xor a |
#8a03 | #2003 | 2 | 17 | ed 42 | sbc hl, bc |
#8a05 | #2005 | 1 | 11 | c1 | pop bc |
#8a06 | #2006 | 1 | 5 | eb | ex de, hl |
#8a07 | #2007 | 2 | 17 | ed 42 | sbc hl, bc ; hl = (z v1 - y v2) * (x v3 - x v2) - (x v1 - x v2) * (y v3 - y v2) |
#8a09 | #2009 | 1 | 12 | e5 | push hl |
#8a0a | #200a | 1 | 5 | eb | ex de, hl |
#8a0b | #200b | 4 | 22 | ed 4b 6d 5e | ld bc, (L5e63_3d_vertex_coordinates_relative_to_player + 5 * 2) |
#8a0f | #200f | 3 | 18 | cd 30 8a | call L8a30_48bitmul_add |
#8a12 | #2012 | 1 | 11 | e1 | pop hl |
#8a13 | #2013 | 3 | 14 | 3a 7a 5e | ld a, (L5e75_48_bit_accumulator + 5) |
#8a16 | #2016 | | | | |
#8a16 | #2016 | | | | ; Check if the normal points forward or backwards: |
#8a16 | #2016 | | | | ; At this point: |
#8a16 | #2016 | | | | ; - a: has the most significant byte of the accumulator (to get the sign of the z coordinate of the normal). |
#8a16 | #2016 | | | | ; - hl: most significant word of "(x v1 - x v2) * (y v3 - y v2) - (z v1 - y v2) * (x v3 - x v2)" |
#8a16 | #2016 | 1 | 5 | 6f | ld l, a |
#8a17 | #2017 | 1 | 5 | ac | xor h |
#8a18 | #2018 | 3 | 11 | f2 1f 8a | jp p, L8a1f |
#8a1b | #201b | | | | ; We get here if the "normal z" has the same sign as "(x v1 - x v2) * (y v3 - y v2) - (z v1 - y v2) * (x v3 - x v2)". |
#8a1b | #201b | | | | ; This gives the face a chance to be drawn if when projected to the screen no vertices fall inside of the view area, |
#8a1b | #201b | | | | ; and the code will check if it's that the face is too big and covers the whole screen. |
#8a1b | #201b | | | | ; Note: I am not sure of what the math means here, as I have not tried to derive what the value of the calculation |
#8a1b | #201b | | | | ; means. |
#8a1b | #201b | 1 | 5 | af | xor a |
#8a1c | #201c | 3 | 14 | 32 28 5f | ld (L5f28_cull_face_when_no_projected_vertices), a |
#8a1f | #201f | | | | L8a1f: |
#8a1f | #201f | 1 | 5 | 7d | ld a, l |
#8a20 | #2020 | 1 | 5 | b7 | or a |
#8a21 | #2021 | 3 | 11 | f2 27 8a | jp p, L8a27 |
#8a24 | #2024 | | | | ; Normal points towrads the camera, this is a front face. |
#8a24 | #2024 | 1 | 5 | af | xor a |
#8a25 | #2025 | 2 | 13 | 18 03 | jr L8a2a |
#8a27 | #2027 | | | | L8a27: |
#8a27 | #2027 | | | | ; Normal points away from camera, this is a back face. |
#8a27 | #2027 | 2 | 8 | 3e 01 | ld a, 1 |
#8a29 | #2029 | 1 | 5 | 37 | scf |
#8a2a | #202a | | | | L8a2a: |
#8a2a | #202a | 1 | 11 | c1 | pop bc |
#8a2b | #202b | 1 | 11 | d1 | pop de |
#8a2c | #202c | 1 | 11 | e1 | pop hl |
#8a2d | #202d | 2 | 16 | dd e1 | pop ix |
#8a2f | #202f | 1 | 11 | c9 | ret |
#8a30 | #2030 | | | | |
#8a30 | #2030 | | | | |
#8a30 | #2030 | | | | ; -------------------------------- |
#8a30 | #2030 | | | | ; Performs the following operation: |
#8a30 | #2030 | | | | ; - First, calculate the multiplication bc * (bc, hl) |
#8a30 | #2030 | | | | ; - Then add the 48 bit result to the 48 bit number in (L5e75_48_bit_accumulator) |
#8a30 | #2030 | | | | ; - Result is saved in (L5e75_48_bit_accumulator) |
#8a30 | #2030 | | | | ; The signed 32 bit result is returned in (DE,HL) |
#8a30 | #2030 | | | | ; Input: |
#8a30 | #2030 | | | | ; - bc |
#8a30 | #2030 | | | | ; - (de, hl) |
#8a30 | #2030 | | | | ; - 6 bytes in (L5e75_48_bit_accumulator) |
#8a30 | #2030 | | | | ; Output: |
#8a30 | #2030 | | | | ; - 6 bytes in (L5e75_48_bit_accumulator) |
#8a30 | #2030 | | | | L8a30_48bitmul_add: |
#8a30 | #2030 | 2 | 10 | cb 7a | bit 7, d |
#8a32 | #2032 | 2 | 13/8 | 28 14 | jr z, L8a48_de_hl_positive |
#8a34 | #2034 | | | | ; if (de, hl) is negative, calculate the absolute value: |
#8a34 | #2034 | 1 | 5 | 7c | ld a, h |
#8a35 | #2035 | 1 | 5 | 2f | cpl |
#8a36 | #2036 | 1 | 5 | 67 | ld h, a |
#8a37 | #2037 | 1 | 5 | 7d | ld a, l |
#8a38 | #2038 | 1 | 5 | 2f | cpl |
#8a39 | #2039 | 1 | 5 | 6f | ld l, a |
#8a3a | #203a | 1 | 5 | 7a | ld a, d |
#8a3b | #203b | 1 | 5 | 2f | cpl |
#8a3c | #203c | 1 | 5 | 57 | ld d, a |
#8a3d | #203d | 1 | 5 | 7b | ld a, e |
#8a3e | #203e | 1 | 5 | 2f | cpl |
#8a3f | #203f | 1 | 5 | 5f | ld e, a |
#8a40 | #2040 | | | | |
#8a40 | #2040 | 1 | 7 | 23 | inc hl |
#8a41 | #2041 | 1 | 5 | 7d | ld a, l |
#8a42 | #2042 | 1 | 5 | b4 | or h |
#8a43 | #2043 | 2 | 8 | 3e 01 | ld a, 1 ; mark that we changed the sign |
#8a45 | #2045 | 2 | 13/8 | 20 01 | jr nz, L8a48_de_hl_positive |
#8a47 | #2047 | 1 | 7 | 13 | inc de |
#8a48 | #2048 | | | | L8a48_de_hl_positive: |
#8a48 | #2048 | 2 | 10 | cb 78 | bit 7, b |
#8a4a | #204a | 2 | 13/8 | 28 0b | jr z, L8a57_bc_positive |
#8a4c | #204c | | | | ; if bc is negative, calculate the absolute value: |
#8a4c | #204c | 1 | 12 | f5 | push af |
#8a4d | #204d | 1 | 5 | 78 | ld a, b |
#8a4e | #204e | 1 | 5 | 2f | cpl |
#8a4f | #204f | 1 | 5 | 47 | ld b, a |
#8a50 | #2050 | 1 | 5 | 79 | ld a, c |
#8a51 | #2051 | 1 | 5 | 2f | cpl |
#8a52 | #2052 | 1 | 5 | 4f | ld c, a |
#8a53 | #2053 | 1 | 7 | 03 | inc bc |
#8a54 | #2054 | 1 | 11 | f1 | pop af |
#8a55 | #2055 | 2 | 8 | ee 01 | xor 1 ; mark that we changed the sign (if we changed the sign of only one of bc, or (de, hl), a = 1). |
#8a57 | #2057 | | | | L8a57_bc_positive: |
#8a57 | #2057 | | | | ; Perform a multiplciation in the following way: |
#8a57 | #2057 | | | | ; de hl |
#8a57 | #2057 | | | | ; * bc |
#8a57 | #2057 | | | | ; ------- |
#8a57 | #2057 | | | | ; AA BB <- bc * hl |
#8a57 | #2057 | | | | ; CC DD |
#8a57 | #2057 | | | | ; -------- |
#8a57 | #2057 | | | | ; hl bc de |
#8a57 | #2057 | 1 | 12 | d5 | push de |
#8a58 | #2058 | 1 | 5 | 59 | ld e, c |
#8a59 | #2059 | 1 | 5 | 50 | ld d, b |
#8a5a | #205a | 3 | 18 | cd b4 8a | call L8ab4_de_times_hl_signed ; (AA, BB) = hl * bc |
#8a5d | #205d | | | | ; We temporarily save the result in RAM: |
#8a5d | #205d | 3 | 17 | 22 7b 5e | ld (L5e7b_48bitmul_tmp1), hl ; save BB |
#8a60 | #2060 | 4 | 22 | ed 53 7d 5e | ld (L5e7d_48bitmul_tmp2), de ; save AA |
#8a64 | #2064 | 1 | 11 | d1 | pop de |
#8a65 | #2065 | 1 | 5 | 69 | ld l, c |
#8a66 | #2066 | 1 | 5 | 60 | ld h, b |
#8a67 | #2067 | 3 | 18 | cd b4 8a | call L8ab4_de_times_hl_signed ; (CC, DD) = de * bc |
#8a6a | #206a | 4 | 22 | ed 4b 7d 5e | ld bc, (L5e7d_48bitmul_tmp2) ; recover AA |
#8a6e | #206e | 1 | 12 | 09 | add hl, bc ; AA + DD |
#8a6f | #206f | 1 | 5 | 44 | ld b, h |
#8a70 | #2070 | 1 | 5 | 4d | ld c, l ; bc = AA + DD |
#8a71 | #2071 | 3 | 11 | 21 00 00 | ld hl, 0 |
#8a74 | #2074 | 2 | 17 | ed 5a | adc hl, de ; hl = CC + (carry of AA + DD) |
#8a76 | #2076 | 4 | 22 | ed 5b 7b 5e | ld de, (L5e7b_48bitmul_tmp1) ; recover BB |
#8a7a | #207a | | | | ; At this point (hl, bc, de) has the absolute value of the 48 bit result of the multiplication |
#8a7a | #207a | | | | ; Check if we need to change the sign of the result: |
#8a7a | #207a | 1 | 5 | b7 | or a |
#8a7b | #207b | 2 | 13/8 | 28 1d | jr z, L8a9a_result_is_positive |
#8a7d | #207d | | | | ; Make the result negative: |
#8a7d | #207d | 1 | 5 | 7c | ld a, h |
#8a7e | #207e | 1 | 5 | 2f | cpl |
#8a7f | #207f | 1 | 5 | 67 | ld h, a |
#8a80 | #2080 | 1 | 5 | 7d | ld a, l |
#8a81 | #2081 | 1 | 5 | 2f | cpl |
#8a82 | #2082 | 1 | 5 | 6f | ld l, a |
#8a83 | #2083 | 1 | 5 | 78 | ld a, b |
#8a84 | #2084 | 1 | 5 | 2f | cpl |
#8a85 | #2085 | 1 | 5 | 47 | ld b, a |
#8a86 | #2086 | 1 | 5 | 79 | ld a, c |
#8a87 | #2087 | 1 | 5 | 2f | cpl |
#8a88 | #2088 | 1 | 5 | 4f | ld c, a |
#8a89 | #2089 | 1 | 5 | 7a | ld a, d |
#8a8a | #208a | 1 | 5 | 2f | cpl |
#8a8b | #208b | 1 | 5 | 57 | ld d, a |
#8a8c | #208c | 1 | 5 | 7b | ld a, e |
#8a8d | #208d | 1 | 5 | 2f | cpl |
#8a8e | #208e | 1 | 5 | 5f | ld e, a |
#8a8f | #208f | 1 | 7 | 13 | inc de |
#8a90 | #2090 | 1 | 5 | 7b | ld a, e |
#8a91 | #2091 | 1 | 5 | b2 | or d |
#8a92 | #2092 | 2 | 13/8 | 20 06 | jr nz, L8a9a_result_is_positive |
#8a94 | #2094 | 1 | 7 | 03 | inc bc |
#8a95 | #2095 | 1 | 5 | 79 | ld a, c |
#8a96 | #2096 | 1 | 5 | b0 | or b |
#8a97 | #2097 | 2 | 13/8 | 20 01 | jr nz, L8a9a_result_is_positive |
#8a99 | #2099 | 1 | 7 | 23 | inc hl |
#8a9a | #209a | | | | L8a9a_result_is_positive: |
#8a9a | #209a | | | | ; At this point (hl, bc, de) has the 48 bit result of the multiplication |
#8a9a | #209a | | | | ; Add this 48 bit number with the 48 bit number stored in (L5e75_48_bit_accumulator) |
#8a9a | #209a | 1 | 12 | e5 | push hl |
#8a9b | #209b | 3 | 17 | 2a 75 5e | ld hl, (L5e75_48_bit_accumulator) |
#8a9e | #209e | 1 | 12 | 19 | add hl, de |
#8a9f | #209f | 3 | 17 | 22 75 5e | ld (L5e75_48_bit_accumulator), hl |
#8aa2 | #20a2 | 3 | 17 | 2a 77 5e | ld hl, (L5e75_48_bit_accumulator + 2) |
#8aa5 | #20a5 | 2 | 17 | ed 4a | adc hl, bc |
#8aa7 | #20a7 | 3 | 17 | 22 77 5e | ld (L5e75_48_bit_accumulator + 2), hl |
#8aaa | #20aa | 3 | 17 | 2a 79 5e | ld hl, (L5e75_48_bit_accumulator + 4) |
#8aad | #20ad | 1 | 11 | c1 | pop bc |
#8aae | #20ae | 2 | 17 | ed 4a | adc hl, bc |
#8ab0 | #20b0 | 3 | 17 | 22 79 5e | ld (L5e75_48_bit_accumulator + 4), hl |
#8ab3 | #20b3 | 1 | 11 | c9 | ret |
#8ab4 | #20b4 | | | | |
#8ab4 | #20b4 | | | | |
#8ab4 | #20b4 | | | | ; -------------------------------- |
#8ab4 | #20b4 | | | | ; Signed multiplication between DE and HL. |
#8ab4 | #20b4 | | | | ; The signed 32 bit result is returned in (DE,HL) |
#8ab4 | #20b4 | | | | ; Input: |
#8ab4 | #20b4 | | | | ; - de |
#8ab4 | #20b4 | | | | ; - hl |
#8ab4 | #20b4 | | | | ; Output: |
#8ab4 | #20b4 | | | | ; - de, hl |
#8ab4 | #20b4 | | | | L8ab4_de_times_hl_signed: |
#8ab4 | #20b4 | 1 | 12 | c5 | push bc |
#8ab5 | #20b5 | 1 | 12 | f5 | push af |
#8ab6 | #20b6 | 1 | 5 | 7c | ld a, h |
#8ab7 | #20b7 | 1 | 5 | 4d | ld c, l |
#8ab8 | #20b8 | 2 | 8 | 06 10 | ld b, 16 |
#8aba | #20ba | 3 | 11 | 21 00 00 | ld hl, 0 |
#8abd | #20bd | | | | L8abd: |
#8abd | #20bd | 2 | 10 | cb 21 | sla c |
#8abf | #20bf | 1 | 5 | 17 | rla |
#8ac0 | #20c0 | 2 | 13/8 | 38 0c | jr c, L8ace |
#8ac2 | #20c2 | 2 | 14/9 | 10 f9 | djnz L8abd |
#8ac4 | #20c4 | 1 | 5 | 50 | ld d, b |
#8ac5 | #20c5 | 1 | 5 | 58 | ld e, b |
#8ac6 | #20c6 | 2 | 13 | 18 11 | jr L8ad9 |
#8ac8 | #20c8 | | | | L8ac8: |
#8ac8 | #20c8 | 1 | 12 | 29 | add hl, hl |
#8ac9 | #20c9 | 2 | 10 | cb 11 | rl c |
#8acb | #20cb | 1 | 5 | 17 | rla |
#8acc | #20cc | 2 | 13/8 | 30 07 | jr nc, L8ad5 |
#8ace | #20ce | | | | L8ace: |
#8ace | #20ce | 1 | 12 | 19 | add hl, de |
#8acf | #20cf | 2 | 13/8 | 30 04 | jr nc, L8ad5 |
#8ad1 | #20d1 | 1 | 5 | 0c | inc c |
#8ad2 | #20d2 | 2 | 13/8 | 20 01 | jr nz, L8ad5 |
#8ad4 | #20d4 | 1 | 5 | 3c | inc a |
#8ad5 | #20d5 | | | | L8ad5: |
#8ad5 | #20d5 | 2 | 14/9 | 10 f1 | djnz L8ac8 |
#8ad7 | #20d7 | 1 | 5 | 57 | ld d, a |
#8ad8 | #20d8 | 1 | 5 | 59 | ld e, c |
#8ad9 | #20d9 | | | | L8ad9: |
#8ad9 | #20d9 | 1 | 11 | f1 | pop af |
#8ada | #20da | 1 | 11 | c1 | pop bc |
#8adb | #20db | 1 | 11 | c9 | ret |
#8adc | #20dc | | | | |
#8adc | #20dc | | | | |
#8adc | #20dc | | | | ; -------------------------------- |
#8adc | #20dc | | | | ; Projects an object, and if it falls within the screen, add it to the list of objects to draw, |
#8adc | #20dc | | | | ; assuming that all vertexes are in screen (if a single one is out, whole object is discarted) |
#8adc | #20dc | | | | ; Input: |
#8adc | #20dc | | | | ; - iy: face definition ptr: |
#8adc | #20dc | | | | ; - first byte is number of faces |
#8adc | #20dc | | | | ; - then, each face has: |
#8adc | #20dc | | | | ; - attribute |
#8adc | #20dc | | | | ; - number of vertices |
#8adc | #20dc | | | | ; - then one byte per vertex (index) |
#8adc | #20dc | | | | L8adc_project_object_and_add_to_render_list_internal: |
#8adc | #20dc | 3 | 14 | 3a 96 74 | ld a, (L7496_current_drawing_primitive_n_vertices) |
#8adf | #20df | 1 | 5 | 47 | ld b, a |
#8ae0 | #20e0 | | | | ; Initialize the L5ee8_already_projected_vertex_coordinates array: |
#8ae0 | #20e0 | | | | ; Since different edges might share vertexes, when we project a vertex, |
#8ae0 | #20e0 | | | | ; we mark it in this array, to prevent projecting them again. |
#8ae0 | #20e0 | 3 | 11 | 21 e8 5e | ld hl, L5ee8_already_projected_vertex_coordinates |
#8ae3 | #20e3 | 2 | 8 | 3e ff | ld a, #ff ; mark that a vertex has not been projected. |
#8ae5 | #20e5 | | | | L8ae5: |
#8ae5 | #20e5 | 1 | 8 | 77 | ld (hl), a |
#8ae6 | #20e6 | 1 | 7 | 23 | inc hl |
#8ae7 | #20e7 | 1 | 7 | 23 | inc hl |
#8ae8 | #20e8 | 2 | 14/9 | 10 fb | djnz L8ae5 |
#8aea | #20ea | | | | |
#8aea | #20ea | 1 | 5 | af | xor a |
#8aeb | #20eb | 3 | 14 | 32 5f 5e | ld (L5e5f_add_to_projected_objects_flag), a |
#8aee | #20ee | 3 | 17 | 2a 97 74 | ld hl, (L7497_next_projected_vertex_ptr) |
#8af1 | #20f1 | 3 | 14 | 3a 68 74 | ld a, (L7468_focus_object_id) |
#8af4 | #20f4 | | | | ; Start writing the projected vertex data: |
#8af4 | #20f4 | 1 | 8 | 77 | ld (hl), a ; object ID |
#8af5 | #20f5 | 1 | 7 | 23 | inc hl |
#8af6 | #20f6 | 2 | 11 | 36 00 | ld (hl), 0 ; number of primitives (init to zero, and will be incremented each time a face is added). |
#8af8 | #20f8 | 1 | 7 | 23 | inc hl |
#8af9 | #20f9 | 3 | 21 | fd 46 00 | ld b, (iy) ; number of faces |
#8afc | #20fc | 2 | 12 | fd 23 | inc iy |
#8afe | #20fe | | | | L8afe_face_loop: |
#8afe | #20fe | 1 | 12 | c5 | push bc |
#8aff | #20ff | 3 | 21 | fd 7e 00 | ld a, (iy) ; a = texture ID. |
#8b02 | #2102 | 2 | 12 | fd 23 | inc iy |
#8b04 | #2104 | 3 | 21 | fd 46 00 | ld b, (iy) ; b = number of vertices in the face. |
#8b07 | #2107 | 2 | 12 | fd 23 | inc iy |
#8b09 | #2109 | | | | ; If it's a transparent face, ignore: |
#8b09 | #2109 | 1 | 5 | b7 | or a |
#8b0a | #210a | 2 | 13/8 | 28 18 | jr z, L8b24_skip_face_bytes_and_next_face |
#8b0c | #210c | 2 | 10 | cb 27 | sla a |
#8b0e | #210e | 2 | 10 | cb 27 | sla a |
#8b10 | #2110 | 2 | 10 | cb 27 | sla a |
#8b12 | #2112 | 2 | 10 | cb 27 | sla a |
#8b14 | #2114 | 1 | 5 | 4f | ld c, a |
#8b15 | #2115 | 3 | 14 | 3a 60 5e | ld a, (L5e60_projection_pre_work_type) |
#8b18 | #2118 | | | | ; - if a == 0: indicates that vertices can be projected directly. |
#8b18 | #2118 | | | | ; - if a == 1: we need to call L88d1_normal_direction_check before projection, and if back-face, we cull |
#8b18 | #2118 | | | | ; - if a == 2: we need to call L88d1_normal_direction_check before projection, and if back-face we need to use L5f26_alternative_shape_edges_ptr |
#8b18 | #2118 | 1 | 5 | b7 | or a |
#8b19 | #2119 | 2 | 13/8 | 28 35 | jr z, L8b50_ready_to_project |
#8b1b | #211b | 2 | 8 | fe 01 | cp 1 |
#8b1d | #211d | 2 | 13/8 | 20 0d | jr nz, L8b2c |
#8b1f | #211f | | | | |
#8b1f | #211f | | | | ; Normal check, and cull if failed: |
#8b1f | #211f | 3 | 18 | cd d1 88 | call L88d1_normal_direction_check |
#8b22 | #2122 | 2 | 13/8 | 30 2c | jr nc, L8b50_ready_to_project |
#8b24 | #2124 | | | | ; back face! |
#8b24 | #2124 | | | | L8b24_skip_face_bytes_and_next_face: |
#8b24 | #2124 | 1 | 5 | 48 | ld c, b |
#8b25 | #2125 | 2 | 8 | 06 00 | ld b, 0 |
#8b27 | #2127 | 2 | 17 | fd 09 | add iy, bc |
#8b29 | #2129 | 3 | 11 | c3 b1 8b | jp L8bb1_next_face |
#8b2c | #212c | | | | |
#8b2c | #212c | | | | L8b2c: |
#8b2c | #212c | 3 | 18 | cd d1 88 | call L88d1_normal_direction_check |
#8b2f | #212f | 3 | 14 | 3a 6a 74 | ld a, (L746a_current_drawing_texture_id) |
#8b32 | #2132 | 2 | 13/8 | 30 0f | jr nc, L8b43 |
#8b34 | #2134 | | | | ; back face, we need to swap texture ID, and use alternative shape edges ptr: |
#8b34 | #2134 | 2 | 8 | e6 f0 | and #f0 |
#8b36 | #2136 | 2 | 13/8 | 28 ec | jr z, L8b24_skip_face_bytes_and_next_face |
#8b38 | #2138 | 1 | 5 | 4f | ld c, a |
#8b39 | #2139 | 4 | 22 | ed 5b 26 5f | ld de, (L5f26_alternative_shape_edges_ptr) |
#8b3d | #213d | 4 | 22 | ed 53 24 5f | ld (L5f24_shape_edges_ptr), de |
#8b41 | #2141 | 2 | 13 | 18 0d | jr L8b50_ready_to_project |
#8b43 | #2143 | | | | |
#8b43 | #2143 | | | | L8b43: |
#8b43 | #2143 | 2 | 8 | e6 0f | and #0f |
#8b45 | #2145 | 2 | 13/8 | 28 dd | jr z, L8b24_skip_face_bytes_and_next_face |
#8b47 | #2147 | 2 | 10 | cb 27 | sla a |
#8b49 | #2149 | 2 | 10 | cb 27 | sla a |
#8b4b | #214b | 2 | 10 | cb 27 | sla a |
#8b4d | #214d | 2 | 10 | cb 27 | sla a |
#8b4f | #214f | 1 | 5 | 4f | ld c, a |
#8b50 | #2150 | | | | L8b50_ready_to_project: |
#8b50 | #2150 | | | | ; At this point: |
#8b50 | #2150 | | | | ; - b: number of vertices |
#8b50 | #2150 | | | | ; - c: texture ID (in the most significant 4 bits) |
#8b50 | #2150 | | | | ; - hl: pointer to the resulting projected vertex data (about to write texture byte) |
#8b50 | #2150 | | | | ; - iy: ptr to the face vertex indexes |
#8b50 | #2150 | 1 | 5 | 79 | ld a, c |
#8b51 | #2151 | 1 | 5 | b0 | or b |
#8b52 | #2152 | 1 | 8 | 77 | ld (hl), a ; save # vertices and texture ID |
#8b53 | #2153 | 1 | 7 | 23 | inc hl |
#8b54 | #2154 | | | | L8b54_vertex_loop: |
#8b54 | #2154 | 1 | 12 | c5 | push bc |
#8b55 | #2155 | 3 | 21 | fd 7e 00 | ld a, (iy) ; edge index |
#8b58 | #2158 | 2 | 8 | e6 7f | and #7f ; get the index (remove a potential flag in the msb) |
#8b5a | #215a | 2 | 10 | cb 27 | sla a |
#8b5c | #215c | 1 | 5 | 4f | ld c, a |
#8b5d | #215d | 2 | 8 | 06 00 | ld b, 0 |
#8b5f | #215f | 4 | 22 | dd 2a 24 5f | ld ix, (L5f24_shape_edges_ptr) |
#8b63 | #2163 | 2 | 12 | dd 23 | inc ix ; skip the number of edges |
#8b65 | #2165 | 2 | 17 | dd 09 | add ix, bc ; ix = ptr to the edge |
#8b67 | #2167 | 4 | 22 | fd cb 00 7e | bit 7, (iy) |
#8b6b | #216b | 2 | 13/8 | 28 02 | jr z, L8b6f |
#8b6d | #216d | 2 | 12 | dd 23 | inc ix ; If the msb flag is set, we invert the vertex in the edge |
#8b6f | #216f | | | | L8b6f: |
#8b6f | #216f | 2 | 12 | fd 23 | inc iy ; next index |
#8b71 | #2171 | 3 | 21 | dd 4e 00 | ld c, (ix) ; get the vertex index |
#8b74 | #2174 | 2 | 10 | cb 21 | sla c ; vertex index * 2 |
#8b76 | #2176 | 4 | 16 | dd 21 e8 5e | ld ix, L5ee8_already_projected_vertex_coordinates |
#8b7a | #217a | 2 | 17 | dd 09 | add ix, bc |
#8b7c | #217c | 3 | 21 | dd 7e 00 | ld a, (ix) |
#8b7f | #217f | | | | ; Check if we have already projected the vertex: |
#8b7f | #217f | 2 | 8 | fe ff | cp #ff |
#8b81 | #2181 | 2 | 13/8 | 20 18 | jr nz, L8b9b_already_projected |
#8b83 | #2183 | | | | ; We have not projected it yet, so, we project it now: |
#8b83 | #2183 | 2 | 17 | dd e5 | push ix |
#8b85 | #2185 | 4 | 16 | dd 21 9f 5e | ld ix, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8b89 | #2189 | 2 | 17 | dd 09 | add ix, bc |
#8b8b | #218b | 2 | 17 | dd 09 | add ix, bc |
#8b8d | #218d | 2 | 17 | dd 09 | add ix, bc |
#8b8f | #218f | 3 | 18 | cd fc 90 | call L90fc_project_one_vertex |
#8b92 | #2192 | 2 | 16 | dd e1 | pop ix |
#8b94 | #2194 | | | | ; Save the projected coordinates (c, b) to the temporary L5ee8_already_projected_vertex_coordinates array. |
#8b94 | #2194 | 3 | 21 | dd 71 00 | ld (ix), c |
#8b97 | #2197 | 3 | 21 | dd 70 01 | ld (ix + 1), b |
#8b9a | #219a | 1 | 5 | 79 | ld a, c ; a = projected x |
#8b9b | #219b | | | | L8b9b_already_projected: |
#8b9b | #219b | | | | ; Write the projected coordiantes to the projected vertices data for rendering: |
#8b9b | #219b | 1 | 8 | 77 | ld (hl), a ; x |
#8b9c | #219c | 1 | 7 | 23 | inc hl |
#8b9d | #219d | 3 | 21 | dd 7e 01 | ld a, (ix + 1) ; y |
#8ba0 | #21a0 | 1 | 8 | 77 | ld (hl), a |
#8ba1 | #21a1 | 1 | 7 | 23 | inc hl |
#8ba2 | #21a2 | 1 | 11 | c1 | pop bc |
#8ba3 | #21a3 | 2 | 14/9 | 10 af | djnz L8b54_vertex_loop |
#8ba5 | #21a5 | | | | |
#8ba5 | #21a5 | 2 | 8 | 3e 01 | ld a, 1 |
#8ba7 | #21a7 | 3 | 14 | 32 5f 5e | ld (L5e5f_add_to_projected_objects_flag), a |
#8baa | #21aa | 4 | 22 | dd 2a 97 74 | ld ix, (L7497_next_projected_vertex_ptr) |
#8bae | #21ae | 3 | 25 | dd 34 01 | inc (ix + 1) ; increment the number of primitives counter |
#8bb1 | #21b1 | | | | L8bb1_next_face: |
#8bb1 | #21b1 | 1 | 11 | c1 | pop bc |
#8bb2 | #21b2 | 1 | 5 | 05 | dec b |
#8bb3 | #21b3 | 3 | 11 | c2 fe 8a | jp nz, L8afe_face_loop |
#8bb6 | #21b6 | 1 | 11 | c9 | ret |
#8bb7 | #21b7 | | | | |
#8bb7 | #21b7 | | | | |
#8bb7 | #21b7 | | | | ; -------------------------------- |
#8bb7 | #21b7 | | | | ; Sets the rendering volume, a cube (to prune which obejcts to render). |
#8bb7 | #21b7 | | | | L8bb7_determine_rendering_volume: |
#8bb7 | #21b7 | 3 | 14 | 3a bd 6a | ld a, (L6abd_cull_by_rendering_volume_flag) ; if we are not culling by volume, just return |
#8bba | #21ba | 1 | 5 | b7 | or a |
#8bbb | #21bb | 1 | 12/6 | c0 | ret nz |
#8bbc | #21bc | | | | ; Clear the L745d_rendering_cube_volume to #ff: |
#8bbc | #21bc | 3 | 11 | 21 5d 74 | ld hl, L745d_rendering_cube_volume |
#8bbf | #21bf | 2 | 8 | 06 06 | ld b, 6 |
#8bc1 | #21c1 | 1 | 5 | 3d | dec a |
#8bc2 | #21c2 | | | | L8bc2_clear_memory_loop: |
#8bc2 | #21c2 | 1 | 8 | 77 | ld (hl), a ; a == #ff here |
#8bc3 | #21c3 | 1 | 7 | 23 | inc hl |
#8bc4 | #21c4 | 2 | 14/9 | 10 fc | djnz L8bc2_clear_memory_loop |
#8bc6 | #21c6 | | | | |
#8bc6 | #21c6 | | | | ; This loop is executed 4 times, each time adjusting the |
#8bc6 | #21c6 | | | | ; pitch/yaw andles up or down by 8 units, and each time, |
#8bc6 | #21c6 | | | | ; the values in L745d_rendering_cube_volume are being set: |
#8bc6 | #21c6 | 2 | 8 | 26 04 | ld h, 4 |
#8bc8 | #21c8 | 4 | 16 | dd 21 5d 74 | ld ix, L745d_rendering_cube_volume |
#8bcc | #21cc | | | | L8bcc_angle_loop: |
#8bcc | #21cc | 1 | 5 | 7c | ld a, h ; h is the iteration index (4, 3, 2, 1) |
#8bcd | #21cd | 2 | 8 | fe 03 | cp 3 |
#8bcf | #21cf | 3 | 14 | 3a b7 6a | ld a, (L6ab7_player_yaw_angle) |
#8bd2 | #21d2 | 2 | 13/8 | 30 0a | jr nc, L8bde |
#8bd4 | #21d4 | | | | ; Iterations 1, 2: |
#8bd4 | #21d4 | | | | ; If we are too close to the upper limit, wrap around |
#8bd4 | #21d4 | 2 | 8 | c6 08 | add a, 8 |
#8bd6 | #21d6 | 2 | 8 | fe 48 | cp FULL_ROTATION_DEGREES |
#8bd8 | #21d8 | 2 | 13/8 | 38 0a | jr c, L8be4_yaw_set |
#8bda | #21da | 2 | 8 | d6 48 | sub FULL_ROTATION_DEGREES |
#8bdc | #21dc | 2 | 13 | 18 06 | jr L8be4_yaw_set |
#8bde | #21de | | | | L8bde: |
#8bde | #21de | | | | ; Iterations 3, 4: |
#8bde | #21de | | | | ; If we are too close to the lower limit, wrap around |
#8bde | #21de | 2 | 8 | d6 08 | sub 8 |
#8be0 | #21e0 | 2 | 13/8 | 30 02 | jr nc, L8be4_yaw_set |
#8be2 | #21e2 | 2 | 8 | c6 48 | add a, FULL_ROTATION_DEGREES |
#8be4 | #21e4 | | | | L8be4_yaw_set: |
#8be4 | #21e4 | | | | ; Here we have a = (L6ab7_player_yaw_angle) |
#8be4 | #21e4 | 1 | 5 | 47 | ld b, a |
#8be5 | #21e5 | 2 | 10 | cb 44 | bit 0, h |
#8be7 | #21e7 | 3 | 14 | 3a b6 6a | ld a, (L6ab6_player_pitch_angle) |
#8bea | #21ea | 2 | 13/8 | 28 0a | jr z, L8bf6 |
#8bec | #21ec | | | | ; Iterations 1 and 3: |
#8bec | #21ec | 2 | 8 | c6 08 | add a, 8 |
#8bee | #21ee | 2 | 8 | fe 48 | cp FULL_ROTATION_DEGREES |
#8bf0 | #21f0 | 2 | 13/8 | 38 0a | jr c, L8bfc_pitch_set |
#8bf2 | #21f2 | 2 | 8 | d6 48 | sub FULL_ROTATION_DEGREES |
#8bf4 | #21f4 | 2 | 13 | 18 06 | jr L8bfc_pitch_set |
#8bf6 | #21f6 | | | | L8bf6: |
#8bf6 | #21f6 | | | | ; Iterations 2 and 4: |
#8bf6 | #21f6 | 2 | 8 | d6 08 | sub 8 |
#8bf8 | #21f8 | 2 | 13/8 | 30 02 | jr nc, L8bfc_pitch_set |
#8bfa | #21fa | 2 | 8 | c6 48 | add a, FULL_ROTATION_DEGREES |
#8bfc | #21fc | | | | L8bfc_pitch_set: |
#8bfc | #21fc | 1 | 5 | 4f | ld c, a |
#8bfd | #21fd | | | | ; Here: b = yaw, c = pitch. |
#8bfd | #21fd | 1 | 5 | 78 | ld a, b |
#8bfe | #21fe | 2 | 8 | fe 12 | cp FULL_ROTATION_DEGREES / 4 |
#8c00 | #2200 | 2 | 13/8 | 30 04 | jr nc, L8c06 |
#8c02 | #2202 | 2 | 8 | 16 01 | ld d, 1 |
#8c04 | #2204 | 2 | 13 | 18 12 | jr L8c18 |
#8c06 | #2206 | | | | L8c06: |
#8c06 | #2206 | 2 | 8 | fe 24 | cp FULL_ROTATION_DEGREES / 2 |
#8c08 | #2208 | 2 | 13/8 | 30 04 | jr nc, L8c0e |
#8c0a | #220a | 2 | 8 | 16 03 | ld d, 3 |
#8c0c | #220c | 2 | 13 | 18 0a | jr L8c18 |
#8c0e | #220e | | | | L8c0e: |
#8c0e | #220e | 2 | 8 | fe 36 | cp 3 * FULL_ROTATION_DEGREES / 4 |
#8c10 | #2210 | 2 | 13/8 | 30 04 | jr nc, L8c16 |
#8c12 | #2212 | 2 | 8 | 16 05 | ld d, 5 |
#8c14 | #2214 | 2 | 13 | 18 02 | jr L8c18 |
#8c16 | #2216 | | | | L8c16: |
#8c16 | #2216 | 2 | 8 | 16 07 | ld d, 7 |
#8c18 | #2218 | | | | L8c18: |
#8c18 | #2218 | 1 | 5 | 79 | ld a, c |
#8c19 | #2219 | 2 | 8 | fe 12 | cp FULL_ROTATION_DEGREES / 4 |
#8c1b | #221b | 2 | 13/8 | 30 03 | jr nc, L8c20 |
#8c1d | #221d | 1 | 5 | 14 | inc d |
#8c1e | #221e | 2 | 13 | 18 16 | jr L8c36 |
#8c20 | #2220 | | | | L8c20: |
#8c20 | #2220 | 2 | 8 | fe 24 | cp FULL_ROTATION_DEGREES / 2 |
#8c22 | #2222 | 2 | 13/8 | 30 04 | jr nc, L8c28 |
#8c24 | #2224 | 2 | 8 | 3e 05 | ld a, 5 |
#8c26 | #2226 | 2 | 13 | 18 06 | jr L8c2e |
#8c28 | #2228 | | | | L8c28: |
#8c28 | #2228 | 2 | 8 | fe 36 | cp 3 * FULL_ROTATION_DEGREES / 4 |
#8c2a | #222a | 2 | 13/8 | 30 0a | jr nc, L8c36 |
#8c2c | #222c | 2 | 8 | 3e 04 | ld a, 4 |
#8c2e | #222e | | | | L8c2e: |
#8c2e | #222e | 1 | 5 | 82 | add a, d |
#8c2f | #222f | 2 | 8 | fe 09 | cp 9 |
#8c31 | #2231 | 2 | 13/8 | 38 02 | jr c, L8c35 |
#8c33 | #2233 | 2 | 8 | d6 08 | sub 8 |
#8c35 | #2235 | | | | L8c35: |
#8c35 | #2235 | 1 | 5 | 57 | ld d, a |
#8c36 | #2236 | | | | L8c36: |
#8c36 | #2236 | | | | ; Here: |
#8c36 | #2236 | | | | ; - d has some number based on the quadrants of pitch/yaw |
#8c36 | #2236 | | | | ; - these are used to set the limits: |
#8c36 | #2236 | | | | ; - in the x/z axis, the maximum limits are [0, 127] |
#8c36 | #2236 | | | | ; - in the y axis it is [0, 63] |
#8c36 | #2236 | | | | ; - all limits that are not set will be replaced by player coordinates. |
#8c36 | #2236 | 1 | 5 | 15 | dec d |
#8c37 | #2237 | 2 | 13/8 | 20 06 | jr nz, L8c3f |
#8c39 | #2239 | | | | ; d == 1: yaw 1st quadrant, pitch 4th quadrant: |
#8c39 | #2239 | 4 | 21 | dd 36 00 7f | ld (ix), 127 |
#8c3d | #223d | 2 | 13 | 18 44 | jr L8c83 |
#8c3f | #223f | | | | L8c3f: |
#8c3f | #223f | 1 | 5 | 15 | dec d |
#8c40 | #2240 | 2 | 13/8 | 20 06 | jr nz, L8c48 |
#8c42 | #2242 | | | | ; d == 2: yaw 1st quadrant, pitch 1st quadrant: |
#8c42 | #2242 | 4 | 21 | dd 36 00 7f | ld (ix), 127 |
#8c46 | #2246 | 2 | 13 | 18 45 | jr L8c8d |
#8c48 | #2248 | | | | L8c48: |
#8c48 | #2248 | 1 | 5 | 15 | dec d |
#8c49 | #2249 | 2 | 13/8 | 20 0a | jr nz, L8c55 |
#8c4b | #224b | | | | ; d == 3: yaw 2nd quadrant, pitch 4th quadrant: |
#8c4b | #224b | 4 | 21 | dd 36 00 7f | ld (ix), 127 |
#8c4f | #224f | 4 | 21 | dd 36 02 3f | ld (ix + 2), 63 |
#8c53 | #2253 | 2 | 13 | 18 21 | jr L8c76 |
#8c55 | #2255 | | | | L8c55: |
#8c55 | #2255 | 1 | 5 | 15 | dec d |
#8c56 | #2256 | 2 | 13/8 | 20 06 | jr nz, L8c5e |
#8c58 | #2258 | | | | ; d == 4: yaw 2nd quadrant, pitch 1st quadrant: |
#8c58 | #2258 | 4 | 21 | dd 36 00 7f | ld (ix), 127 |
#8c5c | #225c | 2 | 13 | 18 14 | jr L8c72 |
#8c5e | #225e | | | | L8c5e: |
#8c5e | #225e | 1 | 5 | 15 | dec d |
#8c5f | #225f | 2 | 13/8 | 20 0a | jr nz, L8c6b |
#8c61 | #2261 | | | | ; d == 5: yaw 1st quadrant, pitch 4th quadrant, or |
#8c61 | #2261 | | | | ; yaw 2nd quadrant, pitch 1st quadrant |
#8c61 | #2261 | 4 | 21 | dd 36 01 00 | ld (ix + 1), 0 |
#8c65 | #2265 | 4 | 21 | dd 36 02 3f | ld (ix + 2), 63 |
#8c69 | #2269 | 2 | 13 | 18 0b | jr L8c76 |
#8c6b | #226b | | | | L8c6b: |
#8c6b | #226b | 1 | 5 | 15 | dec d |
#8c6c | #226c | 2 | 13/8 | 20 0e | jr nz, L8c7c |
#8c6e | #226e | | | | ; d == 6: ... |
#8c6e | #226e | 4 | 21 | dd 36 01 00 | ld (ix + 1), 0 |
#8c72 | #2272 | | | | L8c72: |
#8c72 | #2272 | 4 | 21 | dd 36 03 00 | ld (ix + 3), 0 |
#8c76 | #2276 | | | | L8c76: |
#8c76 | #2276 | 4 | 21 | dd 36 05 00 | ld (ix + 5), 0 |
#8c7a | #227a | 2 | 13 | 18 19 | jr L8c95 |
#8c7c | #227c | | | | L8c7c: |
#8c7c | #227c | 1 | 5 | 15 | dec d |
#8c7d | #227d | 2 | 13/8 | 20 0a | jr nz, L8c89 |
#8c7f | #227f | | | | ; d == 7: ... |
#8c7f | #227f | 4 | 21 | dd 36 01 00 | ld (ix + 1), 0 |
#8c83 | #2283 | | | | L8c83: |
#8c83 | #2283 | 4 | 21 | dd 36 02 3f | ld (ix + 2), 63 |
#8c87 | #2287 | 2 | 13 | 18 08 | jr L8c91 |
#8c89 | #2289 | | | | L8c89: |
#8c89 | #2289 | | | | ; d == 8: ... |
#8c89 | #2289 | 4 | 21 | dd 36 01 00 | ld (ix + 1), 0 |
#8c8d | #228d | | | | L8c8d: |
#8c8d | #228d | 4 | 21 | dd 36 03 00 | ld (ix + 3), 0 |
#8c91 | #2291 | | | | L8c91: |
#8c91 | #2291 | 4 | 21 | dd 36 04 7f | ld (ix + 4), 127 |
#8c95 | #2295 | | | | L8c95: |
#8c95 | #2295 | 1 | 5 | 25 | dec h |
#8c96 | #2296 | 3 | 11 | c2 cc 8b | jp nz, L8bcc_angle_loop |
#8c99 | #2299 | | | | |
#8c99 | #2299 | | | | ; Replace any of the coordinates we have not set above, |
#8c99 | #2299 | | | | ; with the player x, y, or z coordinates: |
#8c99 | #2299 | | | | ; These correspond to areas that are "behind" the player, and |
#8c99 | #2299 | | | | ; hence we use the player coordinates to prune. |
#8c99 | #2299 | 3 | 17 | 2a ad 6a | ld hl, (L6aad_player_current_x) |
#8c9c | #229c | 1 | 12 | 29 | add hl, hl |
#8c9d | #229d | 1 | 12 | 29 | add hl, hl |
#8c9e | #229e | 2 | 8 | 3e ff | ld a, 255 |
#8ca0 | #22a0 | 3 | 21 | dd be 00 | cp (ix) |
#8ca3 | #22a3 | 2 | 13/8 | 20 06 | jr nz, L8cab |
#8ca5 | #22a5 | 1 | 5 | 24 | inc h |
#8ca6 | #22a6 | 3 | 21 | dd 74 00 | ld (ix), h |
#8ca9 | #22a9 | 2 | 13 | 18 08 | jr L8cb3 |
#8cab | #22ab | | | | L8cab: |
#8cab | #22ab | 3 | 21 | dd be 01 | cp (ix + 1) |
#8cae | #22ae | 2 | 13/8 | 20 03 | jr nz, L8cb3 |
#8cb0 | #22b0 | 3 | 21 | dd 74 01 | ld (ix + 1), h |
#8cb3 | #22b3 | | | | L8cb3: |
#8cb3 | #22b3 | 3 | 17 | 2a af 6a | ld hl, (L6aaf_player_current_y) |
#8cb6 | #22b6 | 1 | 12 | 29 | add hl, hl |
#8cb7 | #22b7 | 1 | 12 | 29 | add hl, hl |
#8cb8 | #22b8 | 3 | 21 | dd be 02 | cp (ix + 2) |
#8cbb | #22bb | 2 | 13/8 | 20 06 | jr nz, L8cc3 |
#8cbd | #22bd | 1 | 5 | 24 | inc h |
#8cbe | #22be | 3 | 21 | dd 74 02 | ld (ix + 2), h |
#8cc1 | #22c1 | 2 | 13 | 18 08 | jr L8ccb |
#8cc3 | #22c3 | | | | L8cc3: |
#8cc3 | #22c3 | 3 | 21 | dd be 03 | cp (ix + 3) |
#8cc6 | #22c6 | 2 | 13/8 | 20 03 | jr nz, L8ccb |
#8cc8 | #22c8 | 3 | 21 | dd 74 03 | ld (ix + 3), h |
#8ccb | #22cb | | | | L8ccb: |
#8ccb | #22cb | 3 | 17 | 2a b1 6a | ld hl, (L6ab1_player_current_z) |
#8cce | #22ce | 1 | 12 | 29 | add hl, hl |
#8ccf | #22cf | 1 | 12 | 29 | add hl, hl |
#8cd0 | #22d0 | 3 | 21 | dd be 04 | cp (ix + 4) |
#8cd3 | #22d3 | 2 | 13/8 | 20 06 | jr nz, L8cdb |
#8cd5 | #22d5 | 1 | 5 | 24 | inc h |
#8cd6 | #22d6 | 3 | 21 | dd 74 04 | ld (ix + 4), h |
#8cd9 | #22d9 | 2 | 13 | 18 08 | jr L8ce3 |
#8cdb | #22db | | | | L8cdb: |
#8cdb | #22db | 3 | 21 | dd be 05 | cp (ix + 5) |
#8cde | #22de | 2 | 13/8 | 20 03 | jr nz, L8ce3 |
#8ce0 | #22e0 | 3 | 21 | dd 74 05 | ld (ix + 5), h |
#8ce3 | #22e3 | | | | L8ce3: |
#8ce3 | #22e3 | 1 | 11 | c9 | ret |
#8ce4 | #22e4 | | | | |
#8ce4 | #22e4 | | | | |
#8ce4 | #22e4 | | | | ; -------------------------------- |
#8ce4 | #22e4 | | | | ; Auxiliary variables for L8cf0_project_object_and_add_to_render_list_clipping_internal |
#8ce4 | #22e4 | | | | L8ce4_projected_data_current_ptr_tmp: ; Temporary storage of the current vertex data ptr. |
#8ce4 | #22e4 | 2 | | | dw #0000 |
#8ce6 | #22e6 | | | | L8ce6_current_face_texture_ID: |
#8ce6 | #22e6 | 1 | | | db #00 |
#8ce7 | #22e7 | | | | L8ce7_current_face_normal_check_result: ; Caches the result of the normal check for the current face |
#8ce7 | #22e7 | 1 | | | db #00 |
#8ce8 | #22e8 | | | | L8ce8_screen_corner_coordinates: ; Used to insert new vertices when clipping. |
#8ce8 | #22e8 | 2 | | | db SCREEN_WIDTH_IN_PIXELS, SCREEN_HEIGHT_IN_PIXELS |
#8cea | #22ea | 2 | | | db #00, SCREEN_HEIGHT_IN_PIXELS |
#8cec | #22ec | 2 | | | db #00, #00 |
#8cee | #22ee | 2 | | | db SCREEN_WIDTH_IN_PIXELS, #00 |
#8cf0 | #22f0 | | | | |
#8cf0 | #22f0 | | | | |
#8cf0 | #22f0 | | | | ; -------------------------------- |
#8cf0 | #22f0 | | | | ; Projects an object, and if it falls within the screen, add it to the list of objects to draw, |
#8cf0 | #22f0 | | | | ; assuming that we will have to clip some of the edges as some vertices are outside the viewing area. |
#8cf0 | #22f0 | | | | ; Input: |
#8cf0 | #22f0 | | | | ; - iy: face definition ptr: |
#8cf0 | #22f0 | | | | ; - first byte is number of faces |
#8cf0 | #22f0 | | | | ; - then, each face has: |
#8cf0 | #22f0 | | | | ; - attribute |
#8cf0 | #22f0 | | | | ; - number of vertices |
#8cf0 | #22f0 | | | | ; - then one byte per vertex (index) |
#8cf0 | #22f0 | | | | L8cf0_project_object_and_add_to_render_list_clipping_internal: |
#8cf0 | #22f0 | 3 | 17 | 2a 24 5f | ld hl, (L5f24_shape_edges_ptr) |
#8cf3 | #22f3 | 1 | 8 | 46 | ld b, (hl) ; number of edges |
#8cf4 | #22f4 | | | | ; Initialize the L5ee8_already_projected_vertex_coordinates array: |
#8cf4 | #22f4 | | | | ; (5 bytes per edge): |
#8cf4 | #22f4 | | | | ; - 0 if not processed, 1 if processed |
#8cf4 | #22f4 | | | | ; - projected x (vertex 1) |
#8cf4 | #22f4 | | | | ; - projected y (vertex 1) |
#8cf4 | #22f4 | | | | ; - projected x (vertex 2) |
#8cf4 | #22f4 | | | | ; - projected y (vertex 2) |
#8cf4 | #22f4 | 3 | 11 | 21 e8 5e | ld hl, L5ee8_already_projected_vertex_coordinates |
#8cf7 | #22f7 | 2 | 8 | 3e ff | ld a, #ff |
#8cf9 | #22f9 | 2 | 8 | 0e 00 | ld c, 0 |
#8cfb | #22fb | | | | L8cfb: |
#8cfb | #22fb | 1 | 8 | 71 | ld (hl), c |
#8cfc | #22fc | 1 | 7 | 23 | inc hl |
#8cfd | #22fd | 1 | 8 | 77 | ld (hl), a |
#8cfe | #22fe | 1 | 7 | 23 | inc hl |
#8cff | #22ff | 1 | 7 | 23 | inc hl |
#8d00 | #2300 | 1 | 8 | 77 | ld (hl), a |
#8d01 | #2301 | 1 | 7 | 23 | inc hl |
#8d02 | #2302 | 1 | 7 | 23 | inc hl |
#8d03 | #2303 | 2 | 14/9 | 10 f6 | djnz L8cfb |
#8d05 | #2305 | | | | |
#8d05 | #2305 | 1 | 5 | af | xor a |
#8d06 | #2306 | 3 | 14 | 32 5f 5e | ld (L5e5f_add_to_projected_objects_flag), a |
#8d09 | #2309 | 3 | 17 | 2a 97 74 | ld hl, (L7497_next_projected_vertex_ptr) |
#8d0c | #230c | 3 | 14 | 3a 68 74 | ld a, (L7468_focus_object_id) |
#8d0f | #230f | | | | ; Start writing the projected vertex data: |
#8d0f | #230f | 1 | 8 | 77 | ld (hl), a ; object ID |
#8d10 | #2310 | 1 | 7 | 23 | inc hl |
#8d11 | #2311 | 2 | 11 | 36 00 | ld (hl), 0 ; number of primitives (init to zero, and will be incremented each time a face is added). |
#8d13 | #2313 | 1 | 7 | 23 | inc hl |
#8d14 | #2314 | 3 | 21 | fd 46 00 | ld b, (iy) ; number of faces |
#8d17 | #2317 | 2 | 12 | fd 23 | inc iy |
#8d19 | #2319 | | | | L8d19_face_loop: |
#8d19 | #2319 | 1 | 12 | c5 | push bc |
#8d1a | #231a | 3 | 21 | fd 7e 00 | ld a, (iy) ; a = texture ID. |
#8d1d | #231d | 2 | 12 | fd 23 | inc iy |
#8d1f | #231f | 3 | 21 | fd 46 00 | ld b, (iy) ; b = number of vertexes/edges in the face. |
#8d22 | #2322 | 2 | 12 | fd 23 | inc iy |
#8d24 | #2324 | | | | ; If it's a transparent face, ignore: |
#8d24 | #2324 | 1 | 5 | b7 | or a |
#8d25 | #2325 | 2 | 13/8 | 28 69 | jr z, L8d90_skip_face_bytes_and_next_face |
#8d27 | #2327 | 2 | 10 | cb 27 | sla a |
#8d29 | #2329 | 2 | 10 | cb 27 | sla a |
#8d2b | #232b | 2 | 10 | cb 27 | sla a |
#8d2d | #232d | 2 | 10 | cb 27 | sla a |
#8d2f | #232f | 1 | 5 | 4f | ld c, a ; c = texture ID (in the most significant nibble). |
#8d30 | #2330 | | | | ; This first loop goes over the edges looking to see if any vertex passed all the |
#8d30 | #2330 | | | | ; frustum checks: |
#8d30 | #2330 | 2 | 17 | fd e5 | push iy |
#8d32 | #2332 | 1 | 12 | e5 | push hl |
#8d33 | #2333 | 1 | 12 | c5 | push bc |
#8d34 | #2334 | 2 | 8 | 3e 01 | ld a, 1 |
#8d36 | #2336 | 3 | 14 | 32 28 5f | ld (L5f28_cull_face_when_no_projected_vertices), a |
#8d39 | #2339 | 2 | 8 | 0e 1e | ld c, #1e ; "c" will accumulate the frustum checks of all the vertexes |
#8d3b | #233b | 1 | 5 | 04 | inc b |
#8d3c | #233c | 2 | 10 | cb 38 | srl b ; b = (number of vertexes + 1) * 2 |
#8d3e | #233e | 2 | 8 | 16 00 | ld d, 0 |
#8d40 | #2340 | | | | L8d40_edge_loop: |
#8d40 | #2340 | 3 | 21 | fd 7e 00 | ld a, (iy) ; vertex/edge index |
#8d43 | #2343 | 2 | 8 | e6 7f | and #7f ; get the index (remove a potential flag in the msb) |
#8d45 | #2345 | 2 | 10 | cb 27 | sla a |
#8d47 | #2347 | 1 | 5 | 5f | ld e, a |
#8d48 | #2348 | 4 | 22 | dd 2a 24 5f | ld ix, (L5f24_shape_edges_ptr) |
#8d4c | #234c | 2 | 12 | dd 23 | inc ix ; skip the number of vertexes |
#8d4e | #234e | 2 | 17 | dd 19 | add ix, de ; ix = ptr to the edge |
#8d50 | #2350 | 3 | 21 | dd 5e 00 | ld e, (ix) ; vertex index 1 |
#8d53 | #2353 | 3 | 11 | 21 dc 5e | ld hl, L5edc_vertex_rendering_frustum_checks |
#8d56 | #2356 | 1 | 12 | 19 | add hl, de |
#8d57 | #2357 | 1 | 8 | 7e | ld a, (hl) |
#8d58 | #2358 | 2 | 8 | fe 1f | cp #1f |
#8d5a | #235a | 2 | 13/8 | 28 1a | jr z, L8d76 |
#8d5c | #235c | | | | ; vertex outside of view frustum: |
#8d5c | #235c | 1 | 5 | a1 | and c |
#8d5d | #235d | 1 | 5 | 4f | ld c, a |
#8d5e | #235e | 3 | 21 | dd 5e 01 | ld e, (ix + 1) ; vertex index 2 |
#8d61 | #2361 | 3 | 11 | 21 dc 5e | ld hl, L5edc_vertex_rendering_frustum_checks |
#8d64 | #2364 | 1 | 12 | 19 | add hl, de |
#8d65 | #2365 | 1 | 8 | 7e | ld a, (hl) |
#8d66 | #2366 | 2 | 8 | fe 1f | cp #1f |
#8d68 | #2368 | 2 | 13/8 | 28 0c | jr z, L8d76 |
#8d6a | #236a | | | | ; vertex outside of view frustum: |
#8d6a | #236a | 1 | 5 | a1 | and c |
#8d6b | #236b | 1 | 5 | 4f | ld c, a |
#8d6c | #236c | 2 | 12 | fd 23 | inc iy |
#8d6e | #236e | 2 | 12 | fd 23 | inc iy |
#8d70 | #2370 | 2 | 14/9 | 10 ce | djnz L8d40_edge_loop |
#8d72 | #2372 | | | | |
#8d72 | #2372 | 1 | 5 | 4f | ld c, a ; OPTIMIZATION: useless instruction "ld c, a" was just executed above. |
#8d73 | #2373 | 1 | 5 | b7 | or a |
#8d74 | #2374 | 2 | 13/8 | 28 04 | jr z, L8d7a |
#8d76 | #2376 | | | | L8d76: |
#8d76 | #2376 | | | | ; We get here if one vertex has passed all frustum tests, |
#8d76 | #2376 | | | | ; or if the frustum test accumulator (c) is non zero. |
#8d76 | #2376 | 1 | 5 | af | xor a |
#8d77 | #2377 | 3 | 14 | 32 28 5f | ld (L5f28_cull_face_when_no_projected_vertices), a |
#8d7a | #237a | | | | L8d7a: |
#8d7a | #237a | 1 | 11 | c1 | pop bc ; restore c: texture ID, b: number of edges of face |
#8d7b | #237b | 1 | 11 | e1 | pop hl ; restore hl: ptr to projected vertex data |
#8d7c | #237c | 2 | 16 | fd e1 | pop iy ; restore iy: face edge data ptr. |
#8d7e | #237e | | | | |
#8d7e | #237e | 3 | 14 | 3a 60 5e | ld a, (L5e60_projection_pre_work_type) |
#8d81 | #2381 | | | | ; - if a == 0: indicates that vertices can be projected directly. |
#8d81 | #2381 | | | | ; - if a == 1: we need to call L88d1_normal_direction_check before projection, and if back-face, we cull |
#8d81 | #2381 | | | | ; - if a == 2: we need to call L88d1_normal_direction_check before projection, and if back-face we need to use L5f26_alternative_shape_edges_ptr |
#8d81 | #2381 | 1 | 5 | b7 | or a |
#8d82 | #2382 | 2 | 13/8 | 28 43 | jr z, L8dc7_ready_to_project |
#8d84 | #2384 | 2 | 8 | fe 01 | cp 1 |
#8d86 | #2386 | 2 | 13/8 | 20 10 | jr nz, L8d98 |
#8d88 | #2388 | | | | |
#8d88 | #2388 | | | | ; Normal check, and cull if failed: |
#8d88 | #2388 | 3 | 18 | cd d1 88 | call L88d1_normal_direction_check |
#8d8b | #238b | 3 | 14 | 32 e7 8c | ld (L8ce7_current_face_normal_check_result), a |
#8d8e | #238e | 2 | 13/8 | 30 37 | jr nc, L8dc7_ready_to_project |
#8d90 | #2390 | | | | L8d90_skip_face_bytes_and_next_face: |
#8d90 | #2390 | 1 | 5 | 48 | ld c, b |
#8d91 | #2391 | 2 | 8 | 06 00 | ld b, 0 |
#8d93 | #2393 | 2 | 17 | fd 09 | add iy, bc |
#8d95 | #2395 | 3 | 11 | c3 9f 8f | jp L8f9f_next_face |
#8d98 | #2398 | | | | |
#8d98 | #2398 | | | | L8d98: |
#8d98 | #2398 | | | | ; Normal check, and use back texture if failed: |
#8d98 | #2398 | 3 | 18 | cd d1 88 | call L88d1_normal_direction_check |
#8d9b | #239b | 3 | 14 | 32 e7 8c | ld (L8ce7_current_face_normal_check_result), a |
#8d9e | #239e | 3 | 14 | 3a 6a 74 | ld a, (L746a_current_drawing_texture_id) |
#8da1 | #23a1 | 2 | 13/8 | 30 17 | jr nc, L8dba_front_face |
#8da3 | #23a3 | | | | ; back face, we need to swap texture ID, and use alternative shape edges ptr: |
#8da3 | #23a3 | 2 | 8 | e6 f0 | and #f0 |
#8da5 | #23a5 | 2 | 13/8 | 28 e9 | jr z, L8d90_skip_face_bytes_and_next_face |
#8da7 | #23a7 | 1 | 5 | 4f | ld c, a |
#8da8 | #23a8 | 4 | 22 | ed 5b 26 5f | ld de, (L5f26_alternative_shape_edges_ptr) |
#8dac | #23ac | 4 | 22 | ed 53 24 5f | ld (L5f24_shape_edges_ptr), de |
#8db0 | #23b0 | | | | ; OPTIMIZATION: at this point (L8ce7_current_face_normal_check_result) always contains a 1, so no need to read it and xor, just set to 0. |
#8db0 | #23b0 | 3 | 14 | 3a e7 8c | ld a, (L8ce7_current_face_normal_check_result) |
#8db3 | #23b3 | 2 | 8 | ee 01 | xor 1 |
#8db5 | #23b5 | 3 | 14 | 32 e7 8c | ld (L8ce7_current_face_normal_check_result), a |
#8db8 | #23b8 | 2 | 13 | 18 0d | jr L8dc7_ready_to_project |
#8dba | #23ba | | | | |
#8dba | #23ba | | | | L8dba_front_face: |
#8dba | #23ba | | | | ; Get the texture ID into the most significant nibble of c |
#8dba | #23ba | 2 | 8 | e6 0f | and #0f |
#8dbc | #23bc | 2 | 13/8 | 28 d2 | jr z, L8d90_skip_face_bytes_and_next_face |
#8dbe | #23be | 2 | 10 | cb 27 | sla a |
#8dc0 | #23c0 | 2 | 10 | cb 27 | sla a |
#8dc2 | #23c2 | 2 | 10 | cb 27 | sla a |
#8dc4 | #23c4 | 2 | 10 | cb 27 | sla a |
#8dc6 | #23c6 | 1 | 5 | 4f | ld c, a |
#8dc7 | #23c7 | | | | |
#8dc7 | #23c7 | | | | L8dc7_ready_to_project: |
#8dc7 | #23c7 | | | | ; At this point: |
#8dc7 | #23c7 | | | | ; c = texture ID (most significant nibble) |
#8dc7 | #23c7 | | | | ; b = number of edges in the face |
#8dc7 | #23c7 | | | | ; hl = ptr to projected vertex data |
#8dc7 | #23c7 | | | | ; iy = face edge data ptr. |
#8dc7 | #23c7 | 1 | 5 | 79 | ld a, c |
#8dc8 | #23c8 | 3 | 14 | 32 e6 8c | ld (L8ce6_current_face_texture_ID), a |
#8dcb | #23cb | 1 | 5 | 78 | ld a, b |
#8dcc | #23cc | 2 | 8 | fe 02 | cp 2 |
#8dce | #23ce | 2 | 13/8 | 20 01 | jr nz, L8dd1 |
#8dd0 | #23d0 | 1 | 5 | 05 | dec b ; If the number of edges is 2, make it 1 (a line). |
#8dd1 | #23d1 | | | | L8dd1: |
#8dd1 | #23d1 | | | | ; This second edge loop: projects all the vertices, clipping them if necessary. |
#8dd1 | #23d1 | 2 | 17 | fd e5 | push iy |
#8dd3 | #23d3 | 1 | 12 | e5 | push hl |
#8dd4 | #23d4 | 1 | 12 | c5 | push bc |
#8dd5 | #23d5 | 2 | 8 | 16 00 | ld d, 0 |
#8dd7 | #23d7 | | | | L8dd7_edge_loop_2: |
#8dd7 | #23d7 | 1 | 12 | c5 | push bc |
#8dd8 | #23d8 | 3 | 21 | fd 7e 00 | ld a, (iy) ; edge index |
#8ddb | #23db | 2 | 12 | fd 23 | inc iy |
#8ddd | #23dd | 2 | 17 | fd e5 | push iy |
#8ddf | #23df | 2 | 8 | e6 7f | and #7f ; get rid of the edge flip flag. |
#8de1 | #23e1 | 1 | 5 | 5f | ld e, a |
#8de2 | #23e2 | 2 | 10 | cb 27 | sla a |
#8de4 | #23e4 | 1 | 5 | 4f | ld c, a ; c = edge index * 2 |
#8de5 | #23e5 | 2 | 10 | cb 27 | sla a |
#8de7 | #23e7 | 1 | 5 | 83 | add a, e |
#8de8 | #23e8 | 1 | 5 | 5f | ld e, a ; e = edge index * 5 |
#8de9 | #23e9 | | | | ; Check if this edge had already been processed: |
#8de9 | #23e9 | 4 | 16 | dd 21 e8 5e | ld ix, L5ee8_already_projected_vertex_coordinates |
#8ded | #23ed | 2 | 17 | dd 19 | add ix, de |
#8def | #23ef | 1 | 5 | af | xor a |
#8df0 | #23f0 | 3 | 21 | dd be 00 | cp (ix) |
#8df3 | #23f3 | 2 | 13/8 | 20 67 | jr nz, L8e5c_next_edge |
#8df5 | #23f5 | 2 | 12 | dd 23 | inc ix |
#8df7 | #23f7 | 3 | 17 | 2a 24 5f | ld hl, (L5f24_shape_edges_ptr) |
#8dfa | #23fa | 1 | 7 | 23 | inc hl |
#8dfb | #23fb | 1 | 5 | 59 | ld e, c |
#8dfc | #23fc | 1 | 12 | 19 | add hl, de ; ptr to the edge |
#8dfd | #23fd | 1 | 8 | 5e | ld e, (hl) ; first vertex of the edge |
#8dfe | #23fe | 4 | 16 | fd 21 dc 5e | ld iy, L5edc_vertex_rendering_frustum_checks |
#8e02 | #2402 | 2 | 17 | fd 19 | add iy, de |
#8e04 | #2404 | 3 | 21 | fd 7e 00 | ld a, (iy) ; frustum checks for first vertex of the edge |
#8e07 | #2407 | 1 | 5 | 4f | ld c, a |
#8e08 | #2408 | 2 | 8 | fe 1f | cp #1f |
#8e0a | #240a | 2 | 13/8 | 20 0a | jr nz, L8e16_second_vertex |
#8e0c | #240c | | | | ; Vertex passed all frustum checks: |
#8e0c | #240c | 3 | 21 | dd 7e 00 | ld a, (ix) ; Check if we have already projected it |
#8e0f | #240f | 2 | 8 | fe ff | cp #ff |
#8e11 | #2411 | 2 | 13/8 | 20 03 | jr nz, L8e16_second_vertex |
#8e13 | #2413 | | | | ; We need to project it: |
#8e13 | #2413 | 3 | 18 | cd a5 8f | call L8fa5_project_one_vertex_for_clipping_projection |
#8e16 | #2416 | | | | L8e16_second_vertex: |
#8e16 | #2416 | 1 | 7 | 23 | inc hl |
#8e17 | #2417 | 1 | 8 | 5e | ld e, (hl) ; second vertex of the edge |
#8e18 | #2418 | 1 | 7 | 2b | dec hl |
#8e19 | #2419 | 4 | 16 | fd 21 dc 5e | ld iy, L5edc_vertex_rendering_frustum_checks |
#8e1d | #241d | 2 | 17 | fd 19 | add iy, de |
#8e1f | #241f | 3 | 21 | fd 7e 00 | ld a, (iy) ; frustum checks for second vertex of the edge |
#8e22 | #2422 | 1 | 5 | 47 | ld b, a |
#8e23 | #2423 | 2 | 8 | fe 1f | cp #1f |
#8e25 | #2425 | 2 | 13/8 | 20 0a | jr nz, L8e31 |
#8e27 | #2427 | 3 | 21 | dd 7e 02 | ld a, (ix + 2) ; second vertex x |
#8e2a | #242a | 2 | 8 | fe ff | cp #ff |
#8e2c | #242c | 2 | 13/8 | 20 03 | jr nz, L8e31 |
#8e2e | #242e | 3 | 18 | cd a5 8f | call L8fa5_project_one_vertex_for_clipping_projection |
#8e31 | #2431 | | | | L8e31: |
#8e31 | #2431 | | | | ; Here c and b contain the frustum checks of the two vertices: |
#8e31 | #2431 | 1 | 5 | 78 | ld a, b |
#8e32 | #2432 | 1 | 5 | a1 | and c |
#8e33 | #2433 | 2 | 8 | fe 1f | cp #1f |
#8e35 | #2435 | 2 | 13/8 | 20 05 | jr nz, L8e3c_at_least_one_vertex_outside |
#8e37 | #2437 | | | | L8e37: |
#8e37 | #2437 | | | | ; If both vertices were within the viewable area, or both outside |
#8e37 | #2437 | | | | ; mark this edge as processed: |
#8e37 | #2437 | 3 | 25 | dd 34 ffff | inc (ix - 1) ; mark the eedge as processed |
#8e3a | #243a | 2 | 13 | 18 20 | jr L8e5c_next_edge |
#8e3c | #243c | | | | L8e3c_at_least_one_vertex_outside: |
#8e3c | #243c | | | | ; At least one vertex was outside the view frustum, we need to clip: |
#8e3c | #243c | 1 | 5 | 78 | ld a, b |
#8e3d | #243d | 1 | 5 | b1 | or c |
#8e3e | #243e | 2 | 8 | fe 1f | cp #1f |
#8e40 | #2440 | 2 | 13/8 | 20 f5 | jr nz, L8e37 ; both vertexes were outside, mark as processed too. |
#8e42 | #2442 | | | | ; One vertex was in, the other was out: |
#8e42 | #2442 | 2 | 10 | cb 23 | sla e |
#8e44 | #2444 | 4 | 16 | fd 21 9f 5e | ld iy, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8e48 | #2448 | 2 | 17 | fd 19 | add iy, de |
#8e4a | #244a | 2 | 17 | fd 19 | add iy, de |
#8e4c | #244c | 2 | 17 | fd 19 | add iy, de ; iy = ptr to 3d vertex 2 |
#8e4e | #244e | 1 | 8 | 5e | ld e, (hl) ; get the vertex 1 index again |
#8e4f | #244f | 2 | 10 | cb 23 | sla e |
#8e51 | #2451 | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8e54 | #2454 | 1 | 12 | 19 | add hl, de |
#8e55 | #2455 | 1 | 12 | 19 | add hl, de |
#8e56 | #2456 | 1 | 12 | 19 | add hl, de ; hl = ptr to 3d vertex 1 |
#8e57 | #2457 | 3 | 18 | cd ae 85 | call L85ae_clip_edge |
#8e5a | #245a | 2 | 8 | 16 00 | ld d, 0 |
#8e5c | #245c | | | | L8e5c_next_edge: |
#8e5c | #245c | 2 | 16 | fd e1 | pop iy |
#8e5e | #245e | 1 | 11 | c1 | pop bc |
#8e5f | #245f | 1 | 5 | 05 | dec b |
#8e60 | #2460 | 3 | 11 | c2 d7 8d | jp nz, L8dd7_edge_loop_2 |
#8e63 | #2463 | 1 | 11 | c1 | pop bc |
#8e64 | #2464 | 1 | 11 | e1 | pop hl |
#8e65 | #2465 | 2 | 16 | fd e1 | pop iy |
#8e67 | #2467 | | | | |
#8e67 | #2467 | | | | ; At this point: |
#8e67 | #2467 | | | | ; b = number of edges in the face |
#8e67 | #2467 | | | | ; hl = ptr to projected vertex data we are writing to |
#8e67 | #2467 | | | | ; iy = face edge data ptr. |
#8e67 | #2467 | | | | |
#8e67 | #2467 | | | | ; This third loop adds projected vertices to the projected data, inserting connecting points if necessary. |
#8e67 | #2467 | 1 | 5 | 4a | ld c, d ; c = 0 (number of vertices added) |
#8e68 | #2468 | 3 | 17 | 22 e4 8c | ld (L8ce4_projected_data_current_ptr_tmp), hl ; Save the current pointer to the projected vertex data we are writing to |
#8e6b | #246b | 1 | 7 | 23 | inc hl |
#8e6c | #246c | 1 | 12 | c5 | push bc |
#8e6d | #246d | | | | L8e6d_edge_loop_3: |
#8e6d | #246d | 3 | 21 | fd 7e 00 | ld a, (iy) ; edge index |
#8e70 | #2470 | 2 | 8 | e6 7f | and #7f ; get rid of the edge flip flag. |
#8e72 | #2472 | 1 | 5 | 5f | ld e, a |
#8e73 | #2473 | 2 | 10 | cb 27 | sla a |
#8e75 | #2475 | 2 | 10 | cb 27 | sla a |
#8e77 | #2477 | 1 | 5 | 83 | add a, e ; e = edge index * 5 |
#8e78 | #2478 | 1 | 5 | 5f | ld e, a |
#8e79 | #2479 | 2 | 8 | 16 00 | ld d, 0 |
#8e7b | #247b | 4 | 16 | dd 21 e8 5e | ld ix, L5ee8_already_projected_vertex_coordinates |
#8e7f | #247f | 2 | 17 | dd 19 | add ix, de |
#8e81 | #2481 | | | | ; If this edge was not projected, it means it was fully outside of the |
#8e81 | #2481 | | | | ; view area, just ignore: |
#8e81 | #2481 | 3 | 21 | dd 7e 01 | ld a, (ix + 1) |
#8e84 | #2484 | 2 | 8 | fe ff | cp #ff |
#8e86 | #2486 | 2 | 13/8 | 28 6d | jr z, L8ef5_next_edge |
#8e88 | #2488 | 4 | 22 | fd cb 00 7e | bit 7, (iy) ; Check edge flip flag |
#8e8c | #248c | 2 | 13/8 | 28 19 | jr z, L8ea7_vertices_in_the_correct_order |
#8e8e | #248e | | | | ; Flip the projected vertex info: |
#8e8e | #248e | 3 | 21 | dd 5e 01 | ld e, (ix + 1) |
#8e91 | #2491 | 3 | 21 | dd 56 03 | ld d, (ix + 3) |
#8e94 | #2494 | 1 | 5 | 7a | ld a, d ; overwrite a with the x projection of the new first vertex. |
#8e95 | #2495 | 3 | 21 | dd 72 01 | ld (ix + 1), d |
#8e98 | #2498 | 3 | 21 | dd 73 03 | ld (ix + 3), e |
#8e9b | #249b | 3 | 21 | dd 5e 02 | ld e, (ix + 2) |
#8e9e | #249e | 3 | 21 | dd 56 04 | ld d, (ix + 4) |
#8ea1 | #24a1 | 3 | 21 | dd 72 02 | ld (ix + 2), d |
#8ea4 | #24a4 | 3 | 21 | dd 73 04 | ld (ix + 4), e |
#8ea7 | #24a7 | | | | L8ea7_vertices_in_the_correct_order: |
#8ea7 | #24a7 | 1 | 5 | 5f | ld e, a ; vertex 1 x |
#8ea8 | #24a8 | 3 | 21 | dd 56 02 | ld d, (ix + 2) ; vertex 1 y |
#8eab | #24ab | 1 | 5 | 79 | ld a, c |
#8eac | #24ac | 1 | 5 | b7 | or a |
#8ead | #24ad | 2 | 13/8 | 28 0f | jr z, L8ebe ; If it's the first vertex we project, skip |
#8eaf | #24af | | | | ; Check if the coordinates of vertex 1 are the same as the last projected vertex. |
#8eaf | #24af | | | | ; These should match if there was no clipping, but when there is clipping, we might |
#8eaf | #24af | | | | ; need to insert additional edges to connect clipped points: |
#8eaf | #24af | 1 | 5 | 7b | ld a, e |
#8eb0 | #24b0 | 1 | 7 | 2b | dec hl |
#8eb1 | #24b1 | 1 | 7 | 2b | dec hl |
#8eb2 | #24b2 | 1 | 8 | be | cp (hl) ; compare x coordiantes |
#8eb3 | #24b3 | 1 | 7 | 23 | inc hl |
#8eb4 | #24b4 | 2 | 13/8 | 20 02 | jr nz, L8eb8 ; no x match |
#8eb6 | #24b6 | 1 | 5 | 7a | ld a, d |
#8eb7 | #24b7 | 1 | 8 | be | cp (hl) ; compare y coordinates |
#8eb8 | #24b8 | | | | L8eb8: |
#8eb8 | #24b8 | 1 | 7 | 23 | inc hl |
#8eb9 | #24b9 | 2 | 13/8 | 28 08 | jr z, L8ec3_skip_vertex1_insertion |
#8ebb | #24bb | 3 | 18 | cd ea 8f | call L8fea_add_connecting_projected_vertices |
#8ebe | #24be | | | | L8ebe: |
#8ebe | #24be | | | | ; Add vertex to projection and increment vertex count ("c"): |
#8ebe | #24be | 1 | 8 | 73 | ld (hl), e |
#8ebf | #24bf | 1 | 7 | 23 | inc hl |
#8ec0 | #24c0 | 1 | 8 | 72 | ld (hl), d |
#8ec1 | #24c1 | 1 | 7 | 23 | inc hl |
#8ec2 | #24c2 | 1 | 5 | 0c | inc c |
#8ec3 | #24c3 | | | | L8ec3_skip_vertex1_insertion: |
#8ec3 | #24c3 | 3 | 21 | dd 7e 04 | ld a, (ix + 4) ; vertex 2 y |
#8ec6 | #24c6 | 1 | 5 | ba | cp d |
#8ec7 | #24c7 | 3 | 21 | dd 7e 03 | ld a, (ix + 3) ; vertex 2 x |
#8eca | #24ca | 2 | 13/8 | 20 03 | jr nz, L8ecf |
#8ecc | #24cc | 1 | 5 | bb | cp e |
#8ecd | #24cd | 2 | 13/8 | 28 08 | jr z, L8ed7 |
#8ecf | #24cf | | | | L8ecf: |
#8ecf | #24cf | | | | ; Vertex 2 is different from vertex 1: |
#8ecf | #24cf | 1 | 8 | 77 | ld (hl), a ; x coordinate |
#8ed0 | #24d0 | 1 | 7 | 23 | inc hl |
#8ed1 | #24d1 | 3 | 21 | dd 7e 04 | ld a, (ix + 4) ; y coordinate |
#8ed4 | #24d4 | 1 | 8 | 77 | ld (hl), a |
#8ed5 | #24d5 | 1 | 7 | 23 | inc hl |
#8ed6 | #24d6 | 1 | 5 | 0c | inc c ; incremenr number of projected vertices |
#8ed7 | #24d7 | | | | L8ed7: |
#8ed7 | #24d7 | | | | ; If we had flipped the vertices, put them back in their original order: |
#8ed7 | #24d7 | 4 | 22 | fd cb 00 7e | bit 7, (iy) |
#8edb | #24db | 2 | 13/8 | 28 18 | jr z, L8ef5_next_edge |
#8edd | #24dd | 3 | 21 | dd 5e 01 | ld e, (ix + 1) |
#8ee0 | #24e0 | 3 | 21 | dd 56 03 | ld d, (ix + 3) |
#8ee3 | #24e3 | 3 | 21 | dd 72 01 | ld (ix + 1), d |
#8ee6 | #24e6 | 3 | 21 | dd 73 03 | ld (ix + 3), e |
#8ee9 | #24e9 | 3 | 21 | dd 5e 02 | ld e, (ix + 2) |
#8eec | #24ec | 3 | 21 | dd 56 04 | ld d, (ix + 4) |
#8eef | #24ef | 3 | 21 | dd 72 02 | ld (ix + 2), d |
#8ef2 | #24f2 | 3 | 21 | dd 73 04 | ld (ix + 4), e |
#8ef5 | #24f5 | | | | L8ef5_next_edge: |
#8ef5 | #24f5 | 2 | 12 | fd 23 | inc iy |
#8ef7 | #24f7 | 1 | 5 | 05 | dec b |
#8ef8 | #24f8 | 3 | 11 | c2 6d 8e | jp nz, L8e6d_edge_loop_3 |
#8efb | #24fb | | | | |
#8efb | #24fb | 1 | 5 | 79 | ld a, c |
#8efc | #24fc | 1 | 11 | c1 | pop bc ; restore the number of edges in b |
#8efd | #24fd | 4 | 22 | dd 2a e4 8c | ld ix, (L8ce4_projected_data_current_ptr_tmp) |
#8f01 | #2501 | 1 | 5 | 4f | ld c, a ; number of projected vertices |
#8f02 | #2502 | 2 | 8 | fe 02 | cp 2 |
#8f04 | #2504 | 2 | 13/8 | 30 63 | jr nc, L8f69_2_or_more_vertices_projected |
#8f06 | #2506 | 2 | 8 | fe 01 | cp 1 |
#8f08 | #2508 | 2 | 13/8 | 20 02 | jr nz, L8f0c_0_vertices_projected |
#8f0a | #250a | 1 | 7 | 2b | dec hl |
#8f0b | #250b | 1 | 7 | 2b | dec hl |
#8f0c | #250c | | | | |
#8f0c | #250c | | | | L8f0c_0_vertices_projected: |
#8f0c | #250c | 1 | 5 | 78 | ld a, b |
#8f0d | #250d | 2 | 8 | fe 01 | cp 1 |
#8f0f | #250f | 2 | 13/8 | 28 06 | jr z, L8f17_discard_current_face |
#8f11 | #2511 | 3 | 14 | 3a 28 5f | ld a, (L5f28_cull_face_when_no_projected_vertices) |
#8f14 | #2514 | 1 | 5 | b7 | or a |
#8f15 | #2515 | 2 | 13/8 | 20 06 | jr nz, L8f1d |
#8f17 | #2517 | | | | L8f17_discard_current_face: |
#8f17 | #2517 | | | | ; Ignore this face and all projected points so far |
#8f17 | #2517 | 3 | 17 | 2a e4 8c | ld hl, (L8ce4_projected_data_current_ptr_tmp) |
#8f1a | #251a | 3 | 11 | c3 9f 8f | jp L8f9f_next_face |
#8f1d | #251d | | | | |
#8f1d | #251d | | | | L8f1d: |
#8f1d | #251d | 3 | 14 | 3a 60 5e | ld a, (L5e60_projection_pre_work_type) |
#8f20 | #2520 | 1 | 5 | b7 | or a |
#8f21 | #2521 | 2 | 13/8 | 20 18 | jr nz, L8f3b_we_already_did_normal_check |
#8f23 | #2523 | | | | ; When L5e60_projection_pre_work_type is zero, we had not done a normal check, |
#8f23 | #2523 | | | | ; and hence "L5f28_cull_face_when_no_projected_vertices" might not be fully populated, |
#8f23 | #2523 | | | | ; do it now: |
#8f23 | #2523 | 2 | 17 | fd e5 | push iy |
#8f25 | #2525 | 1 | 5 | 78 | ld a, b |
#8f26 | #2526 | 2 | 10 | ed 44 | neg |
#8f28 | #2528 | 1 | 5 | 5f | ld e, a |
#8f29 | #2529 | 2 | 8 | 16 ff | ld d, 255 |
#8f2b | #252b | 2 | 17 | fd 19 | add iy, de ; iy -= number of edes of the face (to reset to the beginning of this face data) |
#8f2d | #252d | 3 | 18 | cd d1 88 | call L88d1_normal_direction_check |
#8f30 | #2530 | 2 | 16 | fd e1 | pop iy |
#8f32 | #2532 | 3 | 14 | 32 e7 8c | ld (L8ce7_current_face_normal_check_result), a |
#8f35 | #2535 | 3 | 14 | 3a 28 5f | ld a, (L5f28_cull_face_when_no_projected_vertices) |
#8f38 | #2538 | 1 | 5 | b7 | or a |
#8f39 | #2539 | 2 | 13/8 | 28 dc | jr z, L8f17_discard_current_face |
#8f3b | #253b | | | | |
#8f3b | #253b | | | | L8f3b_we_already_did_normal_check: |
#8f3b | #253b | 3 | 18 | cd 68 90 | call L9068_face_covers_whole_screen_check |
#8f3e | #253e | 3 | 14 | 3a 28 5f | ld a, (L5f28_cull_face_when_no_projected_vertices) |
#8f41 | #2541 | 1 | 5 | b7 | or a |
#8f42 | #2542 | 2 | 13/8 | 28 d3 | jr z, L8f17_discard_current_face |
#8f44 | #2544 | | | | |
#8f44 | #2544 | | | | ; Object occupies the whole screen, set screen coordinates as the projected vertices: |
#8f44 | #2544 | 3 | 11 | 11 e8 8c | ld de, L8ce8_screen_corner_coordinates |
#8f47 | #2547 | 1 | 5 | eb | ex de, hl |
#8f48 | #2548 | 3 | 11 | 01 08 00 | ld bc, 8 |
#8f4b | #254b | 2 | 23/18 | ed b0 | ldir |
#8f4d | #254d | 3 | 14 | 3a e6 8c | ld a, (L8ce6_current_face_texture_ID) |
#8f50 | #2550 | 2 | 8 | f6 04 | or 4 |
#8f52 | #2552 | 3 | 21 | dd 77 00 | ld (ix), a |
#8f55 | #2555 | | | | ; Mark that we have objects covering the whols screen: |
#8f55 | #2555 | 3 | 11 | 21 81 74 | ld hl, L7481_n_objects_covering_the_whole_screen |
#8f58 | #2558 | 1 | 12 | 34 | inc (hl) |
#8f59 | #2559 | 3 | 17 | 2a 97 74 | ld hl, (L7497_next_projected_vertex_ptr) |
#8f5c | #255c | 1 | 7 | 23 | inc hl |
#8f5d | #255d | 1 | 12 | 34 | inc (hl) |
#8f5e | #255e | 2 | 17 | cb fe | set 7, (hl) |
#8f60 | #2560 | 1 | 5 | eb | ex de, hl |
#8f61 | #2561 | 2 | 8 | 3e 01 | ld a, 1 |
#8f63 | #2563 | 3 | 14 | 32 5f 5e | ld (L5e5f_add_to_projected_objects_flag), a |
#8f66 | #2566 | 1 | 11 | c1 | pop bc |
#8f67 | #2567 | 2 | 13 | 18 3b | jr L8fa4_ret |
#8f69 | #2569 | | | | |
#8f69 | #2569 | | | | L8f69_2_or_more_vertices_projected: |
#8f69 | #2569 | 2 | 8 | fe 02 | cp 2 |
#8f6b | #256b | 2 | 13/8 | 20 05 | jr nz, L8f72_close_shape |
#8f6d | #256d | | | | ; If we projected just 2 vertices: |
#8f6d | #256d | 1 | 5 | 78 | ld a, b |
#8f6e | #256e | 2 | 8 | fe 01 | cp 1 ; If the original object was just a line, we are done |
#8f70 | #2570 | 2 | 13/8 | 28 1a | jr z, L8f8c_successful_face_projection |
#8f72 | #2572 | | | | L8f72_close_shape: |
#8f72 | #2572 | | | | ; Check if the last vertex we added matches the very first vertex, |
#8f72 | #2572 | | | | ; if it does, remove it. If it does not, check if we need to insert connecting projected vertices: |
#8f72 | #2572 | 3 | 21 | dd 5e 01 | ld e, (ix + 1) |
#8f75 | #2575 | 3 | 21 | dd 56 02 | ld d, (ix + 2) |
#8f78 | #2578 | 1 | 5 | 7b | ld a, e |
#8f79 | #2579 | 1 | 7 | 2b | dec hl |
#8f7a | #257a | 1 | 7 | 2b | dec hl |
#8f7b | #257b | 1 | 8 | be | cp (hl) |
#8f7c | #257c | 1 | 7 | 23 | inc hl |
#8f7d | #257d | 2 | 13/8 | 20 02 | jr nz, L8f81 |
#8f7f | #257f | 1 | 5 | 7a | ld a, d |
#8f80 | #2580 | 1 | 8 | be | cp (hl) |
#8f81 | #2581 | | | | L8f81: |
#8f81 | #2581 | 1 | 7 | 23 | inc hl |
#8f82 | #2582 | 2 | 13/8 | 20 05 | jr nz, L8f89 |
#8f84 | #2584 | | | | ; Match, remove the last vertex: |
#8f84 | #2584 | 1 | 5 | 0d | dec c |
#8f85 | #2585 | 1 | 7 | 2b | dec hl |
#8f86 | #2586 | 1 | 7 | 2b | dec hl |
#8f87 | #2587 | 2 | 13 | 18 03 | jr L8f8c_successful_face_projection |
#8f89 | #2589 | | | | L8f89: |
#8f89 | #2589 | | | | ; No match, check for necessary connecting vertices: |
#8f89 | #2589 | 3 | 18 | cd ea 8f | call L8fea_add_connecting_projected_vertices |
#8f8c | #258c | | | | L8f8c_successful_face_projection: |
#8f8c | #258c | | | | ; Add the texture / # of vertices byte, mark as projected, and move to next face. |
#8f8c | #258c | 3 | 14 | 3a e6 8c | ld a, (L8ce6_current_face_texture_ID) |
#8f8f | #258f | 1 | 5 | b1 | or c |
#8f90 | #2590 | 3 | 21 | dd 77 00 | ld (ix), a |
#8f93 | #2593 | | | | |
#8f93 | #2593 | 2 | 8 | 3e 01 | ld a, 1 |
#8f95 | #2595 | 3 | 14 | 32 5f 5e | ld (L5e5f_add_to_projected_objects_flag), a |
#8f98 | #2598 | 4 | 22 | dd 2a 97 74 | ld ix, (L7497_next_projected_vertex_ptr) |
#8f9c | #259c | 3 | 25 | dd 34 01 | inc (ix + 1) ; increment the number of primitives counter |
#8f9f | #259f | | | | L8f9f_next_face: |
#8f9f | #259f | 1 | 11 | c1 | pop bc |
#8fa0 | #25a0 | 1 | 5 | 05 | dec b |
#8fa1 | #25a1 | 3 | 11 | c2 19 8d | jp nz, L8d19_face_loop |
#8fa4 | #25a4 | | | | L8fa4_ret: |
#8fa4 | #25a4 | 1 | 11 | c9 | ret |
#8fa5 | #25a5 | | | | |
#8fa5 | #25a5 | | | | |
#8fa5 | #25a5 | | | | ; -------------------------------- |
#8fa5 | #25a5 | | | | ; This method projects the vertex with index 'e', and writes the projected coordinates |
#8fa5 | #25a5 | | | | ; to the L5ee8_already_projected_vertex_coordinates buffer, assuming we are using |
#8fa5 | #25a5 | | | | ; projection method L8cf0_project_object_and_add_to_render_list_clipping_internal. |
#8fa5 | #25a5 | | | | ; Input: |
#8fa5 | #25a5 | | | | ; - e: vertex index. |
#8fa5 | #25a5 | | | | L8fa5_project_one_vertex_for_clipping_projection: |
#8fa5 | #25a5 | 2 | 17 | dd e5 | push ix |
#8fa7 | #25a7 | 1 | 12 | e5 | push hl |
#8fa8 | #25a8 | 1 | 12 | d5 | push de |
#8fa9 | #25a9 | 1 | 12 | c5 | push bc |
#8faa | #25aa | 1 | 5 | 7b | ld a, e ; a = vertex index |
#8fab | #25ab | 2 | 10 | cb 23 | sla e |
#8fad | #25ad | 4 | 16 | dd 21 9f 5e | ld ix, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#8fb1 | #25b1 | 2 | 17 | dd 19 | add ix, de |
#8fb3 | #25b3 | 2 | 17 | dd 19 | add ix, de |
#8fb5 | #25b5 | 2 | 17 | dd 19 | add ix, de ; get the 3d vertex pointer |
#8fb7 | #25b7 | 3 | 18 | cd fc 90 | call L90fc_project_one_vertex |
#8fba | #25ba | 3 | 17 | 2a 24 5f | ld hl, (L5f24_shape_edges_ptr) |
#8fbd | #25bd | 4 | 16 | dd 21 e9 5e | ld ix, L5ee8_already_projected_vertex_coordinates + 1 |
#8fc1 | #25c1 | 1 | 5 | 58 | ld e, b ; e = projected y |
#8fc2 | #25c2 | 1 | 8 | 46 | ld b, (hl) ; number of edges |
#8fc3 | #25c3 | 1 | 7 | 23 | inc hl |
#8fc4 | #25c4 | | | | ; This loop goes through the L5ee8_already_projected_vertex_coordinates array, |
#8fc4 | #25c4 | | | | ; and writes projected coordinates for all the vertices that match the current vertex |
#8fc4 | #25c4 | | | | ; we just projected. |
#8fc4 | #25c4 | | | | L8fc4_write_projected_vertex_to_buffer: |
#8fc4 | #25c4 | 1 | 8 | be | cp (hl) ; is this the right vertex? |
#8fc5 | #25c5 | 2 | 13/8 | 20 06 | jr nz, L8fcd |
#8fc7 | #25c7 | | | | ; Yes, write projection data! |
#8fc7 | #25c7 | 3 | 21 | dd 71 00 | ld (ix), c ; projected x |
#8fca | #25ca | 3 | 21 | dd 73 01 | ld (ix + 1), e ; projected y |
#8fcd | #25cd | | | | L8fcd: |
#8fcd | #25cd | 2 | 12 | dd 23 | inc ix |
#8fcf | #25cf | 2 | 12 | dd 23 | inc ix |
#8fd1 | #25d1 | 1 | 7 | 23 | inc hl |
#8fd2 | #25d2 | 1 | 8 | be | cp (hl) ; is this the right vertex? |
#8fd3 | #25d3 | 2 | 13/8 | 20 06 | jr nz, L8fdb |
#8fd5 | #25d5 | | | | ; Yes, write projection data! |
#8fd5 | #25d5 | 3 | 21 | dd 71 00 | ld (ix), c ; projected x |
#8fd8 | #25d8 | 3 | 21 | dd 73 01 | ld (ix + 1), e ; projected y |
#8fdb | #25db | | | | L8fdb: |
#8fdb | #25db | 2 | 12 | dd 23 | inc ix |
#8fdd | #25dd | 2 | 12 | dd 23 | inc ix |
#8fdf | #25df | 2 | 12 | dd 23 | inc ix |
#8fe1 | #25e1 | 1 | 7 | 23 | inc hl |
#8fe2 | #25e2 | 2 | 14/9 | 10 e0 | djnz L8fc4_write_projected_vertex_to_buffer |
#8fe4 | #25e4 | 1 | 11 | c1 | pop bc |
#8fe5 | #25e5 | 1 | 11 | d1 | pop de |
#8fe6 | #25e6 | 1 | 11 | e1 | pop hl |
#8fe7 | #25e7 | 2 | 16 | dd e1 | pop ix |
#8fe9 | #25e9 | 1 | 11 | c9 | ret |
#8fea | #25ea | | | | |
#8fea | #25ea | | | | |
#8fea | #25ea | | | | ; -------------------------------- |
#8fea | #25ea | | | | ; Checks if we need to insert additional projected vertices along the screen edges to |
#8fea | #25ea | | | | ; connect the previous projected vertex with the new one we want to add. |
#8fea | #25ea | | | | ; Input: |
#8fea | #25ea | | | | ; - c: number of inserted vertexes so far |
#8fea | #25ea | | | | ; - e: new vertex projected x |
#8fea | #25ea | | | | ; - d: new vertex projected y |
#8fea | #25ea | | | | ; - hl: ptr to projected vertex data we are writing to |
#8fea | #25ea | | | | ; Output: |
#8fea | #25ea | | | | ; - c: updated number of inserted vertexes so far |
#8fea | #25ea | | | | ; - hl: updated ptr to projected vertex data we are writing to |
#8fea | #25ea | | | | L8fea_add_connecting_projected_vertices: |
#8fea | #25ea | 2 | 17 | dd e5 | push ix |
#8fec | #25ec | 2 | 17 | fd e5 | push iy |
#8fee | #25ee | 1 | 12 | e5 | push hl |
#8fef | #25ef | 2 | 16 | dd e1 | pop ix |
#8ff1 | #25f1 | 3 | 11 | 21 01 00 | ld hl, 1 |
#8ff4 | #25f4 | 2 | 8 | 3e 70 | ld a, SCREEN_HEIGHT_IN_PIXELS |
#8ff6 | #25f6 | 3 | 21 | dd be ffff | cp (ix - 1) ; is previous vertex y at the top of the screen? |
#8ff9 | #25f9 | 2 | 13/8 | 28 0e | jr z, L9009 |
#8ffb | #25fb | 1 | 5 | 2c | inc l ; l = 2 |
#8ffc | #25fc | 1 | 5 | af | xor a |
#8ffd | #25fd | 3 | 21 | dd be fffe | cp (ix - 2) ; is previous vertex x in the left of the screen? |
#9000 | #2600 | 2 | 13/8 | 28 07 | jr z, L9009 |
#9002 | #2602 | 1 | 5 | 2c | inc l ; l = 3 |
#9003 | #2603 | 3 | 21 | dd be ffff | cp (ix - 1) ; is previous vertex y in the bottom of the screen? |
#9006 | #2606 | 2 | 13/8 | 28 01 | jr z, L9009 |
#9008 | #2608 | 1 | 5 | 6f | ld l, a ; l = 0 |
#9009 | #2609 | | | | L9009: |
#9009 | #2609 | | | | ; At this point: |
#9009 | #2609 | | | | ; - l = 0: previous vertex at right side of screen |
#9009 | #2609 | | | | ; - l = 1: previous vertex at top of screen |
#9009 | #2609 | | | | ; - l = 2: previous vertex at left side of screen |
#9009 | #2609 | | | | ; - l = 3: previous vertex at bottom of screen |
#9009 | #2609 | 2 | 8 | 3e c0 | ld a, SCREEN_WIDTH_IN_PIXELS |
#900b | #260b | 1 | 5 | bb | cp e |
#900c | #260c | 2 | 13/8 | 28 0c | jr z, L901a |
#900e | #260e | 1 | 5 | 24 | inc h |
#900f | #260f | 2 | 8 | 3e 70 | ld a, SCREEN_HEIGHT_IN_PIXELS |
#9011 | #2611 | 1 | 5 | ba | cp d |
#9012 | #2612 | 2 | 13/8 | 28 06 | jr z, L901a |
#9014 | #2614 | 1 | 5 | 24 | inc h |
#9015 | #2615 | 1 | 5 | af | xor a |
#9016 | #2616 | 1 | 5 | bb | cp e |
#9017 | #2617 | 2 | 13/8 | 28 01 | jr z, L901a |
#9019 | #2619 | 1 | 5 | 24 | inc h |
#901a | #261a | | | | L901a: |
#901a | #261a | | | | ; At this point: |
#901a | #261a | | | | ; - h = 0: new vertex at right side of screen |
#901a | #261a | | | | ; - h = 1: new vertex at top of screen |
#901a | #261a | | | | ; - h = 2: new vertex at left side of screen |
#901a | #261a | | | | ; - h = 3: new vertex at bottom of screen |
#901a | #261a | 1 | 5 | 7c | ld a, h |
#901b | #261b | 1 | 5 | bd | cp l |
#901c | #261c | 2 | 13/8 | 28 42 | jr z, L9060_done ; both vertexes are in the same side of the screen, we can just insert the new vertex. |
#901e | #261e | | | | ; Previous and new vertex are not on the same edges of the screen, we need to insert an auxiliary vertex: |
#901e | #261e | 1 | 12 | d5 | push de |
#901f | #261f | | | | L901f: |
#901f | #261f | | | | ; Get the coordinates of the screen corner that would help us come closer to |
#901f | #261f | | | | ; the edge of the new projected vertex: |
#901f | #261f | 1 | 5 | 5d | ld e, l |
#9020 | #2620 | 2 | 8 | 16 00 | ld d, 0 |
#9022 | #2622 | 2 | 10 | cb 23 | sla e |
#9024 | #2624 | 4 | 16 | fd 21 e8 8c | ld iy, L8ce8_screen_corner_coordinates |
#9028 | #2628 | 2 | 17 | fd 19 | add iy, de |
#902a | #262a | 3 | 21 | fd 7e 00 | ld a, (iy) |
#902d | #262d | 3 | 21 | fd 56 01 | ld d, (iy + 1) |
#9030 | #2630 | | | | ; Check that we are not adding a point that is identical to the previous one, just in case: |
#9030 | #2630 | 1 | 5 | 5f | ld e, a |
#9031 | #2631 | 3 | 21 | dd be fffe | cp (ix - 2) |
#9034 | #2634 | 2 | 13/8 | 20 06 | jr nz, L903c |
#9036 | #2636 | 1 | 5 | 7a | ld a, d |
#9037 | #2637 | 3 | 21 | dd be ffff | cp (ix - 1) |
#903a | #263a | 2 | 13/8 | 28 1b | jr z, L9057 |
#903c | #263c | | | | L903c: |
#903c | #263c | | | | ; Check that it is not identical to the very first vertex of the face: |
#903c | #263c | 4 | 22 | fd 2a e4 8c | ld iy, (L8ce4_projected_data_current_ptr_tmp) |
#9040 | #2640 | 1 | 5 | 7b | ld a, e |
#9041 | #2641 | 3 | 21 | fd be 01 | cp (iy + 1) |
#9044 | #2644 | 2 | 13/8 | 20 06 | jr nz, L904c |
#9046 | #2646 | 1 | 5 | 7a | ld a, d |
#9047 | #2647 | 3 | 21 | fd be 02 | cp (iy + 2) |
#904a | #264a | 2 | 13/8 | 28 0b | jr z, L9057 |
#904c | #264c | | | | L904c: |
#904c | #264c | | | | ; Insert a new projected vertex: |
#904c | #264c | 3 | 21 | dd 73 00 | ld (ix), e ; x |
#904f | #264f | 3 | 21 | dd 72 01 | ld (ix + 1), d ; y |
#9052 | #2652 | 2 | 12 | dd 23 | inc ix |
#9054 | #2654 | 2 | 12 | dd 23 | inc ix |
#9056 | #2656 | 1 | 5 | 0c | inc c ; increase number of projected vertices count. |
#9057 | #2657 | | | | L9057: |
#9057 | #2657 | | | | ; update the screen edge the new previous vertex is at |
#9057 | #2657 | 1 | 5 | 2c | inc l |
#9058 | #2658 | 1 | 5 | 7d | ld a, l |
#9059 | #2659 | 2 | 8 | e6 03 | and #03 |
#905b | #265b | 1 | 5 | 6f | ld l, a |
#905c | #265c | | | | ; Have we brought it to the same edge as the new vertex? if so, we are done. |
#905c | #265c | 1 | 5 | bc | cp h |
#905d | #265d | 2 | 13/8 | 20 c0 | jr nz, L901f |
#905f | #265f | 1 | 11 | d1 | pop de |
#9060 | #2660 | | | | L9060_done: |
#9060 | #2660 | 2 | 17 | dd e5 | push ix |
#9062 | #2662 | 1 | 11 | e1 | pop hl |
#9063 | #2663 | 2 | 16 | fd e1 | pop iy |
#9065 | #2665 | 2 | 16 | dd e1 | pop ix |
#9067 | #2667 | 1 | 11 | c9 | ret |
#9068 | #2668 | | | | |
#9068 | #2668 | | | | |
#9068 | #2668 | | | | ; -------------------------------- |
#9068 | #2668 | | | | ; Checks a face that has resulted in no projected vertices covers the whole screen. |
#9068 | #2668 | | | | ; Note: I am not sure about how the math in this function works, as I have not tried to derive the |
#9068 | #2668 | | | | ; interpretration of he calculations. So, I have named this function based on the effect that |
#9068 | #2668 | | | | ; it later has when called. |
#9068 | #2668 | | | | ; Input: |
#9068 | #2668 | | | | ; - b: number of edges of face |
#9068 | #2668 | | | | ; - e: number of edges in current face |
#9068 | #2668 | | | | ; - iy: face edge data (pointing to the end of the data) |
#9068 | #2668 | | | | L9068_face_covers_whole_screen_check: |
#9068 | #2668 | 2 | 17 | dd e5 | push ix |
#906a | #266a | 2 | 17 | fd e5 | push iy |
#906c | #266c | 1 | 12 | e5 | push hl |
#906d | #266d | 1 | 5 | af | xor a |
#906e | #266e | 3 | 14 | 32 28 5f | ld (L5f28_cull_face_when_no_projected_vertices), a |
#9071 | #2671 | 1 | 5 | 78 | ld a, b |
#9072 | #2672 | 2 | 10 | ed 44 | neg |
#9074 | #2674 | 1 | 5 | 5f | ld e, a |
#9075 | #2675 | 2 | 8 | 16 ff | ld d, 255 |
#9077 | #2677 | 2 | 17 | fd 19 | add iy, de ; iy -= number of edes of the face (to reset to the beginning of this face data) |
#9079 | #2679 | | | | L9079: |
#9079 | #2679 | 1 | 12 | c5 | push bc |
#907a | #267a | 3 | 21 | fd 7e 00 | ld a, (iy) |
#907d | #267d | 2 | 8 | e6 7f | and #7f |
#907f | #267f | 1 | 5 | 5f | ld e, a |
#9080 | #2680 | 2 | 8 | 16 00 | ld d, 0 |
#9082 | #2682 | 1 | 5 | 62 | ld h, d |
#9083 | #2683 | 2 | 10 | cb 23 | sla e |
#9085 | #2685 | 4 | 22 | dd 2a 24 5f | ld ix, (L5f24_shape_edges_ptr) |
#9089 | #2689 | 2 | 12 | dd 23 | inc ix |
#908b | #268b | 2 | 17 | dd 19 | add ix, de |
#908d | #268d | 3 | 21 | dd 6e 00 | ld l, (ix) |
#9090 | #2690 | 3 | 21 | dd 5e 01 | ld e, (ix + 1) |
#9093 | #2693 | 4 | 22 | fd cb 00 7e | bit 7, (iy) ; vertex flip flag |
#9097 | #2697 | 2 | 13/8 | 28 01 | jr z, L909a |
#9099 | #2699 | 1 | 5 | eb | ex de, hl |
#909a | #269a | | | | L909a: |
#909a | #269a | 2 | 17 | fd e5 | push iy |
#909c | #269c | 2 | 10 | cb 23 | sla e |
#909e | #269e | 4 | 16 | dd 21 9f 5e | ld ix, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#90a2 | #26a2 | 2 | 17 | dd 19 | add ix, de |
#90a4 | #26a4 | 2 | 10 | cb 23 | sla e |
#90a6 | #26a6 | 2 | 17 | dd 19 | add ix, de ; ix += vertex 1 index * 6 |
#90a8 | #26a8 | 1 | 5 | eb | ex de, hl |
#90a9 | #26a9 | 2 | 10 | cb 23 | sla e |
#90ab | #26ab | 4 | 16 | fd 21 9f 5e | ld iy, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#90af | #26af | 2 | 17 | fd 19 | add iy, de |
#90b1 | #26b1 | 2 | 10 | cb 23 | sla e |
#90b3 | #26b3 | 2 | 17 | fd 19 | add iy, de ; iy += vertex 1 index * 6 |
#90b5 | #26b5 | 3 | 21 | dd 5e 02 | ld e, (ix + 2) |
#90b8 | #26b8 | 3 | 21 | dd 56 03 | ld d, (ix + 3) ; de = vertex 1 y |
#90bb | #26bb | 3 | 21 | fd 6e 00 | ld l, (iy) |
#90be | #26be | 3 | 21 | fd 66 01 | ld h, (iy + 1) ; hl = vertex 2 x |
#90c1 | #26c1 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = vertex 1 y * vertex 2 x |
#90c4 | #26c4 | 1 | 12 | d5 | push de |
#90c5 | #26c5 | 1 | 12 | e5 | push hl |
#90c6 | #26c6 | 3 | 21 | dd 5e 00 | ld e, (ix) |
#90c9 | #26c9 | 3 | 21 | dd 56 01 | ld d, (ix + 1) ; de = vertex 1 x |
#90cc | #26cc | 3 | 21 | fd 6e 02 | ld l, (iy + 2) |
#90cf | #26cf | 3 | 21 | fd 66 03 | ld h, (iy + 3) ; hl = vertex 2 y |
#90d2 | #26d2 | 3 | 18 | cd 5e a1 | call La15e_de_times_hl_signed ; (de, hl) = vertex 1 x * vertex 2 y |
#90d5 | #26d5 | 1 | 11 | c1 | pop bc |
#90d6 | #26d6 | 1 | 5 | b7 | or a |
#90d7 | #26d7 | 2 | 17 | ed 42 | sbc hl, bc ; (low word) hl = (vertex 1 x * vertex 2 y) - (vertex 1 y * vertex 2 x) (this is done only to get the carry flag for the next operation) |
#90d9 | #26d9 | 1 | 11 | c1 | pop bc |
#90da | #26da | 1 | 5 | eb | ex de, hl |
#90db | #26db | 2 | 17 | ed 42 | sbc hl, bc ; (high word) hl = (vertex 1 x * vertex 2 y) - (vertex 1 y * vertex 2 x) |
#90dd | #26dd | 2 | 8 | 2e 01 | ld l, 1 |
#90df | #26df | 3 | 11 | f2 e4 90 | jp p, L90e4 |
#90e2 | #26e2 | 2 | 8 | 2e 00 | ld l, 0 |
#90e4 | #26e4 | | | | L90e4: |
#90e4 | #26e4 | 2 | 16 | fd e1 | pop iy |
#90e6 | #26e6 | 1 | 11 | c1 | pop bc |
#90e7 | #26e7 | 3 | 14 | 3a e7 8c | ld a, (L8ce7_current_face_normal_check_result) |
#90ea | #26ea | 1 | 5 | bd | cp l |
#90eb | #26eb | 2 | 13/8 | 20 09 | jr nz, L90f6 |
#90ed | #26ed | 2 | 12 | fd 23 | inc iy |
#90ef | #26ef | 2 | 14/9 | 10 88 | djnz L9079 |
#90f1 | #26f1 | | | | ; Face covers the whole screen! |
#90f1 | #26f1 | 2 | 8 | 3e 01 | ld a, 1 |
#90f3 | #26f3 | 3 | 14 | 32 28 5f | ld (L5f28_cull_face_when_no_projected_vertices), a |
#90f6 | #26f6 | | | | L90f6: |
#90f6 | #26f6 | 1 | 11 | e1 | pop hl |
#90f7 | #26f7 | 2 | 16 | fd e1 | pop iy |
#90f9 | #26f9 | 2 | 16 | dd e1 | pop ix |
#90fb | #26fb | 1 | 11 | c9 | ret |
#90fc | #26fc | | | | |
#90fc | #26fc | | | | |
#90fc | #26fc | | | | ; -------------------------------- |
#90fc | #26fc | | | | ; Projects one vertex from 3d camera coordinates to screen coordinates. |
#90fc | #26fc | | | | ; Input: |
#90fc | #26fc | | | | ; - ix: pointer to a 3d vertex, already transformed, relative to camera view (16 bits per coordinate). |
#90fc | #26fc | | | | ; Output: |
#90fc | #26fc | | | | ; - bc: projected coordinates (c, b) = (x, y) |
#90fc | #26fc | | | | L90fc_project_one_vertex: |
#90fc | #26fc | 1 | 12 | e5 | push hl |
#90fd | #26fd | 1 | 12 | d5 | push de |
#90fe | #26fe | 1 | 12 | f5 | push af |
#90ff | #26ff | 3 | 21 | dd 56 05 | ld d, (ix + 5) |
#9102 | #2702 | 3 | 21 | dd 5e 04 | ld e, (ix + 4) ; de = z |
#9105 | #2705 | 1 | 5 | 7b | ld a, e |
#9106 | #2706 | 1 | 5 | b2 | or d |
#9107 | #2707 | 2 | 13/8 | 20 05 | jr nz, L910e_project_x |
#9109 | #2709 | | | | ; If z = 0, just project to the center of the screen. |
#9109 | #2709 | 3 | 11 | 01 60 38 | ld bc, #3860 ; (96, 56) (center of the screen). |
#910c | #270c | 2 | 13 | 18 62 | jr L9170_return |
#910e | #270e | | | | L910e_project_x: |
#910e | #270e | 3 | 21 | dd 66 01 | ld h, (ix + 1) |
#9111 | #2711 | 3 | 21 | dd 6e 00 | ld l, (ix) ; hl = x |
#9114 | #2714 | 2 | 10 | cb 7c | bit 7, h |
#9116 | #2716 | 2 | 13/8 | 28 0a | jr z, L9122 |
#9118 | #2718 | | | | ; x is negative: |
#9118 | #2718 | 1 | 12 | 19 | add hl, de |
#9119 | #2719 | 1 | 7 | 2b | dec hl ; hl = x + z - 1 |
#911a | #271a | 2 | 10 | cb 7c | bit 7, h |
#911c | #271c | 2 | 13/8 | 28 0e | jr z, L912c |
#911e | #271e | | | | ; x + z - 1 is negative |
#911e | #271e | 2 | 8 | 0e 00 | ld c, 0 ; screen x = 0 |
#9120 | #2720 | 2 | 13 | 18 1e | jr L9140_project_y |
#9122 | #2722 | | | | L9122: |
#9122 | #2722 | 1 | 5 | b7 | or a |
#9123 | #2723 | 2 | 17 | ed 52 | sbc hl, de ; hl = x - z |
#9125 | #2725 | 3 | 11 | fa 2c 91 | jp m, L912c |
#9128 | #2728 | | | | ; x - z is negative |
#9128 | #2728 | 2 | 8 | 0e c0 | ld c, SCREEN_WIDTH_IN_PIXELS ; screen x = 192 |
#912a | #272a | 2 | 13 | 18 14 | jr L9140_project_y |
#912c | #272c | | | | L912c: |
#912c | #272c | 2 | 8 | 3e 60 | ld a, SCREEN_WIDTH_IN_PIXELS / 2 |
#912e | #272e | 3 | 21 | dd 66 01 | ld h, (ix + 1) |
#9131 | #2731 | 3 | 21 | dd 6e 00 | ld l, (ix) ; hl = x |
#9134 | #2734 | 1 | 12 | d5 | push de |
#9135 | #2735 | | | | ; OPTIMIZATION: multiplication by 96 can be accelerated with a custom routine. |
#9135 | #2735 | | | | ; (a, hl) = 96 * x |
#9135 | #2735 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#9138 | #2738 | | | | ; (a, hl) = 96 * x / z |
#9138 | #2738 | 3 | 18 | cd cc a1 | call La1cc_a_hl_divided_by_de_signed |
#913b | #273b | 1 | 11 | d1 | pop de |
#913c | #273c | 2 | 8 | 3e 60 | ld a, SCREEN_WIDTH_IN_PIXELS / 2 |
#913e | #273e | 1 | 5 | 85 | add a, l |
#913f | #273f | 1 | 5 | 4f | ld c, a ; screen x = 96 * x / z + 96 |
#9140 | #2740 | | | | L9140_project_y: |
#9140 | #2740 | 3 | 21 | dd 66 03 | ld h, (ix + 3) |
#9143 | #2743 | 3 | 21 | dd 6e 02 | ld l, (ix + 2) ; hl = y |
#9146 | #2746 | 2 | 10 | cb 7c | bit 7, h |
#9148 | #2748 | 2 | 13/8 | 28 0a | jr z, L9154 |
#914a | #274a | | | | ; y is negative: |
#914a | #274a | 1 | 12 | 19 | add hl, de |
#914b | #274b | 1 | 7 | 2b | dec hl ; hl = y + z - 1 |
#914c | #274c | 2 | 10 | cb 7c | bit 7, h |
#914e | #274e | 2 | 13/8 | 28 0e | jr z, L915e |
#9150 | #2750 | | | | ; y + z - 1 is negative |
#9150 | #2750 | 2 | 8 | 06 00 | ld b, 0 ; screen y = 0 |
#9152 | #2752 | 2 | 13 | 18 1c | jr L9170_return |
#9154 | #2754 | | | | L9154: |
#9154 | #2754 | 1 | 5 | b7 | or a |
#9155 | #2755 | 2 | 17 | ed 52 | sbc hl, de ; hl = y - z |
#9157 | #2757 | 3 | 11 | fa 5e 91 | jp m, L915e |
#915a | #275a | | | | ; y - z is negative: |
#915a | #275a | 2 | 8 | 06 70 | ld b, SCREEN_HEIGHT_IN_PIXELS ; screen y = 112 |
#915c | #275c | 2 | 13 | 18 12 | jr L9170_return |
#915e | #275e | | | | L915e: |
#915e | #275e | 2 | 8 | 3e 38 | ld a, SCREEN_HEIGHT_IN_PIXELS / 2 |
#9160 | #2760 | 3 | 21 | dd 66 03 | ld h, (ix + 3) |
#9163 | #2763 | 3 | 21 | dd 6e 02 | ld l, (ix + 2) ; hl = y |
#9166 | #2766 | | | | ; OPTIMIZATION: multiplication by 96 can be accelerated with a custom routine. |
#9166 | #2766 | | | | ; (a, hl) = 96 * y |
#9166 | #2766 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#9169 | #2769 | | | | ; (a, hl) = 96 * y / z |
#9169 | #2769 | 3 | 18 | cd cc a1 | call La1cc_a_hl_divided_by_de_signed |
#916c | #276c | 2 | 8 | 3e 38 | ld a, SCREEN_HEIGHT_IN_PIXELS / 2 |
#916e | #276e | 1 | 5 | 85 | add a, l |
#916f | #276f | 1 | 5 | 47 | ld b, a ; screen x = 56 * x / z + 56 |
#9170 | #2770 | | | | L9170_return: |
#9170 | #2770 | 1 | 11 | f1 | pop af |
#9171 | #2771 | 1 | 11 | d1 | pop de |
#9172 | #2772 | 1 | 11 | e1 | pop hl |
#9173 | #2773 | 1 | 11 | c9 | ret |
#9174 | #2774 | | | | |
#9174 | #2774 | | | | |
#9174 | #2774 | | | | ; -------------------------------- |
#9174 | #2774 | | | | ; Auxiliary variables for L9177_rotate_relative_bounding_box |
#9174 | #2774 | | | | L9174_24bit_accumulator: |
#9174 | #2774 | 3 | | | db #00, #00, #00 |
#9177 | #2777 | | | | |
#9177 | #2777 | | | | |
#9177 | #2777 | | | | ; -------------------------------- |
#9177 | #2777 | | | | ; This method does two things: |
#9177 | #2777 | | | | ; - Applies the rotation matrix to the first coordinate in (L7499_3d_object_bounding_box_relative_to_player_ptr), |
#9177 | #2777 | | | | ; saving it to (L5e9f_3d_vertex_coordinates_after_rotation_matrix). |
#9177 | #2777 | | | | ; - It then multiplies the width, height, length of the object by each row of the |
#9177 | #2777 | | | | ; rotation matrix, and stores the 9 resulting values in (L5e63_3d_vertex_coordinates_relative_to_player). |
#9177 | #2777 | | | | ; - This method is used for generating vertices for cubes and rectangle objects. |
#9177 | #2777 | | | | L9177_rotate_relative_bounding_box: |
#9177 | #2777 | 4 | 22 | fd 2a 99 74 | ld iy, (L7499_3d_object_bounding_box_relative_to_player_ptr) ; These are in 16bit precision. |
#917b | #277b | 4 | 16 | dd 21 55 5e | ld ix, L5e55_rotation_matrix |
#917f | #277f | 3 | 11 | 21 9f 5e | ld hl, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#9182 | #2782 | 2 | 8 | 06 03 | ld b, 3 |
#9184 | #2784 | | | | ; Apply the rotation matrix to the first coordinate in the bounding box, and |
#9184 | #2784 | | | | ; save it in L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#9184 | #2784 | | | | L9184_matrix_coordinate_loop: |
#9184 | #2784 | 1 | 12 | e5 | push hl |
#9185 | #2785 | | | | ; Multiply the bounding box coordinate 1 by one column of the rotation matrix: |
#9185 | #2785 | 1 | 5 | af | xor a |
#9186 | #2786 | 3 | 14 | 32 74 91 | ld (L9174_24bit_accumulator), a |
#9189 | #2789 | 3 | 14 | 32 75 91 | ld (L9174_24bit_accumulator + 1), a |
#918c | #278c | 3 | 14 | 32 76 91 | ld (L9174_24bit_accumulator + 2), a |
#918f | #278f | 3 | 21 | dd 7e 00 | ld a, (ix) ; get the rotation matrix element |
#9192 | #2792 | 2 | 12 | dd 23 | inc ix |
#9194 | #2794 | 1 | 5 | b7 | or a |
#9195 | #2795 | 2 | 13/8 | 28 0f | jr z, L91a6_matrix_cell_is_zero |
#9197 | #2797 | | | | ; L9174_24bit_accumulator = bounding box x * matrix[b][0] |
#9197 | #2797 | 3 | 21 | fd 6e 00 | ld l, (iy) |
#919a | #279a | 3 | 21 | fd 66 01 | ld h, (iy + 1) |
#919d | #279d | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#91a0 | #27a0 | 3 | 14 | 32 76 91 | ld (L9174_24bit_accumulator + 2), a |
#91a3 | #27a3 | 3 | 17 | 22 74 91 | ld (L9174_24bit_accumulator), hl |
#91a6 | #27a6 | | | | L91a6_matrix_cell_is_zero: |
#91a6 | #27a6 | 3 | 21 | dd 7e 00 | ld a, (ix) ; get the next rotation matrix element |
#91a9 | #27a9 | 2 | 12 | dd 23 | inc ix |
#91ab | #27ab | 1 | 5 | b7 | or a |
#91ac | #27ac | 2 | 13/8 | 28 19 | jr z, L91c7_matrix_cell_is_zero |
#91ae | #27ae | | | | ; L9174_24bit_accumulator += bounding box z * matrix[b][1] |
#91ae | #27ae | 3 | 21 | fd 6e 04 | ld l, (iy + 4) |
#91b1 | #27b1 | 3 | 21 | fd 66 05 | ld h, (iy + 5) |
#91b4 | #27b4 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#91b7 | #27b7 | 4 | 22 | ed 5b 74 91 | ld de, (L9174_24bit_accumulator) |
#91bb | #27bb | 1 | 12 | 19 | add hl, de |
#91bc | #27bc | 3 | 17 | 22 74 91 | ld (L9174_24bit_accumulator), hl |
#91bf | #27bf | 1 | 5 | 5f | ld e, a |
#91c0 | #27c0 | 3 | 14 | 3a 76 91 | ld a, (L9174_24bit_accumulator + 2) |
#91c3 | #27c3 | 1 | 5 | 8b | adc a, e |
#91c4 | #27c4 | 3 | 14 | 32 76 91 | ld (L9174_24bit_accumulator + 2), a |
#91c7 | #27c7 | | | | L91c7_matrix_cell_is_zero: |
#91c7 | #27c7 | 3 | 21 | dd 7e 00 | ld a, (ix) ; get the next rotation matrix element |
#91ca | #27ca | 2 | 12 | dd 23 | inc ix |
#91cc | #27cc | 1 | 5 | b7 | or a |
#91cd | #27cd | 2 | 13/8 | 28 19 | jr z, L91e8_matrix_cell_is_zero |
#91cf | #27cf | | | | ; L9174_24bit_accumulator += bounding box y * matrix[b][2] |
#91cf | #27cf | 3 | 21 | fd 6e 08 | ld l, (iy + 8) |
#91d2 | #27d2 | 3 | 21 | fd 66 09 | ld h, (iy + 9) |
#91d5 | #27d5 | 3 | 18 | cd 08 a1 | call La108_a_times_hl_signed |
#91d8 | #27d8 | 4 | 22 | ed 5b 74 91 | ld de, (L9174_24bit_accumulator) |
#91dc | #27dc | 1 | 12 | 19 | add hl, de |
#91dd | #27dd | 3 | 17 | 22 74 91 | ld (L9174_24bit_accumulator), hl |
#91e0 | #27e0 | 1 | 5 | 5f | ld e, a |
#91e1 | #27e1 | 3 | 14 | 3a 76 91 | ld a, (L9174_24bit_accumulator + 2) |
#91e4 | #27e4 | 1 | 5 | 8b | adc a, e |
#91e5 | #27e5 | 3 | 14 | 32 76 91 | ld (L9174_24bit_accumulator + 2), a |
#91e8 | #27e8 | | | | L91e8_matrix_cell_is_zero: |
#91e8 | #27e8 | 3 | 17 | 2a 74 91 | ld hl, (L9174_24bit_accumulator) |
#91eb | #27eb | 3 | 14 | 3a 76 91 | ld a, (L9174_24bit_accumulator + 2) |
#91ee | #27ee | 1 | 12 | 29 | add hl, hl |
#91ef | #27ef | 1 | 5 | 17 | rla |
#91f0 | #27f0 | 1 | 12 | 29 | add hl, hl |
#91f1 | #27f1 | 1 | 5 | 17 | rla |
#91f2 | #27f2 | 1 | 5 | 5c | ld e, h ; (a, e) = (a, hl) / 64 |
#91f3 | #27f3 | 1 | 11 | e1 | pop hl |
#91f4 | #27f4 | 1 | 8 | 73 | ld (hl), e |
#91f5 | #27f5 | 1 | 7 | 23 | inc hl |
#91f6 | #27f6 | 1 | 8 | 77 | ld (hl), a |
#91f7 | #27f7 | 1 | 7 | 23 | inc hl |
#91f8 | #27f8 | 2 | 14/9 | 10 8a | djnz L9184_matrix_coordinate_loop |
#91fa | #27fa | | | | |
#91fa | #27fa | | | | ; Calculate the 9 terms resulting from multiplying (width, height, length) of the object by |
#91fa | #27fa | | | | ; each row of the rotation matrix, and store them in L5e63_3d_vertex_coordinates_relative_to_player (16 bit precision). |
#91fa | #27fa | 3 | 17 | 2a 9d 74 | ld hl, (L749d_object_currently_being_processed_ptr) |
#91fd | #27fd | 3 | 11 | 11 04 00 | ld de, 4 |
#9200 | #2800 | 1 | 12 | 19 | add hl, de |
#9201 | #2801 | 1 | 5 | eb | ex de, hl ; de = points to the (width, height, length) of the object |
#9202 | #2802 | 4 | 16 | dd 21 55 5e | ld ix, L5e55_rotation_matrix |
#9206 | #2806 | 4 | 16 | fd 21 63 5e | ld iy, L5e63_3d_vertex_coordinates_relative_to_player |
#920a | #280a | 2 | 8 | 06 03 | ld b, 3 |
#920c | #280c | | | | ; 3 iterations, one for width, onr for height, one for length: |
#920c | #280c | | | | L920c_coordinate_loop: |
#920c | #280c | 1 | 8 | 1a | ld a, (de) ; get the w, h or l |
#920d | #280d | 1 | 7 | 13 | inc de |
#920e | #280e | | | | ; Multiply by the first row element: |
#920e | #280e | 3 | 21 | dd 6e 00 | ld l, (ix) |
#9211 | #2811 | 1 | 5 | 67 | ld h, a |
#9212 | #2812 | 3 | 18 | cd 53 a2 | call La253_h_times_l_signed |
#9215 | #2815 | 3 | 21 | fd 75 00 | ld (iy), l |
#9218 | #2818 | 3 | 21 | fd 74 01 | ld (iy + 1), h |
#921b | #281b | 2 | 12 | fd 23 | inc iy |
#921d | #281d | 2 | 12 | fd 23 | inc iy |
#921f | #281f | | | | ; Multiply by the second row element: |
#921f | #281f | 3 | 21 | dd 6e 03 | ld l, (ix + 3) |
#9222 | #2822 | 1 | 5 | 67 | ld h, a |
#9223 | #2823 | 3 | 18 | cd 53 a2 | call La253_h_times_l_signed |
#9226 | #2826 | 3 | 21 | fd 75 00 | ld (iy), l |
#9229 | #2829 | 3 | 21 | fd 74 01 | ld (iy + 1), h |
#922c | #282c | 2 | 12 | fd 23 | inc iy |
#922e | #282e | 2 | 12 | fd 23 | inc iy |
#9230 | #2830 | | | | ; Multiply by the third row element: |
#9230 | #2830 | 3 | 21 | dd 6e 06 | ld l, (ix + 6) |
#9233 | #2833 | 1 | 5 | 67 | ld h, a |
#9234 | #2834 | 3 | 18 | cd 53 a2 | call La253_h_times_l_signed |
#9237 | #2837 | 3 | 21 | fd 75 00 | ld (iy), l |
#923a | #283a | 3 | 21 | fd 74 01 | ld (iy + 1), h |
#923d | #283d | 2 | 12 | fd 23 | inc iy |
#923f | #283f | 2 | 12 | fd 23 | inc iy |
#9241 | #2841 | 2 | 12 | dd 23 | inc ix ; move to next row of the matrix |
#9243 | #2843 | 2 | 14/9 | 10 c7 | djnz L920c_coordinate_loop |
#9245 | #2845 | 1 | 11 | c9 | ret |
#9246 | #2846 | | | | |
#9246 | #2846 | | | | |
#9246 | #2846 | | | | ; -------------------------------- |
#9246 | #2846 | | | | ; Checks if vertices of an object fall inside of the rendering frustum. |
#9246 | #2846 | | | | ; |
#9246 | #2846 | | | | ; Note: in modern 3d engines, the rendering volume is a frustum, but in |
#9246 | #2846 | | | | ; this engine, this is simplified and they use a pyramid. We could easily |
#9246 | #2846 | | | | ; turn it to a frustum, changing the 5th test to be a bit a head of the |
#9246 | #2846 | | | | ; player, rather than exactly at the player. I am still calling it "frustum" |
#9246 | #2846 | | | | ; for clarity (for those familiar with modern engines). |
#9246 | #2846 | | | | ; Input: |
#9246 | #2846 | | | | ; - a: number of vertices. |
#9246 | #2846 | | | | ; Returns: |
#9246 | #2846 | | | | ; - z: object is visible, nz: object is not visible. |
#9246 | #2846 | | | | ; - updates (L5e5e_at_least_one_vertex_outside_rendering_frustum) |
#9246 | #2846 | | | | L9246_object_visibility_check: |
#9246 | #2846 | 3 | 14 | 32 96 74 | ld (L7496_current_drawing_primitive_n_vertices), a |
#9249 | #2849 | 4 | 16 | fd 21 9f 5e | ld iy, L5e9f_3d_vertex_coordinates_after_rotation_matrix |
#924d | #284d | 3 | 11 | 11 dc 5e | ld de, L5edc_vertex_rendering_frustum_checks |
#9250 | #2850 | 1 | 5 | 47 | ld b, a |
#9251 | #2851 | 1 | 5 | af | xor a |
#9252 | #2852 | 3 | 14 | 32 5e 5e | ld (L5e5e_at_least_one_vertex_outside_rendering_frustum), a |
#9255 | #2855 | 1 | 5 | 4f | ld c, a |
#9256 | #2856 | | | | L9256_vertex_loop: |
#9256 | #2856 | 1 | 12 | c5 | push bc |
#9257 | #2857 | | | | ; This code performs 5 culling checks: |
#9257 | #2857 | | | | ; - assuming the rendering volume is a pyramid (with vertex in the player): |
#9257 | #2857 | | | | ; - 4 checks for the 4 walls of the pyramid |
#9257 | #2857 | | | | ; - a 5th check to see if the object is behind the player |
#9257 | #2857 | | | | ; - 'a' is initialized with 5 bits set to 1, indicating the tests pass. |
#9257 | #2857 | | | | ; - Each time a test fails (vertex is outside the rendering volume), one bit is set to 0. |
#9257 | #2857 | 2 | 8 | 3e 1f | ld a, #1f |
#9259 | #2859 | 3 | 21 | fd 4e 04 | ld c, (iy + 4) |
#925c | #285c | 3 | 21 | fd 46 05 | ld b, (iy + 5) ; bc = vertex z |
#925f | #285f | 3 | 21 | fd 6e 00 | ld l, (iy) |
#9262 | #2862 | 3 | 21 | fd 66 01 | ld h, (iy + 1) ; hl = vertex x |
#9265 | #2865 | 1 | 12 | e5 | push hl |
#9266 | #2866 | 1 | 5 | b7 | or a |
#9267 | #2867 | 2 | 17 | ed 4a | adc hl, bc ; hl = x + z |
#9269 | #2869 | 3 | 11 | f2 6e 92 | jp p, L926e_positive |
#926c | #286c | 2 | 8 | e6 0f | and #0f ; zero out bit 4 |
#926e | #286e | | | | L926e_positive: |
#926e | #286e | 3 | 21 | fd 6e 02 | ld l, (iy + 2) |
#9271 | #2871 | 3 | 21 | fd 66 03 | ld h, (iy + 3) ; hl = vertex y |
#9274 | #2874 | 1 | 12 | e5 | push hl |
#9275 | #2875 | 1 | 5 | b7 | or a |
#9276 | #2876 | 2 | 17 | ed 4a | adc hl, bc ; hl = y + z |
#9278 | #2878 | 3 | 11 | f2 7d 92 | jp p, L927d_positive |
#927b | #287b | 2 | 8 | e6 17 | and #17 ; zero out bit 3 |
#927d | #287d | | | | L927d_positive: |
#927d | #287d | 1 | 11 | e1 | pop hl |
#927e | #287e | 1 | 5 | b7 | or a |
#927f | #287f | 2 | 17 | ed 42 | sbc hl, bc ; hl = y - z |
#9281 | #2881 | 3 | 11 | fa 86 92 | jp m, L9286_negative |
#9284 | #2884 | 2 | 8 | e6 1d | and #1d ; zero out bit 2 |
#9286 | #2886 | | | | L9286_negative: |
#9286 | #2886 | 1 | 11 | e1 | pop hl |
#9287 | #2887 | 1 | 5 | b7 | or a |
#9288 | #2888 | 2 | 17 | ed 42 | sbc hl, bc ; hl = x - z |
#928a | #288a | 3 | 11 | fa 8f 92 | jp m, L928f_negative |
#928d | #288d | 2 | 8 | e6 1b | and #1b ; zero out bit 1 |
#928f | #288f | | | | L928f_negative: |
#928f | #288f | 2 | 10 | cb 78 | bit 7, b |
#9291 | #2891 | 2 | 13/8 | 28 02 | jr z, L9295_z_positive |
#9293 | #2893 | | | | ; vertex behind the camera |
#9293 | #2893 | 2 | 8 | e6 1e | and #1e ; zero out bit 0 |
#9295 | #2895 | | | | L9295_z_positive: |
#9295 | #2895 | 3 | 11 | 01 06 00 | ld bc, 6 |
#9298 | #2898 | 2 | 17 | fd 09 | add iy, bc ; next vertex |
#929a | #289a | 1 | 11 | c1 | pop bc |
#929b | #289b | 1 | 8 | 12 | ld (de), a |
#929c | #289c | 1 | 7 | 13 | inc de |
#929d | #289d | 2 | 8 | fe 1f | cp #1f |
#929f | #289f | 2 | 13/8 | 28 07 | jr z, L92a8 |
#92a1 | #28a1 | | | | ; At least one of the culling tests failed (point is outside the view frustum). |
#92a1 | #28a1 | | | | ; Hence, mark that we will use "L8cf0_project_object_and_add_to_render_list_clipping_internal" |
#92a1 | #28a1 | | | | ; instead of "L8adc_project_object_and_add_to_render_list_internal". |
#92a1 | #28a1 | | | | ; OPTIMIZATION: below, better do ld hl,L5e5e_at_least_one_vertex_outside_rendering_frustum; ld (hl),1 |
#92a1 | #28a1 | 1 | 5 | 67 | ld h, a ; save 'a' |
#92a2 | #28a2 | 2 | 8 | 3e 01 | ld a, 1 |
#92a4 | #28a4 | 3 | 14 | 32 5e 5e | ld (L5e5e_at_least_one_vertex_outside_rendering_frustum), a |
#92a7 | #28a7 | 1 | 5 | 7c | ld a, h ; restore 'a' |
#92a8 | #28a8 | | | | L92a8: |
#92a8 | #28a8 | | | | ; - 'c' accumulates the culling checks. |
#92a8 | #28a8 | | | | ; - 'c' will be #1f if at least one point has passed all the tests, or if collectively, |
#92a8 | #28a8 | | | | ; each test has been passed by at least one point. |
#92a8 | #28a8 | 1 | 5 | b1 | or c |
#92a9 | #28a9 | 1 | 5 | 4f | ld c, a |
#92aa | #28aa | 2 | 14/9 | 10 aa | djnz L9256_vertex_loop |
#92ac | #28ac | 1 | 5 | 79 | ld a, c |
#92ad | #28ad | 2 | 8 | fe 1f | cp #1f |
#92af | #28af | 1 | 11 | c9 | ret |
#92b0 | #28b0 | | | | |
#92b0 | #28b0 | | | | |
#92b0 | #28b0 | | | | ; -------------------------------- |
#92b0 | #28b0 | | | | ; Projects an object, and if it falls within the screen, add it to the list of objects to draw. |
#92b0 | #28b0 | | | | ; Input: |
#92b0 | #28b0 | | | | ; - a: projection type. |
#92b0 | #28b0 | | | | ; - if a == 0: indicates that vertices can be projected directly. |
#92b0 | #28b0 | | | | ; - if a == 1: we need to call L88d1_normal_direction_check before projection, and if back-face, we cull |
#92b0 | #28b0 | | | | ; - if a == 2: we need to call L88d1_normal_direction_check before projection, we need to use L5f26_alternative_shape_edges_ptr |
#92b0 | #28b0 | | | | ; - iy: face definition pointer. |
#92b0 | #28b0 | | | | L92b0_project_object_and_add_to_render_list: |
#92b0 | #28b0 | 3 | 14 | 32 60 5e | ld (L5e60_projection_pre_work_type), a |
#92b3 | #28b3 | 3 | 14 | 3a 5e 5e | ld a, (L5e5e_at_least_one_vertex_outside_rendering_frustum) |
#92b6 | #28b6 | 1 | 5 | b7 | or a |
#92b7 | #28b7 | 2 | 13/8 | 20 05 | jr nz, L92be |
#92b9 | #28b9 | | | | ; Easy case, all vertices within rendering volume: |
#92b9 | #28b9 | 3 | 18 | cd dc 8a | call L8adc_project_object_and_add_to_render_list_internal |
#92bc | #28bc | 2 | 13 | 18 03 | jr L92c1_continue |
#92be | #28be | | | | L92be: |
#92be | #28be | | | | ; Complex case, not all vertices within rendering volume: |
#92be | #28be | 3 | 18 | cd f0 8c | call L8cf0_project_object_and_add_to_render_list_clipping_internal |
#92c1 | #28c1 | | | | L92c1_continue: |
#92c1 | #28c1 | 3 | 14 | 3a 5f 5e | ld a, (L5e5f_add_to_projected_objects_flag) |
#92c4 | #28c4 | 1 | 5 | b7 | or a |
#92c5 | #28c5 | 2 | 13/8 | 28 24 | jr z, L92eb_do_not_draw |
#92c7 | #28c7 | | | | ; This object has to be drawn, add it to the list of projected objects: |
#92c7 | #28c7 | 4 | 22 | ed 5b 97 74 | ld de, (L7497_next_projected_vertex_ptr) ; Get the ptr we just wrote the object to. |
#92cb | #28cb | 3 | 17 | 22 97 74 | ld (L7497_next_projected_vertex_ptr), hl ; Update the ptr for the next object to just after the current one. |
#92ce | #28ce | 3 | 17 | 2a 9b 74 | ld hl, (L749b_next_object_projected_data_ptr) |
#92d1 | #28d1 | | | | ; Save the pointer to the projected vertex data for this object: |
#92d1 | #28d1 | 1 | 8 | 73 | ld (hl), e |
#92d2 | #28d2 | 1 | 7 | 23 | inc hl |
#92d3 | #28d3 | 1 | 8 | 72 | ld (hl), d |
#92d4 | #28d4 | 1 | 7 | 23 | inc hl |
#92d5 | #28d5 | | | | ; Save the pointer to the relative bounding box for this object: |
#92d5 | #28d5 | 4 | 22 | ed 5b 99 74 | ld de, (L7499_3d_object_bounding_box_relative_to_player_ptr) |
#92d9 | #28d9 | 1 | 8 | 73 | ld (hl), e |
#92da | #28da | 1 | 7 | 23 | inc hl |
#92db | #28db | 1 | 8 | 72 | ld (hl), d |
#92dc | #28dc | 1 | 7 | 23 | inc hl |
#92dd | #28dd | 3 | 17 | 22 9b 74 | ld (L749b_next_object_projected_data_ptr), hl |
#92e0 | #28e0 | | | | ; hl = de + 12 (next bounding box ptr) |
#92e0 | #28e0 | 3 | 11 | 21 0c 00 | ld hl, 12 |
#92e3 | #28e3 | 1 | 12 | 19 | add hl, de |
#92e4 | #28e4 | 3 | 17 | 22 99 74 | ld (L7499_3d_object_bounding_box_relative_to_player_ptr), hl |
#92e7 | #28e7 | 3 | 11 | 21 6b 74 | ld hl, L746b_n_objects_to_draw |
#92ea | #28ea | 1 | 12 | 34 | inc (hl) |
#92eb | #28eb | | | | L92eb_do_not_draw: |
#92eb | #28eb | 1 | 11 | c9 | ret |
#92ec | #28ec | | | | |
#92ec | #28ec | | | | |
#92ec | #28ec | | | | ; -------------------------------- |
#92ec | #28ec | | | | ; Draws a primitive (line, or polygon) |
#92ec | #28ec | | | | ; Input: |
#92ec | #28ec | | | | ; - ix: pointer to the primitive data |
#92ec | #28ec | | | | ; - (L7496_current_drawing_primitive_n_vertices): number of vertices of the primitive. |
#92ec | #28ec | | | | ; Output: |
#92ec | #28ec | | | | ; - ix: ptr to the next primitive. |
#92ec | #28ec | | | | L92ec_draw_primitive: |
#92ec | #28ec | 1 | 12 | e5 | push hl |
#92ed | #28ed | 1 | 12 | d5 | push de |
#92ee | #28ee | 1 | 12 | c5 | push bc |
#92ef | #28ef | 1 | 5 | 08 | ex af, af' |
#92f0 | #28f0 | 1 | 12 | f5 | push af |
#92f1 | #28f1 | 1 | 5 | d9 | exx |
#92f2 | #28f2 | 1 | 12 | e5 | push hl |
#92f3 | #28f3 | 1 | 12 | d5 | push de |
#92f4 | #28f4 | 1 | 12 | c5 | push bc |
#92f5 | #28f5 | 3 | 14 | 3a 96 74 | ld a, (L7496_current_drawing_primitive_n_vertices) |
#92f8 | #28f8 | 2 | 8 | fe 02 | cp 2 |
#92fa | #28fa | 3 | 11 | c2 7d 93 | jp nz, L937d_draw_polygon |
#92fd | #28fd | | | | ; Case 1: Draw a line. |
#92fd | #28fd | | | | ; Lines are defined by just 4 bytes: |
#92fd | #28fd | 3 | 21 | dd 6e 00 | ld l, (ix) ; x1 |
#9300 | #2900 | 3 | 21 | dd 66 01 | ld h, (ix + 1) ; y1 |
#9303 | #2903 | 3 | 21 | dd 5e 02 | ld e, (ix + 2) ; x2 |
#9306 | #2906 | 3 | 21 | dd 56 03 | ld d, (ix + 3) ; y2 |
#9309 | #2909 | 3 | 11 | 01 04 00 | ld bc, 4 |
#930c | #290c | 2 | 17 | dd 09 | add ix, bc ; move ix to the next primitive. |
#930e | #290e | 2 | 17 | dd e5 | push ix |
#9310 | #2910 | 1 | 5 | 7a | ld a, d |
#9311 | #2911 | 1 | 5 | 94 | sub h |
#9312 | #2912 | 2 | 13/8 | 30 03 | jr nc, L9317_line_drawing_order_set |
#9314 | #2914 | 2 | 10 | ed 44 | neg |
#9316 | #2916 | 1 | 5 | eb | ex de, hl ; if the line was to be drawn downwards, swap the points |
#9317 | #2917 | | | | L9317_line_drawing_order_set: |
#9317 | #2917 | 1 | 5 | 47 | ld b, a ; y2 - y1 |
#9318 | #2918 | 1 | 5 | 7c | ld a, h ; y1 |
#9319 | #2919 | 3 | 14 | 32 08 75 | ld (L7508_current_drawing_row), a |
#931c | #291c | 3 | 18 | cd c4 94 | call L94c4_calculate_row_ptr_and_texture_ptr |
#931f | #291f | 1 | 5 | 78 | ld a, b |
#9320 | #2920 | 1 | 5 | b7 | or a |
#9321 | #2921 | 2 | 13/8 | 20 05 | jr nz, L9328_line_is_not_horizontal |
#9323 | #2923 | | | | ; It is a horizontal line: |
#9323 | #2923 | 1 | 5 | 65 | ld h, l |
#9324 | #2924 | 1 | 5 | 53 | ld d, e |
#9325 | #2925 | 3 | 11 | c3 b5 94 | jp L94b5_draw_texture_row_and_return |
#9328 | #2928 | | | | L9328_line_is_not_horizontal: |
#9328 | #2928 | 1 | 5 | 4d | ld c, l ; starting x pixel |
#9329 | #2929 | 1 | 12 | c5 | push bc |
#932a | #292a | 1 | 5 | 7c | ld a, h |
#932b | #292b | 1 | 5 | 92 | sub d |
#932c | #292c | 1 | 5 | 4f | ld c, a |
#932d | #292d | 2 | 8 | 06 ff | ld b, #ff ; bc = y1 - y2 |
#932f | #292f | 1 | 7 | 0b | dec bc |
#9330 | #2930 | 1 | 5 | 7d | ld a, l |
#9331 | #2931 | 1 | 5 | 93 | sub e ; a = x1 - x2 |
#9332 | #2932 | 3 | 11 | 11 00 00 | ld de, 0 |
#9335 | #2935 | 1 | 5 | 6b | ld l, e |
#9336 | #2936 | 2 | 13/8 | 30 01 | jr nc, L9339 |
#9338 | #2938 | | | | ; (de, hl) should be negative |
#9338 | #2938 | 1 | 7 | 1b | dec de |
#9339 | #2939 | | | | L9339: |
#9339 | #2939 | 1 | 5 | 67 | ld h, a ; hl = (x1 - x2) * 256 |
#933a | #293a | | | | ; Calculate the line slope: |
#933a | #293a | | | | ; - slope = dx * 256 / dy |
#933a | #293a | 3 | 18 | cd b7 b1 | call Lb1b7_de_hl_divided_by_bc_signed |
#933d | #293d | 3 | 17 | 22 04 75 | ld (L7504_line_drawing_slope), hl |
#9340 | #2940 | 2 | 8 | 3e 01 | ld a, 1 |
#9342 | #2942 | 2 | 10 | cb 7a | bit 7, d |
#9344 | #2944 | 2 | 13/8 | 20 02 | jr nz, L9348_thinning_direction_set |
#9346 | #2946 | | | | ; If the result is negative, mark that we want to thicken the line |
#9346 | #2946 | | | | ; to the left in case the line is to thin to be drawn in any row. |
#9346 | #2946 | 2 | 8 | 3e ff | ld a, -1 |
#9348 | #2948 | | | | L9348_thinning_direction_set: |
#9348 | #2948 | 3 | 14 | 32 09 75 | ld (L7509_line_drawing_thinning_direction), a |
#934b | #294b | 1 | 11 | c1 | pop bc |
#934c | #294c | 1 | 5 | 04 | inc b ; number of rows to draw |
#934d | #294d | | | | ; Initialize both points (de and hl) to the beginning of the line (bottom): |
#934d | #294d | 1 | 5 | 61 | ld h, c ; c == starting x pixel |
#934e | #294e | 2 | 8 | 2e 00 | ld l, 0 |
#9350 | #2950 | 1 | 5 | 54 | ld d, h |
#9351 | #2951 | 1 | 5 | 5d | ld e, l |
#9352 | #2952 | 1 | 12 | c5 | push bc |
#9353 | #2953 | | | | ; Advance one of the two pixels, so they are offset by 1 vertical pixel. |
#9353 | #2953 | 4 | 22 | ed 4b 04 75 | ld bc, (L7504_line_drawing_slope) |
#9357 | #2957 | 1 | 12 | 09 | add hl, bc |
#9358 | #2958 | 2 | 13 | 18 14 | jr L936e_line_draw_entry_point |
#935a | #295a | | | | L935a_line_draw_row_loop: |
#935a | #295a | | | | ; Line drawing using fixed-point arithmetic: |
#935a | #295a | | | | ; - Keeps two points (one in the current Y position, and one in the previous), and draws |
#935a | #295a | | | | ; horizontal lines at each row to connect them. |
#935a | #295a | 1 | 12 | c5 | push bc |
#935b | #295b | | | | ; Draw pixels from 'd' -> 'h' |
#935b |