;============================================================================= ; Lines.asm ; This program will help me to draw the maps for text games ; Algorithm ; L1: Initialization ; ; L2: Main cycle. Get symbol! ; L3: ; ;(C)I don't take any responsibility for the use of this program ; Zedr0n -- connection closed ;============================================================================= ;============================================================================= ; .Com declaration ;============================================================================= .MODEL TINY LOCALS @@ ;============================================================================= ; Data definition/declaration ;============================================================================= .DATA CUR_POS STRUC ; X DB ? Y DB ? CUR_POS ENDS ;----------------------------------------------------------------------------- ; Equals ;----------------------------------------------------------------------------- PGUP EQU 049H PGDN EQU 051H HL EQU 0C4H VL EQU 0B3H ; CRO EQU 0C5H MLD EQU 0C2H ; MLU EQU 0C1H LLC EQU 0C0H ; LRC EQU 0D9H ; ULC EQU 0DAH ; URC EQU 0BFH LEFT EQU 4BH ; RIGHT EQU 4DH UP EQU 48H ; DOWN EQU 50H ; SPACE EQU 39H ;----------------------------------------------------------------------------- ; Constants ;----------------------------------------------------------------------------- FILENAME DB "MAP",0 ;----------------------------------------------------------------------------- ; File variables ;----------------------------------------------------------------------------- ON DB ? ; CUR CUR_POS ? HFILE DW ? SCREEN DW ? VIRT_SCR DB 80*25*2*100 DUP(?) ;----------------------------------------------------------------------------- ; Stack variables ;----------------------------------------------------------------------------- .CODE .386 ORG 100H ;============================================================================= ; Code segment ;============================================================================= START: L1: ; MOV SCREEN,0 PUSH 0B800H POP ES MOV ON,0 L2: CALL GET_SYM CMP AH,01H ; JZ L3 CALL REACT JMP L2 L3: RET ;----------------------------------------------------------------------------- ; Get_Sym ; This procedure returns a char pressed ; Algorithm ; G1: Get a char ;----------------------------------------------------------------------------- GET_SYM PROC ; G1: XOR AH,AH ; INT 16H OR AL,AL JNZ G2 OR AH,AH ; JZ G1 G2: ; RET GET_SYM ENDP ;----------------------------------------------------------------------------- ; Draw_Char ; DL : Character to show ;----------------------------------------------------------------------------- DRAW_CHAR PROC ; ; MOV AH,02H INT 21H RET ; DRAW_CHAR ENDP ;----------------------------------------------------------------------------- ; React ; Reactions on the specified keys ; R1: Check which key has been pressed ; R2: TURN ON/ÏFF ; R3: DRAW_HL right ; R4: DRAW_HL left ; R5: Draw vert. line down. Check if need to change to corner ; R6: Show corner ;----------------------------------------------------------------------------- REACT PROC ; R1: CALL GETCUR_POS CMP AH,1CH ; JZ R2 CMP ON,1 JNZ R7 CMP AH,LEFT ; JZ R4 ; CMP AH,RIGHT ; JZ R3 CMP AH,DOWN ; JZ R5 CMP AH,UP ; JZ R6 JMP EXIT R2: ; MOV AL,ON ; XOR AL,1 ; MOV ON,AL ; JMP EXIT R3: ; CALL DRAW_LINE_RIGHT JMP EXIT R4: ; CALL DRAW_LINE_LEFT JMP EXIT R5: ; CALL DRAW_LINE_DOWN ; JMP EXIT R6: ; CALL DRAW_LINE_UP JMP EXIT R7: ; CMP AH,LEFT ; JZ R8 ; CMP AH,RIGHT ; JZ R9 ; CMP AH,UP ; JZ R10 CMP AH,DOWN ; JZ R11 CMP AH,SPACE ; JZ R12 ; CMP AH,3BH ; JZ R14 CMP AH,3CH ; JZ R15 CMP AH,3DH ; JZ R16 CMP AH,PGUP ; JZ R17 ; CMP AH,PGDN ; JZ R18 MOV DL,AL CALL DRAW_CHAR JMP EXIT R8: ; DEC CUR.X ; JMP R13 R9: ; INC CUR.X ; JMP R13 ; R10: ; DEC CUR.Y ; CMP CUR.Y,0FFH JNZ R13 CALL STORE_SCREEN ; DEC SCREEN ; CALL SHOW_SCREEN ; MOV CUR.Y,0 ; MOV CUR.X,0 ; JMP R13 R11: ; INC CUR.Y ; CMP CUR.Y,24 ; JLE R13 ; CALL STORE_SCREEN ; INC SCREEN ; CALL SHOW_SCREEN MOV CUR.Y,0 ; MOV CUR.X,0 ; JMP R13 R12: ; MOV DL,20H CALL DRAW_CHAR ; INC CUR.X ; R13: ; CALL SETCUR_POS ; JMP EXIT R14: ; CALL CREATE_FILE CALL STORE_SCREEN CALL SAVE_SCREEN CALL CLOSE_FILE JMP EXIT R15: CALL OPEN_FILE ; CALL RESTORE_SCREEN ; CALL SHOW_SCREEN CALL CLOSE_FILE JMP EXIT R16: ; CALL CLEAR_SCREEN JMP EXIT ; R17: ; MOV CUR.Y,0 ; JMP R13 ; R18: ; MOV CUR.Y,24 ; JMP R13 EXIT: RET REACT ENDP ;----------------------------------------------------------------------------- ; GetCur_Pos ; Get current cursor position ;----------------------------------------------------------------------------- GETCUR_POS PROC ; PUSH AX MOV AH,03H ; XOR BH,BH ; INT 10H ; MOV CUR.X,DL ; MOV CUR.Y,DH POP AX RET ; GETCUR_POS ENDP ;----------------------------------------------------------------------------- ; SetCur_Pos ; Set current cursor position ;----------------------------------------------------------------------------- SETCUR_POS PROC ; MOV DH,CUR.Y ; MOV DL,CUR.X XOR BH,BH ; MOV AH,02H ; INT 10H RET SETCUR_POS ENDP ;----------------------------------------------------------------------------- ; Check_if_Empty ; Check if the current cursor position is empty ; Algorithm ; C1: Get absolute offset in video buffer ; 80 = 64+16 ; C2: Check! ;----------------------------------------------------------------------------- CHECK_IF_EMPTY PROC ; @@CHAR EQU [BP+4] PUSH BP ; MOV BP,SP C1: MOVZX BX,CUR.Y ; IMUL BX,80 ;MOV BX, AX ;SHL AX, 6 ;SHL BX, 4 ; MOVZX CX,CUR.X ; ADD BX, CX SHL BX,1 C2: MOV AH,@@CHAR MOV AL,BYTE PTR ES:[BX] CMP AL,AH JZ C3 XOR AL,AL C3: ; POP BP RET 2 CHECK_IF_EMPTY ENDP ;----------------------------------------------------------------------------- ; Draw_Line_right ; Draw horizontal lines and corners ; Algorithm ; L1: Check if current cell is empty ; L2: ;----------------------------------------------------------------------------- DRAW_LINE_RIGHT PROC @@R1: ; CALL GETCUR_POS MOV AH,CUR.Y ; MOV AL,CUR.X ; PUSH AX DEC CUR.Y ; PUSH VL CALL CHECK_IF_EMPTY OR AL,AL JNZ @@R3 ; PUSH URC ; CALL CHECK_IF_EMPTY ; OR AL,AL ; JNZ @@R3 ADD CUR.Y,2 ; PUSH VL ; CALL CHECK_IF_EMPTY ; OR AL,AL ; JNZ @@R4 PUSH LRC ; CALL CHECK_IF_EMPTY ; OR AL,AL ; JNZ @@R4 MOV DL,HL @@R2: POP AX ; MOV CUR.Y,AH ; MOV CUR.X,AL ; CALL DRAW_CHAR ; INC CUR.X CALL SETCUR_POS JMP @@EXIT @@R3: MOV DL,LLC JMP @@R2 @@R4: ; MOV DL,ULC ; JMP @@R2 @@EXIT: RET ; DRAW_LINE_RIGHT ENDP ;----------------------------------------------------------------------------- ; Draw_Line_left ; Draw horizontal lines and corners ; Algorithm ; L1: Check if there is something above current cell ; L2: Draw character and fix position ; L3: Set the character to be drawn ;----------------------------------------------------------------------------- DRAW_LINE_LEFT PROC @@L1: ; MOV AH,CUR.Y ; MOV AL,CUR.X ; PUSH AX DEC CUR.Y ; PUSH VL CALL CHECK_IF_EMPTY OR AL,AL JNZ @@L3 ; ADD CUR.Y,2 ; PUSH VL ; CALL CHECK_IF_EMPTY ; OR AL,AL ; JNZ @@L4 MOV DL,HL @@L2: POP AX ; MOV CUR.Y,AH ; MOV CUR.X,AL ; CALL DRAW_CHAR ; DEC CUR.X CALL SETCUR_POS ; JMP @@EXIT @@L3: MOV DL,LRC JMP @@L2 @@L4: ; MOV DL,URC ; JMP @@L2 @@EXIT: RET DRAW_LINE_LEFT ENDP ;----------------------------------------------------------------------------- ; Draw_Line_Down ; Draw vertical line down ;----------------------------------------------------------------------------- DRAW_LINE_DOWN PROC ; @@L1: CALL GETCUR_POS MOV AH,CUR.Y ; MOV AL,CUR.X ; PUSH AX DEC CUR.X PUSH HL CALL CHECK_IF_EMPTY OR AL,AL JNZ @@L3 ; ADD CUR.X,2 PUSH HL ; CALL CHECK_IF_EMPTY OR AL,AL ; JNZ @@L4 MOV DL,VL @@L2: POP AX ; MOV CUR.Y,AH ; MOV CUR.X,AL ; CALL DRAW_CHAR ; INC CUR.Y CALL SETCUR_POS ; JMP @@EXIT @@L3: ADD CUR.X,2 PUSH HL ; CALL CHECK_IF_EMPTY OR AL,AL ; JNZ @@L5 MOV DL,URC JMP @@L2 @@L4: ; MOV DL,ULC ; JMP @@L2 @@L5: MOV DL,MLD JMP @@L2 @@EXIT: ; RET ; DRAW_LINE_DOWN ENDP ;----------------------------------------------------------------------------- ; Draw_Line_Up ; Draw vertical line up ;----------------------------------------------------------------------------- DRAW_LINE_UP PROC ; @@L1: ; CALL GETCUR_POS MOV AH,CUR.Y ; MOV AL,CUR.X ; PUSH AX DEC CUR.X PUSH HL CALL CHECK_IF_EMPTY OR AL,AL JNZ @@L3 ; ADD CUR.X,2 PUSH HL ; CALL CHECK_IF_EMPTY OR AL,AL ; JNZ @@L4 MOV DL,VL @@L2: POP AX ; MOV CUR.Y,AH ; MOV CUR.X,AL ; CALL DRAW_CHAR ; DEC CUR.Y CALL SETCUR_POS ; JMP @@EXIT @@L3: ADD CUR.X,2 PUSH HL ; CALL CHECK_IF_EMPTY OR AL,AL ; JNZ @@L5 MOV DL,LRC JMP @@L2 @@L4: ; MOV DL,LLC ; JMP @@L2 @@L5: ; MOV DL,MLU ; JMP @@L2 @@EXIT: ; RET ; DRAW_LINE_UP ENDP ;----------------------------------------------------------------------------- ; Create_file ;----------------------------------------------------------------------------- CREATE_FILE PROC ; MOV AH,3CH ; XOR CX,CX ; MOV DX,OFFSET FILENAME INT 21H MOV HFILE,AX RET CREATE_FILE ENDP ;----------------------------------------------------------------------------- ; Save_screen ; Save current video buffer into file ;----------------------------------------------------------------------------- SAVE_SCREEN PROC ; PUSH DS MOV AH,40H ; MOV CX,80*25*2*10 MOV BX,HFILE ; MOV DX,OFFSET VIRT_SCR INT 21H ; POP DS RET SAVE_SCREEN ENDP ;----------------------------------------------------------------------------- ; Close_file ;----------------------------------------------------------------------------- CLOSE_FILE PROC ; MOV AH,3EH ; MOV BX,HFILE ; INT 21H RET ; CLOSE_FILE ENDP ;----------------------------------------------------------------------------- ; Open_file ;----------------------------------------------------------------------------- OPEN_FILE PROC ; MOV AH,3DH ; XOR AL,AL ; MOV DX,OFFSET FILENAME ; INT 21H MOV HFILE,AX ; RET ; OPEN_FILE ENDP ;----------------------------------------------------------------------------- ; Restore_screen ; Restore the screen from file ;----------------------------------------------------------------------------- RESTORE_SCREEN PROC ; PUSH DS MOV AH,3FH ; MOV BX,HFILE ; MOV CX,80*25*2*10 MOV DX,OFFSET VIRT_SCR INT 21H POP DS RET RESTORE_SCREEN ENDP ;----------------------------------------------------------------------------- ; Show_Screen - show the current screen ;----------------------------------------------------------------------------- SHOW_SCREEN PROC XOR CX,CX MOV SI,OFFSET VIRT_SCR XOR DI,DI @@S1: ; CMP SCREEN,CX ; JZ @@S2 ADD SI,80*25*2 ; INC CX JMP @@S1 @@S2: MOV CX,80*25*2 ; REP MOVSB RET SHOW_SCREEN ENDP ;----------------------------------------------------------------------------- ; Store_Screen - store the current screen ;----------------------------------------------------------------------------- STORE_SCREEN PROC ; PUSH ES ; PUSH DS XOR SI,SI ; PUSH CS ; POP ES MOV DI,OFFSET VIRT_SCR XOR CX,CX @@T1: CMP SCREEN,CX ; JZ @@T2 ; ADD DI,80*25*2 ; INC CX ; JMP @@T1 @@T2: PUSH 0B800H ; POP DS MOV CX,80*25*2 ; REP MOVSB POP DS ; POP ES RET STORE_SCREEN ENDP ;----------------------------------------------------------------------------- ; Clear_Screen ; Clear the screen fully and set the cursor to upper left corner ;----------------------------------------------------------------------------- CLEAR_SCREEN PROC ; XOR CH,CH ; XOR CL,CL MOV DH,25 ; MOV DL,80 MOV BH,7 ; MOV AH,07H ; INT 10H MOV CUR.X,0 ; MOV CUR.Y,0 ; CALL SETCUR_POS RET CLEAR_SCREEN ENDP END START