├── SRC ├── README.md ├── ERRMSG.C ├── DOIT.BAT ├── U4_FILE.H ├── U4.RSP ├── U4_DOS.H ├── U4_GRAPH.H ├── U4_LOC.H ├── U4_SCAN.H ├── U4_FILE.C ├── U4_HOLE.C ├── U4_MAIN2.C ├── U4_Q_N_V.C ├── U4_VAR.ASM ├── U4_EVT.C ├── U4_DOS.ASM ├── U4_MIX.C ├── U4_LOCAT.C ├── MAKEFILE ├── U4_SRCH2.C ├── U4_MAIN.C ├── U4_CSTES.C ├── U4_INIT.C ├── U4_COMBB.C ├── U4_GET.C ├── U4_SHRIN.C ├── U4_SHAPE.H ├── U4_DNG.C ├── LOW.ASM ├── U4_PEER.C ├── U4_SRCH.C ├── U4_END.C ├── U4_USE.C ├── U4_Z.C ├── UTIL2.ASM └── U4_SOUND.ASM ├── SRC-TITLE ├── joe.h ├── README.md ├── TITLE_X.C ├── ERRMSG.C ├── ERRMSG.ASM ├── BEEP.ASM ├── VAR.ASM ├── DOIT.BAT ├── U4_SCAN.H ├── FILE.C ├── TITLE.H ├── LOW.ASM ├── INFLATE.ASM ├── DATA.ASM └── UTIL2.ASM ├── forVS ├── UN_U4.vcproj ├── readme.txt ├── UN_U4.dsw ├── UN_U4.sln ├── common.h ├── lzw.h ├── U4_VAR.C ├── UN_U4TITLE.DSP └── UN_U4.DSP ├── SRC-DRV ├── doit.bat └── README.md └── README.md /SRC/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SRC-TITLE/joe.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SRC-TITLE/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /forVS/UN_U4.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ergonomy-joe/u4-decompiled/HEAD/forVS/UN_U4.vcproj -------------------------------------------------------------------------------- /SRC-DRV/doit.bat: -------------------------------------------------------------------------------- 1 | \TOOLS\MASM510 CGA_DRV.ASM; 2 | \TOOLS\LINK240 CGA_DRV.OBJ; 3 | \TOOLS\exe2bin CGA_DRV.EXE CGA.DRV 4 | fc /b CGA.DRV ..\ORIGINAL\CGA.DRV 5 | -------------------------------------------------------------------------------- /SRC-TITLE/TITLE_X.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "title.h" 8 | 9 | unsigned D_0036 = 0; 10 | unsigned D_0038 = 0; 11 | -------------------------------------------------------------------------------- /SRC-TITLE/ERRMSG.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | char huge /*D_3906*/MSG_DSKERR[] = "Disk error. Press any key to try again."; 8 | char huge /*D_392E*/MSG_SYSERR[] = "DOS: Fatal System Error!"; 9 | -------------------------------------------------------------------------------- /SRC/ERRMSG.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | 8 | char /*D_0036*/MSG_DSKERR[] = "Disk error. Press any key to try again."; 9 | char /*D_005E*/MSG_SYSERR[] = "DOS: Fatal System Error!"; 10 | -------------------------------------------------------------------------------- /SRC-TITLE/ERRMSG.ASM: -------------------------------------------------------------------------------- 1 | 2 | DGROUP GROUP CONST 3 | 4 | CONST SEGMENT PUBLIC WORD 'CONST' 5 | ASSUME DS:DGROUP 6 | PUBLIC MSG_DSKERR,MSG_SYSERR 7 | 8 | MSG_DSKERR db "Disk error. Press any key to try again.",0 ;D_3906 9 | MSG_SYSERR db "DOS: Fatal System Error!",0 ;D_392E 10 | 11 | CONST ENDS 12 | END 13 | -------------------------------------------------------------------------------- /SRC/DOIT.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | set OLDPATH=%PATH% 3 | 4 | set MSC=\tools\msc400 5 | set PATH=%MSC%;%PATH% 6 | set INCLUDE=%MSC%\INCLUDE 7 | set LIB=%MSC%\LIB 8 | 9 | \tools\turboc20\make > log.txt 10 | 11 | fc /b u4_main.exe ..\original\avatar.exe > diff.txt 12 | 13 | set PATH=%OLDPATH% 14 | set OLDPATH= 15 | 16 | type log.txt 17 | echo on 18 | -------------------------------------------------------------------------------- /SRC/U4_FILE.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | #ifndef __U4_FILE_H__ 7 | #define __U4_FILE_H__ 8 | 9 | #ifdef WIN32 10 | #define far 11 | #endif 12 | 13 | extern /*C_0812*/Console(char *); 14 | extern /*C_0855*/Load(char *, unsigned, void far *); 15 | extern /*C_08D1*/Save(char *, unsigned, void far *); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /SRC-DRV/README.md: -------------------------------------------------------------------------------- 1 | Low-level graphic functions are implemented in 3 differents files: CGA.DRV, EGA.DRV, TANDY.DRV. 2 | At runtime, depending on the running configuration, only one is loaded in memory and its functions addressed through some "hooks" placed at the beginning at the file. Some kind of extra-simple DLL. 3 | Only AVATAR.EXE uses this system. TITLE.EXE has the functions for all three types of devices linked into it. 4 | Since this is not the most interesting part of the job (and since I love CGA), I only reversed CGA.DRV. 5 | -------------------------------------------------------------------------------- /SRC/U4.RSP: -------------------------------------------------------------------------------- 1 | errmsg+ 2 | low+ 3 | u4_use+ 4 | u4_file+ 5 | u4_util+ 6 | util2+ 7 | u4_main+ 8 | u4_sound+ 9 | u4_main2+ 10 | u4_dos+ 11 | u4_graph+ 12 | u4_map+ 13 | u4_end+ 14 | u4_anim+ 15 | u4_explo+ 16 | u4_z+ 17 | u4_cstes+ 18 | u4_npc+ 19 | u4_comba+ 20 | u4_spell+ 21 | u4_q_n_v+ 22 | u4_get+ 23 | u4_locate+ 24 | u4_combb+ 25 | u4_combc+ 26 | u4_dng+ 27 | u4_hole+ 28 | u4_mix+ 29 | u4_srch+ 30 | u4_evt+ 31 | u4_ai+ 32 | u4_talk+ 33 | u4_3d+ 34 | u4_srch2+ 35 | u4_peer+ 36 | u4_init+ 37 | u4_shops+ 38 | u4_lb+ 39 | u4_shrin+ 40 | u4_var 41 | u4_main; -------------------------------------------------------------------------------- /SRC/U4_DOS.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #ifndef __U4_DOS_H__ 8 | #define __U4_DOS_H__ 9 | 10 | /*u4_dos*/ 11 | extern void far * cdecl /*C_1FF4*/dalloc(int); 12 | extern cdecl /*C_2023*/dfree(void far *); 13 | extern cdecl /*C_2033*/dopen(char *, int); 14 | extern cdecl /*C_2049*/dlseek(int, unsigned long); 15 | extern cdecl /*C_2067*/dread(int, void far *, int); 16 | extern cdecl /*C_208B*/dwrite(int, void far *, int); 17 | extern cdecl /*C_20AB*/dclose(int); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /SRC-TITLE/BEEP.ASM: -------------------------------------------------------------------------------- 1 | 2 | EXTRN speed_info:WORD 3 | 4 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 5 | ASSUME CS:_TEXT 6 | 7 | ;same as sound(1) for avatar.exe 8 | PUBLIC sound_1 ;C_21BF 9 | sound_1 PROC NEAR 10 | MOV AX,0CAh 11 | MUL speed_info 12 | MOV DX,AX 13 | ;-- backup port 61h 14 | IN AL,61h 15 | MOV AH,AL 16 | ;-- 17 | AND AL,NOT 3 18 | MOV CX,10h 19 | C_21D1: 20 | OUT 61h,AL 21 | XOR AL,2 22 | MOV BX,DX 23 | C_21D7: 24 | DEC BX 25 | PUSHF 26 | PUSH AX 27 | POP AX 28 | POPF 29 | JNZ C_21D7 30 | LOOP C_21D1 31 | ;-- restore port 61h 32 | MOV AL,AH 33 | OUT 61h,AL 34 | ;-- 35 | RET 36 | sound_1 ENDP 37 | 38 | _TEXT ENDS 39 | 40 | END 41 | -------------------------------------------------------------------------------- /SRC-TITLE/VAR.ASM: -------------------------------------------------------------------------------- 1 | DGROUP GROUP XOB,XO,XOE,c_common 2 | 3 | XOB SEGMENT PUBLIC WORD 'BSS' 4 | XOB ENDS 5 | XO SEGMENT PUBLIC WORD 'BSS' 6 | XO ENDS 7 | XOE SEGMENT PUBLIC WORD 'BSS' 8 | XOE ENDS 9 | 10 | PUBLIC D_6E80 11 | PUBLIC Party 12 | PUBLIC D_7078 13 | PUBLIC pShapes 14 | PUBLIC pAnim 15 | PUBLIC D_7082 16 | PUBLIC pCharset 17 | PUBLIC txt_X 18 | PUBLIC txt_Y 19 | PUBLIC pTitle 20 | 21 | ;actually, the next segment should be 22 | ;generated as a COMDEF record 23 | 24 | c_common SEGMENT PUBLIC PARA 'BSS' 25 | ASSUME DS:DGROUP 26 | 27 | D_6E80 dw ? ;2 monster callback flag 28 | Party db 1F6h dup(?) ;D_6E82 29 | D_7078 dw ? ;graphic adapter 30 | pShapes dd ? ;D_707A 31 | pAnim dd ? ;D_707E 32 | D_7082 dw ? 33 | pCharset dd ? ;D_7084 34 | txt_X dw ? ;D_7088 35 | txt_Y dw ? ;D_708A 36 | pTitle dd ? ;D_708C 37 | 38 | c_common ENDS 39 | 40 | END 41 | -------------------------------------------------------------------------------- /forVS/readme.txt: -------------------------------------------------------------------------------- 1 | This is experimemtal stuff, and it is not mean to be part of any release. 2 | The point is to build the old 16 bit code from Ultima IV with a 32bit compiler. 3 | You can try to build with Visual Studio 97 (an old one !) with the project file UN_U4.DSW 4 | This one contains two projects: the game, and the title part. 5 | You can also build with Visual Studio 2008: project file UN_U4.SLN 6 | But this one containt only the game part. 7 | 8 | I made a small wrapper with a window, some drawing functions, etc... 9 | I had to convert the content of the ".asm" files to C code. It seems to work but I didn't do a serious check. 10 | The drawing functions are very slow. 11 | There is no frame limitation. 12 | There may be bugs related to the conversion of signed chars or 16bit ints to 32 bit variables. 13 | There are a lot of warnings. 14 | ... 15 | 16 | ergonomy_joe 2018/09/10 17 | -------------------------------------------------------------------------------- /forVS/UN_U4.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 5.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "UN_U4"=.\UN_U4.DSP - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Project: "UN_U4TITLE"=.\UN_U4TITLE.DSP - Package Owner=<4> 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<4> 25 | {{{ 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | Global: 31 | 32 | Package=<5> 33 | {{{ 34 | }}} 35 | 36 | Package=<3> 37 | {{{ 38 | }}} 39 | 40 | ############################################################################### 41 | 42 | -------------------------------------------------------------------------------- /forVS/UN_U4.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UN_U4", "UN_U4.vcproj", "{AFC7F97D-64C7-4641-9000-7D278F0AF247}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {AFC7F97D-64C7-4641-9000-7D278F0AF247}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {AFC7F97D-64C7-4641-9000-7D278F0AF247}.Debug|Win32.Build.0 = Debug|Win32 14 | {AFC7F97D-64C7-4641-9000-7D278F0AF247}.Release|Win32.ActiveCfg = Release|Win32 15 | {AFC7F97D-64C7-4641-9000-7D278F0AF247}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /forVS/common.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include 5 | 6 | //#define U4_ROOT "I:\\OSI\\U4\\ORIGINAL\\" 7 | #define U4_ROOT "G:/WORKSPACE/UN_U4/ultima_4/" 8 | #define RATIO 2 9 | 10 | #define CONSOLE printf 11 | #define FAKE_RET return 0 12 | 13 | #define DO_SWAP(a,b,temp) { (temp) = (a); (a) = (b); (b) = (temp); } 14 | 15 | extern int CMN_kbhit; 16 | 17 | extern COLORREF U4_PALETTE[]; 18 | extern HBRUSH U4_BRUSH[]; 19 | extern HPEN U4_PEN[]; 20 | 21 | extern void CMN_createWindow(int dwWidth, int dwHeight, void *pShp, void *pChr); 22 | extern void CMN_pumpmessages(void); 23 | extern void CMN_clear(int x, int y, int w, int h, int col); 24 | 25 | extern unsigned char *CMN_getCharsetData(int c); 26 | extern unsigned char *CMN_getShapeData(int c); 27 | 28 | extern int CMN_beginScene(void); 29 | extern int CMN_endScene(void); 30 | extern void CMN_putpixel(int x, int y, int col); 31 | extern void CMN_xorpixel(int x, int y, int col); 32 | extern void CMN_puttile(unsigned char c, int x, int y); 33 | extern void CMN_putchar(char c, int x, int y); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /SRC-TITLE/DOIT.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | set OLDPATH=%PATH% 3 | 4 | set MSC4=\TOOLS\MSC400 5 | set PATH=%MSC4% 6 | set INCLUDE=%MSC4%\INCLUDE 7 | set LIB=%MSC4%\LIB 8 | set CFLAGS=/Ox /Zp /Gc 9 | set AS=\TOOLS\MASM300 10 | 11 | echo START > log.txt 12 | 13 | MSC %CFLAGS% title_x; >> log.txt 14 | MSC %CFLAGS% file; >> log.txt 15 | MSC %CFLAGS% title_0; >> log.txt 16 | %AS% /Mx GRAPH; >> log.txt 17 | %AS% /Mx BEEP; >> log.txt 18 | %AS% /Mx INFLATE; >> log.txt 19 | %AS% /Mx LOW; >> log.txt 20 | MSC %CFLAGS% title_1; >> log.txt 21 | %AS% /Mx UTIL2; >> log.txt 22 | %AS% /Mx VAR; >> log.txt 23 | 24 | REM MSC %CFLAGS% data; >> log.txt 25 | REM MSC %CFLAGS% errmsg; >> log.txt 26 | %AS% /Mx DATA; >> log.txt 27 | %AS% /Mx ERRMSG; >> log.txt 28 | 29 | LINK /MAP title_x file title_0 graph beep inflate low title_1 util2 VAR %LIB%\binmode data errmsg,title_0; >> log.txt 30 | 31 | \tools\exepack title_0.exe tmp.exe 32 | \tools\unp tmp.exe 33 | copy tmp.exe title_0.exe 34 | del tmp.exe 35 | copy title_0.exe ..\original\ 36 | 37 | set PATH=%OLDPATH% 38 | set OLDPATH= 39 | 40 | fc /b TITLE_0.EXE ..\ORIGINAL\TITLE.EXE > diff.txt 41 | -------------------------------------------------------------------------------- /forVS/lzw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lzw.h - LZW decompression from memory to memory 3 | * 4 | * Copyright (C) 2002 Marc Winterrowd 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | #ifndef LZW_H 22 | #define LZW_H 23 | 24 | long lzw_get_decompressed_size(unsigned char* compressed_mem, long compressed_size); 25 | long lzw_decompress(unsigned char* compressed_mem, unsigned char* decompressed_mem, long compressed_size); 26 | 27 | #endif /* LZW_H */ 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Lots of information/tools/remakes about "Ultima IV - Quest Of The Avatar" have been made, but so far, no one really gave an insight of the binary itself. To be more precise, of the executables of the PC version of the game (ported by James Van Artsdalen). 2 | There are two of them: AVATAR.EXE and TITLE.EXE 3 | 4 | Basically, what I did is reverse engineer them to obtain a list of source files, that, when compiled and linked, produce new executables very close to the original ones (there are maybe 10 bytes difference for each executable). 5 | 6 | Some of the source files are in assembly code. 7 | The biggest chunk is in C language, which means that it should be easier to read it. 8 | Of course, since this is a reverse-engineered from binary, files|variables|functions names were lost and I had to come up with new naming. I hope you like it. 9 | 10 | Concerning the compiler, I used "Microsoft C Compiler 4.00". Which is certainly the version that was used to build the original game. 11 | 12 | Very good remakes of the game exist already; this project is not intended to compete with them at all. Instead, interested people can take a look at the code to understand some algorithms, coding technics from another age, ... 13 | 14 | I hope you enjoy browsing the code ! 15 | ergonomy_joe 16 | -------------------------------------------------------------------------------- /SRC/U4_GRAPH.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | #ifndef __U4_GRAPH_H__ 7 | #define __U4_GRAPH_H__ 8 | 9 | extern C_20C1(char *); 10 | extern C_213B(); 11 | extern cdecl Gra_line(int, int, int, int, int); 12 | extern cdecl /*C_2201*/Gra_00(int, int); 13 | extern cdecl /*C_2206*/Gra_01(/**/); 14 | extern cdecl /*C_220B*/Gra_02(/**/); 15 | extern cdecl /*C_2210*/Gra_03(); 16 | extern cdecl /*C_221B*/Gra_04(); 17 | extern cdecl /*C_2226*/Gra_05(/*int h, int w, void *src, int dst_ofs*/); 18 | extern cdecl /*C_222B*/Gra_dot(/*int, int, int*/); 19 | extern /*C_2230*/Gra_CR(); 20 | extern /*C_2241*/Gra_09(); 21 | extern /*C_2246*/Gra_10(); 22 | extern /*C_224B*/Gra_11(int); 23 | extern cdecl /*C_2250*/Gra_12(int, int);/*(uncalled)*/ 24 | extern /*C_226C*/Gra_13(); 25 | extern cdecl /*C_2271*/Gra_dot_OR(/*int, int, int*/); 26 | extern cdecl /*C_2276*/Gra_dot_XOR(/*int, int, int*/); 27 | extern cdecl /*C_227B*/Gra_16(/*char *, int, int*/); 28 | extern cdecl /*C_2280*/Gra_17(); 29 | extern cdecl /*C_2297*/Gra_18(/**/); 30 | extern cdecl /*C_229C*/Gra_19(); 31 | extern cdecl /*C_22A7*/Gra_animSpit(); 32 | extern cdecl /*C_22AC*/Gra_init(/*char *, char *, callback*/); 33 | extern cdecl /*C_22B1*/Gra_clrscr(); 34 | extern /*C_22B6*/Gra_animFlow(unsigned);/*bug?*/ 35 | extern /*C_22BB*/Gra_animFlag(); 36 | extern /*C_22C0*/Gra_putchar(char); 37 | extern /*C_22CF*/sizzleShapes(); 38 | extern /*C_2341*/sizzleCharset(); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /SRC-TITLE/U4_SCAN.H: -------------------------------------------------------------------------------- 1 | #ifndef __U4_SCAN_H__ 2 | #define __U4_SCAN_H__ 3 | 4 | #define KBD_ESC 0x011b 5 | #define KBD_BS 0x0e08 6 | /*ctrl + backspace?*/ 7 | #define KBD_0e7f 0x0e7f 8 | #define KBD_SPACE 0x3920 9 | #define KBD_ENTER 0x1c0d 10 | 11 | #define KBD_HOME 0x4700 12 | #define KBD_UP 0x4800 13 | #define KBD_UP_ 0x487e 14 | #define KBD_PGUP 0x4900 15 | #define KBD_LEFT 0x4B00 16 | #define KBD_LEFT_ 0x4b7c 17 | #define KBD_RIGHT 0x4D00 18 | #define KBD_RIGHT_ 0xf400 19 | #define KBD_END 0x4f00 20 | #define KBD_DOWN 0x5000 21 | #define KBD_DOWN_ 0x5060 22 | #define KBD_PGDN 0x5100 23 | 24 | #define KBD_1 0x0231 25 | #define KBD_2 0x0332 26 | #define KBD_3 0x0433 27 | #define KBD_4 0x0534 28 | #define KBD_5 0x0635 29 | #define KBD_6 0x0736 30 | #define KBD_7 0x0837 31 | #define KBD_8 0x0938 32 | #define KBD_0 0x0b30 33 | 34 | #define KBD_A 0x1E61 35 | #define KBD_B 0x3062 36 | #define KBD_C 0x2E63 37 | #define KBD_D 0x2064 38 | #define KBD_E 0x1265 39 | #define KBD_F 0x2166 40 | #define KBD_G 0x2267 41 | #define KBD_H 0x2368 42 | #define KBD_I 0x1769 43 | #define KBD_J 0x246A 44 | #define KBD_K 0x256B 45 | #define KBD_L 0x266C 46 | #define KBD_M 0x326D 47 | #define KBD_N 0x316E 48 | #define KBD_O 0x186F 49 | #define KBD_P 0x1970 50 | #define KBD_Q 0x1071 51 | #define KBD_R 0x1372 52 | #define KBD_S 0x1F73 53 | #define KBD_T 0x1474 54 | #define KBD_U 0x1675 55 | #define KBD_V 0x2F76 56 | #define KBD_W 0x1177 57 | #define KBD_X 0x2D78 58 | #define KBD_Y 0x1579 59 | #define KBD_Z 0x2c7a 60 | 61 | #define KBD_CTRL_S 0x1f13 62 | #define KBD_ALT_Z 0x2c00 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /SRC/U4_LOC.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #ifndef __U4_LOC_H__ 8 | #define __U4_LOC_H__ 9 | 10 | 11 | #define LOC_BUILDINGS 0x01 12 | 13 | /*====---- ----====*/ 14 | #define LOC_CASTLES 0x01 15 | 16 | #define LOC_LCB 0x01 17 | #define LOC_LYCAEUM 0x02 18 | #define LOC_EMPATH 0x03 19 | #define LOC_SERPENT 0x04 20 | 21 | /*====---- ----====*/ 22 | #define LOC_TOWNS 0x05 23 | 24 | #define LOC_MOONGLOW 0x05 25 | #define LOC_BRITAIN 0x06 26 | #define LOC_JHELOM 0x07 27 | #define LOC_YEW 0x08 28 | #define LOC_MINOC 0x09 29 | #define LOC_TRINSIC 0x0a 30 | #define LOC_SKARA 0x0b 31 | #define LOC_MAGINCIA 0x0c 32 | 33 | #define LOC_PAWS 0x0d 34 | #define LOC_DEN 0x0e 35 | #define LOC_VESPER 0x0f 36 | #define LOC_COVE 0x10 37 | 38 | /*====---- ----====*/ 39 | #define LOC_DUNGEONS 0x11 40 | 41 | #define LOC_DECEIT 0x11 42 | #define LOC_DESPISE 0x12 43 | #define LOC_DESTARD 0x13 44 | #define LOC_WRONG 0x14 45 | #define LOC_COVETOUS 0x15 46 | #define LOC_SHAME 0x16 47 | #define LOC_HYTHLOTH 0x17 48 | #define LOC_ABYSS 0x18 49 | 50 | /*====---- ----====*/ 51 | #define LOC_SHRINES 0x19 52 | 53 | #define LOC_HONESTY 0x19 54 | #define LOC_COMPASSION 0x1a 55 | #define LOC_VALOR 0x1b 56 | #define LOC_JUSTICE 0x1c 57 | #define LOC_SACRIFICE 0x1d 58 | #define LOC_HONOR 0x1e 59 | #define LOC_SPIRITUALITY 0x1f 60 | #define LOC_HUMILITY 0x20 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /SRC/U4_SCAN.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #ifndef __U4_SCAN_H__ 8 | #define __U4_SCAN_H__ 9 | 10 | #define KBD_ESC 0x011b 11 | #define KBD_BS 0x0e08 12 | #define KBD_0e7f 0x0e7f 13 | #define KBD_SPACE 0x3920 14 | #define KBD_ENTER 0x1c0d 15 | 16 | #define KBD_HOME 0x4700 17 | #define KBD_UP 0x4800 18 | #define KBD_UP_ 0x487e 19 | #define KBD_PGUP 0x4900 20 | #define KBD_LEFT 0x4B00 21 | #define KBD_LEFT_ 0x4b7c 22 | #define KBD_RIGHT 0x4D00 23 | #define KBD_RIGHT_ 0xf400 24 | #define KBD_END 0x4f00 25 | #define KBD_DOWN 0x5000 26 | #define KBD_DOWN_ 0x5060 27 | #define KBD_PGDN 0x5100 28 | 29 | #define KBD_1 0x0231 30 | #define KBD_2 0x0332 31 | #define KBD_3 0x0433 32 | #define KBD_4 0x0534 33 | #define KBD_5 0x0635 34 | #define KBD_6 0x0736 35 | #define KBD_7 0x0837 36 | #define KBD_8 0x0938 37 | #define KBD_0 0x0b30 38 | 39 | #define KBD_A 0x1E61 40 | #define KBD_B 0x3062 41 | #define KBD_C 0x2E63 42 | #define KBD_D 0x2064 43 | #define KBD_E 0x1265 44 | #define KBD_F 0x2166 45 | #define KBD_G 0x2267 46 | #define KBD_H 0x2368 47 | #define KBD_I 0x1769 48 | #define KBD_J 0x246A 49 | #define KBD_K 0x256B 50 | #define KBD_L 0x266C 51 | #define KBD_M 0x326D 52 | #define KBD_N 0x316E 53 | #define KBD_O 0x186F 54 | #define KBD_P 0x1970 55 | #define KBD_Q 0x1071 56 | #define KBD_R 0x1372 57 | #define KBD_S 0x1F73 58 | #define KBD_T 0x1474 59 | #define KBD_U 0x1675 60 | #define KBD_V 0x2F76 61 | #define KBD_W 0x1177 62 | #define KBD_X 0x2D78 63 | #define KBD_Y 0x1579 64 | #define KBD_Z 0x2c7a 65 | 66 | #define KBD_CTRL_S 0x1f13 67 | #define KBD_ALT_Z 0x2c00 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /SRC/U4_FILE.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4_file.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "u4_dos.h" 14 | 15 | /*C_0812*/Console(bp04) 16 | char *bp04; 17 | { 18 | int bp_02; 19 | 20 | if((bp_02 = dwrite(1, bp04, strlen(bp04))) == -1 || strlen(bp04) != bp_02) { 21 | exit(3); 22 | } 23 | } 24 | 25 | /*C_0855*/Load(bp0a, bp08, bp04) 26 | char *bp0a; 27 | unsigned bp08; 28 | void far *bp04; 29 | { 30 | int bp_02, bp_04; 31 | 32 | if((bp_02 = dopen(bp0a, 0)) == -1) { 33 | Console("\r\nOpening "); 34 | Console(bp0a); 35 | return -1; 36 | } 37 | if((bp_04 = dread(bp_02, bp04, bp08)) == -1 || bp08 != bp_04) { 38 | Console("\r\nReading "); 39 | if(bp_04 == -1) { 40 | Console(bp0a); 41 | } else { 42 | Console(bp0a); 43 | Console(": File wrong size\r\n"); 44 | } 45 | return -1; 46 | } 47 | if(dclose(bp_02) == -1) { 48 | Console("\r\nClosing "); 49 | Console(bp0a); 50 | return -1; 51 | } 52 | return 0; 53 | } 54 | 55 | /*C_08D1*/Save(bp0a, bp08, bp04) 56 | char *bp0a; 57 | unsigned bp08; 58 | void far *bp04; 59 | { 60 | int bp_02, bp_04; 61 | 62 | if((bp_02 = dopen(bp0a, 1)) == -1) { 63 | Console("\r\nOpening "); 64 | Console(bp0a); 65 | return -1; 66 | } 67 | if((bp_04 = dwrite(bp_02, bp04, bp08)) == -1 || bp08 != bp_04) { 68 | Console("\r\nWriting "); 69 | if(bp_04 == -1) { 70 | Console(bp0a); 71 | } else { 72 | Console(bp0a); 73 | Console(": File wrong size\r\n"); 74 | } 75 | exit(1); 76 | } 77 | if(dclose(bp_02) == -1) { 78 | Console("\r\nClosing "); 79 | Console(bp0a); 80 | return -1; 81 | } 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /forVS/U4_VAR.C: -------------------------------------------------------------------------------- 1 | #include "u4.h" 2 | 3 | unsigned char D_9140; 4 | unsigned char D_9141; 5 | int D_9142; 6 | struct tParty /*D_9144*/Party; 7 | tMap32x32 far *D_933A[8][8]; 8 | int D_943A; /* graphic adaptater type */ 9 | unsigned char /*D_943C*/tile_forward; 10 | /*dummy*/unsigned char __943D; 11 | int D_943E; 12 | unsigned D_9440; 13 | unsigned char /*D_9442,D_9443*/ship_x, ship_y; 14 | unsigned char /*D_9444*/tile_cur; 15 | char D_9445; 16 | unsigned D_9446; 17 | char D_9448; 18 | /*dummy*/unsigned char __9449; 19 | char D_944A[8]; 20 | unsigned char D_9452; 21 | /*dummy*/unsigned char __9453; 22 | void far /*D_9454*/*pShapes; 23 | jmp_buf D_9458; 24 | unsigned /*D_946A*/CurMode; 25 | unsigned char D_946C; 26 | /*dummy*/unsigned char __946D; 27 | unsigned /*D_946E*/spell_cnt; 28 | struct tCombat /*D_9470*/Combat; 29 | struct t_68 /*D_9530*/Fighters; 30 | int /*D_9598*/File_DNG; 31 | int /*D_959A*/activeChara; 32 | struct aStruct D_959C; 33 | unsigned char /*D_959E*/tile_east; 34 | /*dummy*/unsigned char __959F; 35 | void far /*D_95A0*/*pCharset; 36 | char /*D_95A4*/spell_sta; 37 | struct aStruct D_95A5; 38 | /*dummy*/unsigned char __95A7; 39 | int /*D_95A8*/txt_X; 40 | unsigned char /*D_95AA*/tile_north; 41 | /*dummy*/unsigned char __95AB; 42 | unsigned /*D_95AC*/activeCharaY; 43 | unsigned /*D_95AE*/hit_tile; 44 | unsigned char /*D_95B0,D_95B1*/hit_x, hit_y; 45 | unsigned char D_95B2[16]; 46 | unsigned char /*D_95C2*/tile_west; 47 | unsigned char /*D_95C3*/tile_south; 48 | int /*D_95C4*/txt_Y; 49 | unsigned D_95C6; 50 | int D_95C8; 51 | unsigned char /*D_95CA*/tile_back; 52 | /*dummy*/unsigned char __95CB; 53 | int D_95CC; 54 | unsigned char D_95CE[0x120]; 55 | char D_96EE; 56 | /*dummy*/unsigned char __96EF; 57 | int /*D_96F0*/File_MAP; 58 | unsigned /*D_96F2*/WindDir; 59 | char D_96F4; 60 | /*dummy*/unsigned char __96F5; 61 | int /*D_96F6*/File_TLK; 62 | unsigned char D_96F8; 63 | unsigned char D_96F9[11*11]; 64 | unsigned char D_9772; 65 | -------------------------------------------------------------------------------- /SRC/U4_HOLE.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | 11 | unsigned char D_26B8[] = {TIL_C0,TIL_C4,TIL_C8,TIL_CC,TIL_B4,TIL_A0,TIL_A4,TIL_DC}; 12 | 13 | C_8A5A() 14 | { 15 | register int si; 16 | 17 | u4_puts(/*D_26AC*/"Ambushed!\n"); 18 | D_9772 = Party._x; 19 | D_9140 = Party._y; 20 | D_96F8 = D_9452 = D_26B8[U4_RND1(7)]; 21 | for(si = Party.f_1d8; --si >= 0; ) { 22 | if(Party.chara[si]._stat == 'G') 23 | Party.chara[si]._stat = 'S'; 24 | } 25 | dspl_Stats(); 26 | C_7FD7(); 27 | } 28 | 29 | /*C_8AB0*/CMD_HoleUp() { 30 | register int si; 31 | 32 | u4_puts(/*D_26C0*/"Hole up & Camp\n"); 33 | if(CurMode != MOD_DUNGEON && Party._loc != 0) { 34 | w_NotHere(); 35 | return; 36 | } 37 | if(Party._tile != TIL_1F) { 38 | w_OnlyOnFoot(); 39 | return; 40 | } 41 | #ifdef WIN32 42 | if(Load(CurMode == MOD_DUNGEON?/*D_26D0*/"CAMP.DNG":/*D_26D9*/"CAMP.CON", sizeof(struct tCombat), &Combat) == -1) 43 | #else 44 | if(Load(CurMode == MOD_DUNGEON?/*D_26D0*/"CAMP.DNG":/*D_26D9*/"CAMP.CON", (char *)&Fighters - (char *)&Combat, &Combat) == -1) 45 | #endif 46 | exit(3); 47 | for(si = 31; si >= 0; si--) 48 | Fighters._tile[si] = 0; 49 | for(si = Party.f_1d8; --si >= 0; ) { 50 | D_944A[si] = Fighters._chtile[si] = isCharaAlive(si)?TIL_38:0; 51 | } 52 | dspl_Stats(); 53 | u4_puts(/*D_26E2*/"Resting...\n"); 54 | D_95CC = CurMode; 55 | CurMode = MOD_COM_CAMP; 56 | u_delay(10, 0); 57 | if(U4_RND1(7) == 0) { 58 | C_8A5A(); 59 | } else if(Party._moves / 100 == Party.f_1e6) { 60 | u4_puts(/*D_26EE*/"No effect.\n"); 61 | } else { 62 | Party.f_1e6 = Party._moves / 100; 63 | for(si = Party.f_1d8; --si >= 0; ) { 64 | if(isCharaAlive(si)) { 65 | if(Party.chara[si]._stat == 'S') 66 | Party.chara[si]._stat = 'G'; 67 | HP_inc(si, U4_RND1(119)); 68 | HP_inc(si, 99); 69 | Party.chara[si]._MP = 99; 70 | } 71 | } 72 | MP_recover(); 73 | u4_puts(/*D_26FA*/"Players Healed!\n"); 74 | } 75 | dspl_Stats(); 76 | CurMode = D_95CC; 77 | if(CurMode == MOD_DUNGEON) 78 | D_9446 = 1; 79 | } 80 | -------------------------------------------------------------------------------- /SRC-TITLE/FILE.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /*C_0010*/Console(bp04) 16 | char *bp04; 17 | { 18 | int bp_02; 19 | 20 | if((bp_02 = write(1, bp04, strlen(bp04))) == -1 || strlen(bp04) != bp_02) { 21 | exit(3); 22 | } 23 | } 24 | 25 | /*C_0051*/Load(bp0a, bp08, bp04) 26 | char *bp0a; 27 | unsigned bp08; 28 | void far *bp04; 29 | { 30 | void *loc_A; 31 | int loc_B; 32 | void far *loc_C; 33 | int loc_D; 34 | 35 | loc_A = malloc(bp08); 36 | loc_C = loc_A; 37 | if(loc_A == 0) { 38 | Console(/*D_003A*/"\r\nError allocating space\r\n"); 39 | exit(0x13); 40 | } 41 | 42 | if((loc_B = open(bp0a, O_BINARY|O_RDONLY)) == -1) { 43 | Console("\r\nOpening "); 44 | Console(bp0a); 45 | return -1; 46 | } 47 | if((loc_D = read(loc_B, loc_A, bp08)) == -1 || bp08 != loc_D) { 48 | Console("\r\nReading "); 49 | if(loc_D == -1) { 50 | Console(bp0a); 51 | } else { 52 | Console(bp0a); 53 | Console(": File wrong size\r\n"); 54 | } 55 | return -1; 56 | } 57 | if(close(loc_B) == -1) { 58 | Console("\r\nClosing "); 59 | Console(bp0a); 60 | return -1; 61 | } 62 | movedata(FP_SEG(loc_C), FP_OFF(loc_C), FP_SEG(bp04), FP_OFF(bp04), bp08); 63 | free(loc_A); 64 | 65 | return 0; 66 | } 67 | 68 | /*unlike the avatar.exe's version 69 | the source buffer is not far*/ 70 | /*C_0110*/Save(bp0a, bp08, bp04) 71 | char *bp0a; 72 | unsigned bp08; 73 | void /*far */*bp04; 74 | { 75 | int bp_02, bp_04; 76 | 77 | if((bp_02 = open(bp0a, O_BINARY|O_WRONLY)) == -1) { 78 | Console("\r\nOpening "); 79 | Console(bp0a); 80 | return -1; 81 | } 82 | if((bp_04 = write(bp_02, bp04, bp08)) == -1 || bp08 != bp_04) { 83 | Console("\r\nWriting "); 84 | if(bp_04 == -1) { 85 | Console(bp0a); 86 | } else { 87 | Console(bp0a); 88 | Console(": File wrong size\r\n"); 89 | } 90 | exit(1); 91 | } 92 | if(close(bp_02) == -1) { 93 | Console("\r\nClosing "); 94 | Console(bp0a); 95 | return -1; 96 | } 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /SRC/U4_MAIN2.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | unsigned D_07F8 = 1; 10 | 11 | /*karmas*/ 12 | U16 /*D_07FA*/*pKarmas[] = { 13 | &(Party._hones), 14 | &(Party._compa), 15 | &(Party._valor), 16 | &(Party._justi), 17 | &(Party._sacri), 18 | &(Party._honor), 19 | &(Party._spiri), 20 | &(Party._humil), 21 | }; 22 | 23 | int /*D_080A*/activeCharaX = -1; 24 | 25 | char D_080C[] = {-1,0,1,0}; 26 | char D_0810[] = {0,-1,0,1}; 27 | 28 | /*moongates positions*/ 29 | unsigned char D_0814[] = {0xE0,0x60,0x26,0x32,0xA6,0x68,0x17,0xBB}; 30 | unsigned char D_081C[] = {0x85,0x66,0xE0,0x25,0x13,0xC2,0x7E,0xA7}; 31 | 32 | /*towns/castles files*/ 33 | char *D_0824[] = { 34 | /*Castles*/ 35 | /*D_06C2*/"LCB_1.ULT", 36 | /*D_06CC*/"LYCAEUM.ULT", 37 | /*D_06D8*/"EMPATH.ULT", 38 | /*D_06E3*/"SERPENT.ULT", 39 | /*Townes*/ 40 | /*D_06EF*/"MOONGLOW.ULT", 41 | /*D_06FC*/"BRITAIN.ULT", 42 | /*D_0708*/"JHELOM.ULT", 43 | /*D_0713*/"YEW.ULT", 44 | /*D_071B*/"MINOC.ULT", 45 | /*D_0725*/"TRINSIC.ULT", 46 | /*D_0731*/"SKARA.ULT", 47 | /*D_073B*/"MAGINCIA.ULT", 48 | /*Villages*/ 49 | /*D_0748*/"PAWS.ULT", 50 | /*D_0751*/"DEN.ULT", 51 | /*D_0759*/"VESPER.ULT", 52 | /*D_0764*/"COVE.ULT" 53 | }; 54 | 55 | /*places world's coordinates*/ 56 | char D_0844[] = {0x56,0xDA,0x1C,0x92,0xE8,0x52,0x24,0x3A,0x9F,0x6A,0x16,0xBB,0x62,0x88,0xC9,0x88,0xF0,0x5B,0x48,0x7E,0x9C,0x3A,0xEF,0xE9, 0xE9,0x80,0x24,0x49,0xCD,0x51,0xE7,0xE7}; 57 | char D_0864[] = {0x6B,0x6B,0x32,0xF1,0x87,0x6A,0xDE,0x2B,0x14,0xB8,0x80,0xA9,0x91,0x9E,0x3B,0x5A,0x49,0x43,0xA8,0x14,0x1B,0x66,0xF0,0xE9, 0x42,0x5C,0xE5,0x0B,0x2D,0xCF,0xD8,0xD8}; 58 | 59 | /*colors*/ 60 | char *D_0884[] = { 61 | /*D_076D*/"Blue", 62 | /*D_0772*/"Yellow", 63 | /*D_0779*/"Red", 64 | /*D_077D*/"Green", 65 | /*D_0783*/"Orange", 66 | /*D_078A*/"Purple", 67 | /*D_0791*/"White", 68 | /*D_0797*/"Black" 69 | }; 70 | 71 | /*dungeons files*/ 72 | char *D_0894[] = { 73 | /*D_079D*/"Deceit.Dng", 74 | /*D_07A8*/"Despise.Dng", 75 | /*D_07B4*/"Destard.Dng", 76 | /*D_07C0*/"Wrong.Dng", 77 | /*D_07CA*/"Covetous.Dng", 78 | /*D_07D7*/"Shame.Dng", 79 | /*D_07E1*/"Hythloth.Dng", 80 | /*D_07EE*/"Abyss.Dng" 81 | }; 82 | -------------------------------------------------------------------------------- /SRC/U4_Q_N_V.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | #include 11 | 12 | /*C_6F29*/CMD_Quit() 13 | { 14 | u4_puts(/*D_21A2*/"Quit & Save...\n"); 15 | u4_putl(Party._moves, 1, '0'); 16 | u4_puts(/*D_21B2*/" moves\n"); 17 | if(Party._loc) { 18 | if(Party._loc < 0x11 || Party._loc > 0x18) { 19 | u4_puts(/*D_21BA*/"Not Here!\n"); 20 | return; 21 | } 22 | } 23 | if(Save(/*D_21C5*/"PARTY.SAV", sizeof(struct tParty), &Party) == -1) 24 | exit(3); 25 | if(Party._loc == 0) { 26 | if(Save(/*D_21CF*/"MONSTERS.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) 27 | exit(3); 28 | } 29 | if(Party._loc < 0x11 || Party._loc > 0x18) 30 | return; 31 | if(Save(/*D_21DC*/"MONSTERS.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) 32 | exit(3); 33 | if(Save(/*D_21E9*/"DNGMAP.SAV", sizeof(tMap8x8x8), &(D_8742._map)) == -1) 34 | exit(3); 35 | } 36 | 37 | char D_21F4[] = ", You must lead!\n"; 38 | 39 | /*exchange two party members ?*/ 40 | C_6FF9(bp06, bp04) 41 | struct tChara *bp06; 42 | struct tChara *bp04; 43 | { 44 | struct tChara bp_28; 45 | memcpy(&bp_28, bp06, sizeof(struct tChara)); 46 | memcpy(bp06, bp04, sizeof(struct tChara)); 47 | memcpy(bp04, &bp_28, sizeof(struct tChara)); 48 | } 49 | 50 | /*C_7034*/CMD_NewOrder() 51 | { 52 | register struct tChara *loc_A, *loc_B; 53 | struct tChara loc_E;/*not used*/ 54 | int loc_C, loc_D; 55 | 56 | u4_puts(/*D_2206*/"New Order!\n"); 57 | if((loc_C = AskChara(/*D_2212*/"Exchange #\x12\x12\b")) < 0) 58 | return; 59 | loc_A = &(Party.chara[loc_C]); 60 | if(loc_A == &(Party.chara[0])) { 61 | u4_puts(Party.chara[0]._name); 62 | u4_puts(D_21F4); 63 | return; 64 | } 65 | if((loc_D = AskChara(/*D_2220*/" with #\x12\x12\b")) < 0) 66 | return; 67 | loc_B = &(Party.chara[loc_D]); 68 | if(loc_B == &(Party.chara[0])) { 69 | u4_puts(Party.chara[0]._name); 70 | u4_puts(D_21F4); 71 | return; 72 | } 73 | if(loc_A == loc_B) { 74 | w_What(); 75 | return; 76 | } 77 | C_6FF9(loc_A, loc_B); 78 | Gra_13(); 79 | dspl_Stats(); 80 | } 81 | 82 | /*C_70AD*/CMD_Volume() 83 | { 84 | u4_puts(/*D_222E*/"Volume O"); 85 | u4_puts((SoundFlag ^= 1)?/*D_2237*/"n!\n":/*D_223B*/"ff!\n"); 86 | } 87 | -------------------------------------------------------------------------------- /SRC/U4_VAR.ASM: -------------------------------------------------------------------------------- 1 | DGROUP GROUP XOB,XO,XOE,c_common 2 | 3 | XOB SEGMENT PUBLIC WORD 'BSS' 4 | XOB ENDS 5 | XO SEGMENT PUBLIC WORD 'BSS' 6 | XO ENDS 7 | XOE SEGMENT PUBLIC WORD 'BSS' 8 | XOE ENDS 9 | 10 | PUBLIC D_9140,D_9141,D_9142,Party 11 | PUBLIC D_933A,D_943A,tile_forward,D_943E 12 | PUBLIC D_9440,ship_x,ship_y,tile_cur 13 | PUBLIC D_9445,D_9446,D_9448,D_944A 14 | PUBLIC D_9452,pShapes,D_9458,CurMode 15 | PUBLIC spell_cnt,D_946C,Combat,Fighters 16 | PUBLIC File_DNG,activeChara,D_959C 17 | PUBLIC tile_east,pCharset,spell_sta,D_95A5 18 | PUBLIC txt_X,tile_north,activeCharaY 19 | PUBLIC hit_tile,hit_x,hit_y 20 | PUBLIC D_95B2 21 | PUBLIC tile_west,tile_south,txt_Y,D_95C6 22 | PUBLIC D_95C8,tile_back,D_95CC,D_95CE 23 | PUBLIC D_96EE,File_MAP,WindDir,D_96F4 24 | PUBLIC File_TLK,D_96F8,D_96F9,D_9772 25 | 26 | ;actually, the next segment should be 27 | ;generated as a COMDEF record 28 | 29 | c_common SEGMENT PUBLIC PARA 'BSS' 30 | ASSUME DS:DGROUP 31 | 32 | D_9140 db ? 33 | D_9141 db ? 34 | D_9142 dw ? 35 | Party db 1F6h dup(?) ;D_9144 36 | D_933A dd 8*8 dup(?) ;tMap32x32 far * 37 | D_943A dw ? ;graphic adaptater type 38 | tile_forward db ? ;D_943C 39 | db ? 40 | D_943E dw ? 41 | D_9440 dw ? 42 | ship_x db ? ;D_9442 43 | ship_y db ? ;D_9443 44 | tile_cur db ? ;D_9444 45 | D_9445 db ? 46 | D_9446 dw ? 47 | D_9448 db ? 48 | db ? 49 | D_944A db 8 dup (?) 50 | D_9452 db ? 51 | db ? 52 | pShapes dd ? ;D_9454 53 | D_9458 dw 9 dup(?) ;jmp_buf 54 | CurMode dw ? ;D_946A 55 | D_946C db ? 56 | db ? 57 | spell_cnt dw ? ;D_946E 58 | Combat db 0C0h dup(?) ;D_9470 struct tCombat 59 | Fighters db 68h dup(?) ;D_9530 60 | File_DNG dw ? ;D_9598 61 | activeChara dw ? ;D_959A 62 | D_959C db ?,? 63 | tile_east db ? ;D_959E 64 | db ? 65 | pCharset dd ? ;D_95A0 66 | spell_sta db ? ;D_95A4 67 | D_95A5 db ?,? 68 | db ? 69 | txt_X dw ? 70 | tile_north db ? ;D_95AA 71 | db ? 72 | activeCharaY dw ? ;D_95AC 73 | hit_tile dw ? ;D_95AE 74 | hit_x db ? ;D_95B0 75 | hit_y db ? ;D_95B1 76 | D_95B2 db 16 dup (?) 77 | tile_west db ? ;D_95C2 78 | tile_south db ? ;D_95C3 79 | txt_Y dw ? 80 | D_95C6 dw ? 81 | D_95C8 dw ? 82 | tile_back db ? ;D_95CA 83 | db ? 84 | D_95CC dw ? 85 | D_95CE db 120h dup (?) 86 | D_96EE db ? 87 | db ? 88 | File_MAP dw ? ;D_96F0 89 | WindDir dw ? ;D_96F2 90 | D_96F4 db ? 91 | db ? 92 | File_TLK dw ? ;D_96F6 93 | D_96F8 db ? 94 | D_96F9 db 11*11 dup (?) 95 | D_9772 db ? 96 | 97 | c_common ENDS 98 | 99 | END 100 | -------------------------------------------------------------------------------- /SRC/U4_EVT.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | C_919A() 10 | { 11 | register int si; 12 | 13 | for(si = Party.f_1d8; --si >= 0; ) { 14 | if(isCharaConscious(si) && U4_RND1(3) == 0) { 15 | Party.chara[si]._stat = 'S'; 16 | C_09D9(si); 17 | dspl_Stats(); 18 | } 19 | } 20 | } 21 | 22 | C_91D1() 23 | { 24 | register int si; 25 | 26 | for(si = Party.f_1d8; --si >= 0; ) { 27 | if(Party.chara[si]._stat == 'G' && U4_RND1(7) == 0) { 28 | Party.chara[si]._stat = 'P'; 29 | C_09D9(si); 30 | dspl_Stats(); 31 | } 32 | } 33 | } 34 | 35 | /*randomEvent*/ 36 | C_9209() 37 | { 38 | unsigned bp_02; 39 | 40 | if(CurMode == MOD_OUTDOORS && tile_cur == TIL_17 && U4_RND1(7) == 0) { 41 | u4_puts(/*D_2998*/"\nBridge Trolls!\n"); 42 | D_96F8 = TIL_A4; 43 | D_9772 = Party._x; 44 | D_9140 = Party._y; 45 | D_946C = TIL_17; 46 | C_7DBC(); 47 | return; 48 | } 49 | if(CurMode <= MOD_BUILDING && Party.f_1dc != 0) 50 | return; 51 | if(CurMode >= MOD_COMBAT) { 52 | if(Fighters._chtile[activeChara] == 0) 53 | return; 54 | switch(Combat_MAP(Combat._charaY[activeChara], Combat._charaX[activeChara])) { 55 | case TIL_03: case TIL_44: 56 | if(Party.chara[activeChara]._stat == 'G') { 57 | Party.chara[activeChara]._stat = 'P'; 58 | C_09D9(activeChara); 59 | dspl_Stats(); 60 | } 61 | break; 62 | case TIL_47: 63 | if(isCharaConscious(activeChara)) { 64 | Party.chara[activeChara]._stat = 'S'; 65 | Fighters._chtile[activeChara] = TIL_38; 66 | C_09D9(activeChara); 67 | dspl_Stats(); 68 | } 69 | break; 70 | case TIL_46: case TIL_4C: 71 | C_09D9(activeChara); 72 | bp_02 = U4_RND3(32) + 16; 73 | hitChara(activeChara, bp_02); 74 | break; 75 | } 76 | return; 77 | } 78 | if(CurMode == MOD_DUNGEON) { 79 | if((tile_cur & 0xf0) == 0xa0) { 80 | switch(tile_cur & 3) { 81 | case 0: C_91D1(); break; 82 | case 2: C_1584(); break; 83 | case 3: C_919A(); break; 84 | } 85 | } else if((tile_cur & 0xf0) == 0x80) { 86 | if(tile_cur == 0x80) { 87 | u4_puts(/*D_29A9*/"\nWinds!\n"); 88 | Party.f_1dc = 0; 89 | } else { 90 | u4_puts((tile_cur < 0x88)?/*D_29B2*/"\nFalling Rocks!\n":/*D_29C3*/"\nPit!\n"); 91 | C_1584(); 92 | } 93 | } 94 | return; 95 | } 96 | switch(tile_cur) { 97 | case TIL_03: case TIL_44: C_91D1(); break; 98 | case TIL_46: case TIL_4C: C_1584(); break; 99 | case TIL_47: C_919A(); break; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /SRC/U4_DOS.ASM: -------------------------------------------------------------------------------- 1 | EXTRN _exit:NEAR 2 | 3 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 4 | ASSUME CS:_TEXT 5 | 6 | ;--C_1FF4 7 | PUBLIC _dalloc 8 | _dalloc PROC NEAR 9 | PUSH BP 10 | MOV BP,SP 11 | ;-- convert to size in paragraphs 12 | MOV BX,[BP+04] 13 | SHR BX,1 14 | SHR BX,1 15 | SHR BX,1 16 | SHR BX,1 17 | TEST WORD PTR [BP+04],0Fh 18 | JZ C_200A 19 | INC BX 20 | C_200A: ;-- 21 | MOV AH,48h 22 | INT 21h 23 | MOV DX,AX 24 | MOV AX,0 25 | JNB C_201F 26 | ;-- 27 | MOV AX,2Dh 28 | PUSH AX 29 | CALL _exit 30 | ;-- 31 | MOV DX,0 32 | C_201F: ;-- 33 | MOV SP,BP 34 | POP BP 35 | RET 36 | _dalloc ENDP 37 | 38 | ;--C_2023 39 | PUBLIC _dfree 40 | _dfree PROC NEAR 41 | PUSH ES 42 | PUSH BP 43 | MOV BP,SP 44 | ;-- 45 | MOV ES,[BP+08] 46 | MOV AH,49h 47 | INT 21h 48 | ;-- 49 | MOV SP,BP 50 | POP BP 51 | POP ES 52 | RET 53 | _dfree ENDP 54 | 55 | ;--C_2033 56 | PUBLIC _dopen 57 | _dopen PROC NEAR 58 | PUSH BP 59 | MOV BP,SP 60 | ;-- 61 | MOV DX,[BP+04] 62 | MOV AL,[BP+06] 63 | MOV AH,3Dh 64 | INT 21h 65 | JNB C_2045 66 | MOV AX,0FFFFh 67 | C_2045: ;-- 68 | MOV SP,BP 69 | POP BP 70 | RET 71 | _dopen ENDP 72 | 73 | ;--C_2049 74 | PUBLIC _dlseek 75 | _dlseek PROC NEAR 76 | PUSH BP 77 | MOV BP,SP 78 | ;-- 79 | MOV BX,[BP+04] 80 | MOV CX,[BP+08] 81 | MOV DX,[BP+06] 82 | MOV AL,0 83 | MOV AH,42h ; move file pointer using handler 84 | INT 21h 85 | JNB C_2063 86 | MOV AX,0FFFFh 87 | MOV DX,0FFFFh 88 | C_2063: ;-- 89 | MOV SP,BP 90 | POP BP 91 | RET 92 | _dlseek ENDP 93 | 94 | ;--C_2067 95 | PUBLIC _dread 96 | _dread PROC NEAR 97 | PUSH BP 98 | MOV BP,SP 99 | PUSH DS 100 | PUSH SI 101 | PUSH DI 102 | ;-- 103 | MOV BX,[BP+04] 104 | MOV CX,[BP+0Ah] 105 | MOV DX,[BP+06] 106 | MOV AX,[BP+08] 107 | MOV DS,AX 108 | MOV AH,3Fh 109 | INT 21h 110 | JNB C_2084 111 | MOV AX,0FFFFh 112 | C_2084: ;-- 113 | POP DI 114 | POP SI 115 | POP DS 116 | MOV SP,BP 117 | POP BP 118 | RET 119 | _dread ENDP 120 | 121 | ;--C_208B 122 | PUBLIC _dwrite 123 | _dwrite PROC NEAR 124 | PUSH BP 125 | MOV BP,SP 126 | PUSH DS 127 | ;-- 128 | MOV BX,[BP+04] 129 | MOV CX,[BP+0Ah] 130 | MOV DX,[BP+06] 131 | MOV AX,[BP+08] 132 | MOV DS,AX 133 | MOV AH,40h 134 | INT 21h 135 | JNB C_20A6 136 | MOV AX,0FFFFh 137 | C_20A6: ;-- 138 | POP DS 139 | MOV SP,BP 140 | POP BP 141 | RET 142 | _dwrite ENDP 143 | 144 | ;--C_20AB 145 | PUBLIC _dclose 146 | _dclose PROC NEAR 147 | PUSH BP 148 | MOV BP,SP 149 | ;-- 150 | MOV BX,[BP+04] 151 | MOV AH,3Eh 152 | INT 21h 153 | MOV AX,0 154 | JNB C_20BD 155 | MOV AX,0FFFFh 156 | C_20BD: ;-- 157 | MOV SP,BP 158 | POP BP 159 | RET 160 | _dclose ENDP 161 | 162 | 163 | _TEXT ENDS 164 | 165 | END 166 | -------------------------------------------------------------------------------- /SRC/U4_MIX.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #define RG_ash (0x80>>0) 10 | #define RG_ginseng (0x80>>1) 11 | #define RG_garlic (0x80>>2) 12 | #define RG_spiderSilk (0x80>>3) 13 | #define RG_bloodMoss (0x80>>4) 14 | #define RG_blackPearl (0x80>>5) 15 | #define RG_nightshade (0x80>>6) 16 | #define RG_mandrake (0x80>>7) 17 | 18 | unsigned char D_277E[] = { 19 | /*A*/RG_ginseng|RG_garlic, 20 | /*B*/RG_spiderSilk|RG_bloodMoss, 21 | /*C*/RG_ginseng|RG_garlic, 22 | /*D*/RG_ash|RG_garlic|RG_blackPearl, 23 | /*E*/RG_ash|RG_spiderSilk|RG_blackPearl, 24 | /*F*/RG_ash|RG_blackPearl, 25 | /*G*/RG_ash|RG_blackPearl|RG_mandrake, 26 | /*H*/RG_ginseng|RG_spiderSilk, 27 | /*I*/RG_blackPearl|RG_mandrake, 28 | /*J*/RG_blackPearl|RG_nightshade|RG_mandrake, 29 | /*K*/RG_blackPearl|RG_nightshade, 30 | /*L*/RG_ash, 31 | /*M*/RG_ash|RG_blackPearl, 32 | /*N*/RG_ash|RG_garlic|RG_mandrake, 33 | /*O*/RG_ash|RG_bloodMoss, 34 | /*P*/RG_ash|RG_ginseng|RG_garlic, 35 | /*Q*/RG_ash|RG_ginseng|RG_bloodMoss, 36 | /*R*/RG_ash|RG_ginseng|RG_garlic|RG_spiderSilk|RG_bloodMoss|RG_mandrake, 37 | /*S*/RG_ginseng|RG_spiderSilk, 38 | /*T*/RG_ash|RG_bloodMoss|RG_mandrake, 39 | /*U*/RG_ash|RG_garlic, 40 | /*V*/RG_nightshade|RG_mandrake, 41 | /*W*/RG_ash|RG_bloodMoss, 42 | /*X*/RG_ash|RG_spiderSilk|RG_bloodMoss, 43 | /*Y*/RG_spiderSilk|RG_bloodMoss, 44 | /*Z*/RG_spiderSilk|RG_bloodMoss 45 | }; 46 | 47 | /*C_8C08*/CMD_Mix() 48 | { 49 | register int si; 50 | unsigned char loc_A[8]; 51 | int loc_B, loc_C, loc_D; 52 | char loc_E; 53 | 54 | loc_D = 0; 55 | do { 56 | Gra_13(); 57 | C_4649(); 58 | C_4C42(); 59 | txt_Y = 23; 60 | txt_X = 24; 61 | u4_puts(/*D_270C*/"Mix Reagents\n"); 62 | if((loc_C = AskLetter(/*D_271A*/"For Spell:\x12\x12\b", 'A', 'Z')) < 0) 63 | break; 64 | loc_C -= 'A'; 65 | u4_puts(D_1E98[101 + loc_C]); 66 | Gra_CR(); 67 | Gra_13(); 68 | C_4649(); 69 | for(si = 7; si >= 0; si --) 70 | loc_A[si] = Party._reagents[si]; 71 | loc_E = 0; 72 | while(1) { 73 | C_4BC7(); 74 | txt_Y = 23; 75 | txt_X = 24; 76 | if((loc_B = AskLetter(/*D_2728*/"Reagent:\x12\x12\b", 'A', 'H')) == -2) { 77 | for(si = 7; si >= 0; si --) 78 | Party._reagents[si] = loc_A[si]; 79 | loc_D = 1; 80 | break; 81 | } 82 | if(loc_B == -1) { 83 | if(loc_E == 0) { 84 | u4_puts(/*D_2734*/"\nNothing mixed!\n"); 85 | } else { 86 | u4_puts(/*D_2745*/"\nYou mix the Reagents, and...\n"); 87 | loc_B = 0; 88 | if(D_277E[loc_C] == loc_E) { 89 | u4_puts(/*D_2764*/"Success!\n\n"); 90 | Party._mixtures[loc_C] ++; 91 | if(Party._mixtures[loc_C] > 99) 92 | Party._mixtures[loc_C] = 99; 93 | } else { 94 | u4_puts(/*D_276F*/"It Fizzles!\n\n"); 95 | } 96 | } 97 | break; 98 | } 99 | loc_B -= 'A'; 100 | if(Party._reagents[loc_B] == 0) { 101 | w_NoneLeft(); 102 | break; 103 | } 104 | loc_E |= 0x80 >> loc_B; 105 | Party._reagents[loc_B] --; 106 | } 107 | } while(loc_D == 0); 108 | Gra_13(); 109 | C_4649(); 110 | dspl_Stats(); 111 | } 112 | -------------------------------------------------------------------------------- /SRC/U4_LOCAT.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | /*---------------------------------------- 10 | LOCATE 11 | ----------------------------------------*/ 12 | 13 | /*C_755E*/CMD_Locate() 14 | { 15 | u4_puts(/*D_22EA*/"Locate position with "); 16 | if(Party._sextants == 0) { 17 | w_What(); 18 | return; 19 | } 20 | u4_puts(/*D_2300*/"sextant\n Latitude: "); 21 | u4_putc((Party._y >> 4) + 'A'); 22 | u4_putc('\''); 23 | u4_putc((Party._y & 0xf) + 'A'); 24 | u4_puts(/*D_2314*/"\"\nLongitude: "); 25 | u4_putc((Party._x >> 4) + 'A'); 26 | u4_putc('\''); 27 | u4_putc((Party._x & 0xf) + 'A'); 28 | u4_putc('"'); 29 | Gra_CR(); 30 | } 31 | 32 | /*---------------------------------------- 33 | 34 | ----------------------------------------*/ 35 | 36 | unsigned char D_2334[] = { 37 | /*weapons class masks*/ 38 | 0xFF,0xFF,0xFF,0xFF,0x7F,0x6F,0x6F,0x7E,0x7E,0xFF,0x2C,0x0C,0x2E,0x5E,0xD0,0xFF, 39 | /*D_2344*//*armor class masks*/ 40 | 0xFF,0xFF,0x7F,0x2C,0x2C,0x24,0x04,0xFF 41 | }; 42 | 43 | /*"may not use"*/ 44 | C_75DC(bp08, bp06, bp04) 45 | int bp08; 46 | int bp06; 47 | int bp04; 48 | { 49 | u4_puts(/*D_2322*/"\nA "); 50 | u4_puts(D_1E98[77 + (int)Party.chara[bp08]._class]); 51 | u4_puts(/*D_2326*/" may NOT use "); 52 | if(bp04) 53 | u4_putc('a'); 54 | Gra_CR(); 55 | u4_puts(D_1E98[37 + bp06]); 56 | Gra_CR(); 57 | sound(1); 58 | } 59 | 60 | /*C_7631*/CMD_Ready() 61 | { 62 | register int loc_A, loc_B; 63 | int loc_C; 64 | 65 | if(CurMode >= MOD_COMBAT) { 66 | u4_puts(/*D_234C*/"Ready Weapon!\n"); 67 | loc_A = activeChara; 68 | } else { 69 | u4_puts(/*D_235B*/"Ready a weapon\n"); 70 | if((loc_A = AskChara(/*D_236B*/"for:\x12\x12\b")) < 0) 71 | return; 72 | } 73 | Gra_13(); 74 | C_4832(); 75 | txt_Y = 23; txt_X = 24; 76 | loc_B = AskLetter(/*D_2373*/"Weapon:\x12\x12\b", 'A', 'P'); 77 | Gra_13(); 78 | C_4649(); 79 | dspl_Stats(); 80 | if(CurMode >= MOD_COMBAT) 81 | Gra_11(activeChara); 82 | if(loc_B < 0) 83 | return; 84 | loc_B -= 'A'; 85 | if(loc_B != 0 && Party._weapons[loc_B] == 0) { 86 | w_NoneLeft(); 87 | return; 88 | } 89 | if(loc_B != 0) { 90 | if(((0x80 >> Party.chara[loc_A]._class) & D_2334[loc_B]) == 0) { 91 | C_75DC(loc_A, loc_B, 1); 92 | return; 93 | } 94 | } 95 | if((loc_C = Party.chara[loc_A]._weapon) != 0) { 96 | if(++Party._weapons[loc_C] > 99) 97 | Party._weapons[loc_C] = 99; 98 | } 99 | if(loc_B != 0) 100 | Party._weapons[loc_B] --; 101 | Party.chara[loc_A]._weapon = loc_B; 102 | u4_puts(D_1E98[37 + loc_B]); 103 | Gra_CR(); 104 | } 105 | 106 | /*C_7732*/CMD_Wear() 107 | { 108 | register int loc_A, loc_B; 109 | int loc_C; 110 | 111 | u4_puts(/*D_237E*/"Wear Armour\n"); 112 | if((loc_A = AskChara(/*D_238B*/"for:\x12\x12\b")) < 0) 113 | return; 114 | Gra_13(); 115 | C_48F8(); 116 | txt_Y = 23; txt_X = 24; 117 | loc_B = AskLetter(/*D_2393*/"Armour:\x12\x12\b", 'A', 'H'); 118 | Gra_13(); 119 | C_4649(); 120 | dspl_Stats(); 121 | if(CurMode >= MOD_COMBAT) 122 | Gra_11(activeChara); 123 | if(loc_B < 0) 124 | return; 125 | loc_B -= 'A'; 126 | if(loc_B != 0 && Party._armors[loc_B] == 0) { 127 | w_NoneLeft(); 128 | return; 129 | } 130 | if(loc_B != 0) { 131 | if(((0x80 >> Party.chara[loc_A]._class) & D_2334[loc_B + 0x10]) == 0) { 132 | C_75DC(loc_A, loc_B + 0x10, 0); 133 | return; 134 | } 135 | } 136 | if((loc_C = Party.chara[loc_A]._armor) != 0) { 137 | if(++Party._armors[loc_C] > 99) 138 | Party._armors[loc_C] = 99; 139 | } 140 | if(loc_B != 0) 141 | Party._armors[loc_B] --; 142 | Party.chara[loc_A]._armor = loc_B; 143 | u4_puts(D_1E98[53 + loc_B]); 144 | Gra_CR(); 145 | } 146 | -------------------------------------------------------------------------------- /SRC/MAKEFILE: -------------------------------------------------------------------------------- 1 | CFLAGS=/Ox /Zp /Gc 2 | ASM=\tools\masm300 /Mx 3 | OBJS=errmsg.obj \ 4 | low.obj \ 5 | u4_use.obj \ 6 | u4_file.obj \ 7 | u4_util.obj \ 8 | util2.obj \ 9 | u4_main.obj \ 10 | u4_sound.obj \ 11 | u4_main2.obj \ 12 | u4_dos.obj \ 13 | u4_graph.obj \ 14 | u4_map.obj \ 15 | u4_end.obj \ 16 | u4_anim.obj \ 17 | u4_explo.obj \ 18 | u4_z.obj \ 19 | u4_cstes.obj \ 20 | u4_npc.obj \ 21 | u4_comba.obj \ 22 | u4_spell.obj \ 23 | u4_q_n_v.obj \ 24 | u4_get.obj \ 25 | u4_locate.obj \ 26 | u4_combb.obj \ 27 | u4_combc.obj \ 28 | u4_dng.obj \ 29 | u4_hole.obj \ 30 | u4_mix.obj \ 31 | u4_srch.obj \ 32 | u4_evt.obj \ 33 | u4_ai.obj \ 34 | u4_talk.obj \ 35 | u4_3d.obj \ 36 | u4_srch2.obj \ 37 | u4_peer.obj \ 38 | u4_init.obj \ 39 | u4_shops.obj \ 40 | u4_lb.obj \ 41 | u4_shrin.obj \ 42 | u4_var.obj 43 | 44 | 45 | all: install 46 | 47 | install: u4_main.exe 48 | copy u4_main.exe ..\original 49 | 50 | u4_main.exe: $(OBJS) 51 | #----create the exe file 52 | link /MAP @u4.rsp 53 | #----pack it and then unpack it 54 | \tools\exepack u4_main.exe tmp.exe 55 | \tools\unp tmp.exe 56 | copy tmp.exe u4_main.exe 57 | del tmp.exe 58 | 59 | 60 | #u4_var.obj: u4_var.c 61 | # msc $(CFLAGS) /J u4_var; 62 | 63 | u4_var.obj: u4_var.asm 64 | $(ASM) u4_var; 65 | 66 | errmsg.obj: errmsg.c 67 | msc $(CFLAGS) errmsg; 68 | 69 | low.obj: low.asm 70 | $(ASM) low; 71 | 72 | u4_use.obj: u4_use.c 73 | msc $(CFLAGS) /J u4_use; 74 | 75 | u4_file.obj: u4_file.c 76 | msc $(CFLAGS) /J u4_file; 77 | 78 | u4_util.obj: u4_util.c 79 | msc $(CFLAGS) u4_util; 80 | 81 | util2.obj: util2.asm 82 | $(ASM) util2; 83 | 84 | u4_main.obj: u4_main.c 85 | msc $(CFLAGS) /J u4_main; 86 | 87 | u4_sound.obj: u4_sound.asm 88 | $(ASM) u4_sound; 89 | 90 | u4_main2.obj: u4_main2.c 91 | msc $(CFLAGS) /J u4_main2; 92 | 93 | u4_dos.obj: u4_dos.asm 94 | $(ASM) u4_dos; 95 | 96 | u4_graph.obj: u4_graph.asm 97 | $(ASM) u4_graph; 98 | 99 | u4_map.obj: u4_map.c 100 | msc $(CFLAGS) /J u4_map; 101 | 102 | u4_end.obj: u4_end.c 103 | msc $(CFLAGS) /J u4_end; 104 | 105 | u4_anim.obj: u4_anim.c 106 | msc $(CFLAGS) /J u4_anim; 107 | 108 | u4_explo.obj: u4_explo.c 109 | msc $(CFLAGS) u4_explo; 110 | 111 | u4_z.obj: u4_z.c 112 | msc $(CFLAGS) u4_z; 113 | 114 | u4_cstes.obj: u4_cstes.c 115 | msc $(CFLAGS) u4_cstes; 116 | 117 | u4_npc.obj: u4_npc.c 118 | msc $(CFLAGS) u4_npc; 119 | 120 | u4_comba.obj: u4_comba.c 121 | msc $(CFLAGS) /J u4_comba; 122 | 123 | u4_spell.obj: u4_spell.c 124 | msc $(CFLAGS) /J u4_spell; 125 | 126 | u4_q_n_v.obj: u4_q_n_v.c 127 | msc $(CFLAGS) /J u4_q_n_v; 128 | 129 | u4_get.obj: u4_get.c 130 | msc $(CFLAGS) u4_get; 131 | 132 | u4_locate.obj: u4_locate.c 133 | msc $(CFLAGS) u4_locate; 134 | 135 | u4_combb.obj: u4_combb.c 136 | msc $(CFLAGS) /J u4_combb; 137 | 138 | u4_combc.obj: u4_combc.c 139 | msc $(CFLAGS) u4_combc; 140 | 141 | u4_dng.obj: u4_dng.c 142 | msc $(CFLAGS) u4_dng; 143 | 144 | u4_hole.obj: u4_hole.c 145 | msc $(CFLAGS) u4_hole; 146 | 147 | u4_mix.obj: u4_mix.c 148 | msc $(CFLAGS) u4_mix; 149 | 150 | u4_srch.obj: u4_srch.c 151 | msc $(CFLAGS) u4_srch; 152 | 153 | u4_evt.obj: u4_evt.c 154 | msc $(CFLAGS) u4_evt; 155 | 156 | u4_ai.obj: u4_ai.c 157 | msc $(CFLAGS) u4_ai; 158 | 159 | u4_talk.obj: u4_talk.c 160 | msc $(CFLAGS) u4_talk; 161 | 162 | u4_3d.obj: u4_3d.c 163 | msc $(CFLAGS) u4_3d; 164 | 165 | u4_srch2.obj: u4_srch2.c 166 | msc $(CFLAGS) u4_srch2; 167 | 168 | u4_peer.obj: u4_peer.c 169 | msc $(CFLAGS) u4_peer; 170 | 171 | u4_init.obj: u4_init.c 172 | msc $(CFLAGS) u4_init; 173 | 174 | u4_shops.obj: u4_shops.c 175 | msc $(CFLAGS) u4_shops; 176 | 177 | u4_lb.obj: u4_lb.c 178 | msc $(CFLAGS) u4_lb; 179 | 180 | u4_shrin.obj: u4_shrin.c 181 | msc $(CFLAGS) u4_shrin; 182 | -------------------------------------------------------------------------------- /SRC/U4_SRCH2.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | /*---------------------------------------- 10 | MODULE SEARCH[dungeon] 11 | ----------------------------------------*/ 12 | 13 | char *D_2E04[] = {/*D_2DF0*/"\nHmmm--No Effect!\n"}; 14 | 15 | C_B730(bp06, bp04) 16 | int bp06; 17 | int bp04; 18 | { 19 | Gra_11(bp06); 20 | sound(7); 21 | sound(7); 22 | sound(7); 23 | Gra_11(bp06); 24 | hitChara(bp06, 100 * bp04); 25 | } 26 | 27 | /*increment characteristic (max 50)*/ 28 | C_B770(bp06, bp04) 29 | int *bp06; 30 | int bp04; 31 | { 32 | *bp06 += bp04; 33 | *bp06 = (*bp06 > 50)?50:*bp06; 34 | } 35 | 36 | int D_2E6E[] = {2,2,2,4,4,4,6,6};/*magical ball hits points*/ 37 | int D_2E7E[][8] = {/*magical ball characteristic*/ 38 | {0,0,5,0,5,5,5,0}, 39 | {0,5,0,5,5,0,5,0}, 40 | {5,0,0,5,0,5,5,0} 41 | }; 42 | 43 | /*magical ball*/ 44 | C_B795() 45 | { 46 | int bp_02; 47 | 48 | u4_puts(/*D_2E06*/"\nYou find a Magical Ball...\n"); 49 | if((bp_02 = AskChara(/*D_2E23*/"Who touches?\x12\x12\b")) < 0) 50 | return; 51 | if(!isCharaConscious(bp_02)) { 52 | u4_puts(/*D_2E33*/"\nDisabled!\n"); 53 | return; 54 | } 55 | D_8742._map.x8x8x8[Party._z][Party._y][Party._x] = 0; 56 | C_B730(bp_02, D_2E6E[Party._loc - 0x11]); 57 | /*-- which characteristic(s) ? --*/ 58 | if(D_2E7E[0][Party._loc - 0x11]) { 59 | C_B770(&(Party.chara[bp_02]._str), 5); 60 | u4_puts(/*D_2E3F*/"Strength + 5\n"); 61 | } 62 | if(D_2E7E[1][Party._loc - 0x11]) { 63 | C_B770(&(Party.chara[bp_02]._dex), 5); 64 | u4_puts(/*D_2E4D*/"Dexterity + 5\n"); 65 | } 66 | if(D_2E7E[2][Party._loc - 0x11]) { 67 | C_B770(&(Party.chara[bp_02]._int), 5); 68 | u4_puts(/*D_2E5C*/"Intelligence + 5\n"); 69 | } 70 | } 71 | 72 | /*fountain*/ 73 | C_B863() 74 | { 75 | int bp_02; 76 | 77 | u4_puts(/*D_2EAE*/"You find a Fountain.\n"); 78 | if((bp_02 = AskChara(/*D_2EC4*/"Who drinks?\x12\x12\b")) < 0) 79 | return; 80 | if(!isCharaConscious(bp_02)) { 81 | u4_puts(/*D_2ED3*/"\nDisabled!\n"); 82 | return; 83 | } 84 | switch(tile_cur & 0xf) { 85 | case 0: u4_puts(D_2E04[0]); break; 86 | case 1: 87 | if(Party.chara[bp_02]._HP[0] == Party.chara[bp_02]._HP[1]) { 88 | u4_puts(D_2E04[0]); 89 | } else { 90 | u4_puts(/*D_2EDF*/"\nAhh-Refreshing!\n"); 91 | Party.chara[bp_02]._HP[0] = Party.chara[bp_02]._HP[1]; 92 | } 93 | break; 94 | case 2: 95 | u4_puts(/*D_2EF1*/"\nBleck--Nasty!\n"); 96 | C_B730(bp_02, 1); 97 | return; 98 | case 3: 99 | if(Party.chara[bp_02]._stat != 'P') { 100 | u4_puts(D_2E04[0]); 101 | } else { 102 | Party.chara[bp_02]._stat = 'G'; 103 | u4_puts(/*D_2F01*/"\nHmm--Delicious!\n"); 104 | } 105 | break; 106 | case 4: 107 | if(Party.chara[bp_02]._stat == 'P') { 108 | u4_puts(D_2E04[0]); 109 | } else { 110 | Party.chara[bp_02]._stat = 'P'; 111 | u4_puts(/*D_2F13*/"\nArgh-Choke-Gasp!\n"); 112 | C_B730(bp_02, 1); 113 | }; 114 | break; 115 | } 116 | } 117 | 118 | /*found stone*/ 119 | C_B93F() 120 | { 121 | if( 122 | Party._loc == 0x17 || Party._loc == 0x18 || 123 | TST_MSK(Party.mStones, Party._loc - 0x11) 124 | ) { 125 | u4_puts(/*D_2F26*/"\nYou find Nothing!\n"); 126 | return; 127 | } 128 | SET_MSK(Party.mStones, Party._loc - 0x11); 129 | u4_puts(/*D_2F3A*/"\nYou find the "); 130 | u4_puts(D_0884[Party._loc - 0x11]); 131 | u4_puts(/*D_2F49*/" stone!\n"); 132 | karma_inc(&(Party._honor), 5); 133 | XP_inc(0, 200); 134 | } 135 | 136 | /*(S)earch [dungeon]*/ 137 | C_B9B2() 138 | { 139 | u4_puts(/*D_2F52*/"Search...\n"); 140 | switch(tile_cur & 0xf0) { 141 | case 0x70: C_B795(); break; 142 | case 0x90: C_B863(); break; 143 | case 0xB0: C_B93F(); break; 144 | default: u4_puts(/*D_2F5D*/"\nYou find Nothing!\n"); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /SRC/U4_MAIN.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | void cdecl /*C_191E*/main() 14 | { 15 | register unsigned si; 16 | int bp_04; 17 | 18 | low_init(); 19 | C_C51C(); 20 | if(Party._loc >= 0x11 && Party._loc <= 0x18) { 21 | CurMode = MOD_DUNGEON; 22 | if(Load("DNGMAP.SAV", sizeof(tMap8x8x8), &(D_8742._map)) == -1) 23 | exit(3); 24 | File_DNG = dopen(D_0894[Party._loc - 0x11], 0); 25 | if(setjmp(D_9458) == 0) 26 | DNG_main(); 27 | } else { 28 | Party._loc = 0; 29 | } 30 | u_kbflush(); 31 | bp_04 = 0; 32 | for(;;) { 33 | setjmp(D_9458); 34 | t_callback(); 35 | C_9209(); 36 | if(C_10FD()) { 37 | u4_putc(0x10); 38 | u_delay(25, 1); 39 | si = u_kbhit()?u_kbread():KBD_SPACE; 40 | if(u4_isupper((unsigned char)si)) 41 | si = (si & 0xff00) | u4_lower((unsigned char)si); 42 | switch(si) { 43 | case KBD_SPACE: w_Pass(); break; 44 | case 0x487e: 45 | case KBD_UP: CMDDIR_Up(); break; 46 | case 0x4b7c: 47 | case KBD_LEFT: CMDDIR_Left(); break; 48 | case 0x5060: 49 | case KBD_DOWN: CMDDIR_Down(); break; 50 | case 0xf400: 51 | case KBD_RIGHT: CMDDIR_Right(); break; 52 | case KBD_A: CMD_Attack(); break; 53 | case KBD_B: CMD_Board(); break; 54 | case KBD_C: CMD_Cast(); break; 55 | case KBD_D: CMD_Descend(); break; 56 | case KBD_E: CMD_Enter(); break; 57 | case KBD_F: CMD_Fire(); break; 58 | case KBD_G: CMD_Get(); break; 59 | case KBD_H: CMD_HoleUp(); break; 60 | case KBD_I: CMD_Ignite(); break; 61 | case KBD_J: CMD_Jimmy(); break; 62 | case KBD_K: CMD_Klimb(); break; 63 | case KBD_L: CMD_Locate(); break; 64 | case KBD_M: CMD_Mix(); break; 65 | case KBD_N: CMD_NewOrder(); break; 66 | case KBD_O: CMD_Open(); break; 67 | case KBD_P: CMD_Peer(); break; 68 | case KBD_Q: CMD_Quit(); break; 69 | case KBD_R: CMD_Ready(); break; 70 | case KBD_S: CMD_Search(); break; 71 | case KBD_T: CMD_Talk(); break; 72 | case KBD_U: CMD_Use(); break; 73 | case KBD_V: CMD_Volume(); break; 74 | case KBD_W: CMD_Wear(); break; 75 | case KBD_X: CMD_X_it(); break; 76 | case KBD_Y: CMD_Yell(); break; 77 | case KBD_Z: CMD_Ztats(); break; 78 | case KBD_CTRL_S: 79 | if(bp_04 == KBD_ALT_Z) { 80 | C_1C21(); 81 | break; 82 | } 83 | default: 84 | u4_puts("Bad command!\n"); 85 | sound(2); 86 | D_07F8 = 0; 87 | break; 88 | } 89 | } else { 90 | u4_puts("Zzzzz\n"); 91 | } 92 | if(D_07F8 != 0) { 93 | C_1C53(); 94 | } else { 95 | t_callback(); 96 | D_07F8 = 1; 97 | } 98 | bp_04 = si; 99 | } 100 | } 101 | 102 | /*cheat code --> reveal the different levels of karmas*/ 103 | C_1C21() 104 | { 105 | register int si; 106 | 107 | Gra_CR(); 108 | for(si = 0; si < 8; si++) 109 | u4_putl(*(pKarmas[si]), 2, '0'); 110 | Gra_CR(); 111 | } 112 | 113 | C_1C53() 114 | { 115 | register int si; 116 | register struct tChara *di; 117 | 118 | C_10FD(); 119 | /*restore some hull*/ 120 | if(Party._ship < 50 && U4_RND1(3) == 0) 121 | Party._ship ++; 122 | /*S=>G(randomly), P=>takes 2 hit*/ 123 | for(di = Party.chara, si = 0; si < Party.f_1d8; di++, si++) { 124 | if(di->_stat == 'S' && U4_RND1(7) == 0) { 125 | di->_stat = 'G'; 126 | } else if(di->_stat == 'P') { 127 | hitChara(si, 2); 128 | Gra_11(si); sound(6); Gra_11(si); 129 | } 130 | } 131 | /*FOOD management*/ 132 | if(food_dec(Party.f_1d8)) { 133 | u4_puts("\nStarving!!!\n"); 134 | for(si = 0; si < Party.f_1d8; si ++) { 135 | if(isCharaAlive(si)) 136 | hitChara(si, 2); 137 | } 138 | si = Party.f_1d8; 139 | while(--si >= 0) 140 | Gra_11(si); 141 | sound(6); 142 | si = Party.f_1d8; 143 | while(--si >= 0) 144 | Gra_11(si); 145 | } 146 | /* */ 147 | MP_recover(); 148 | if(Party.f_1dc == 0) { 149 | C_7918(); 150 | C_5834(); 151 | C_5851(); 152 | C_7918(); 153 | } 154 | Party._moves ++; 155 | if(spell_cnt) { 156 | if(--spell_cnt == 0) 157 | spell_sta = 7; 158 | } 159 | dspl_Stats(); 160 | /*automatic door closing*/ 161 | C_431D(); 162 | } 163 | -------------------------------------------------------------------------------- /SRC/U4_CSTES.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | char *D_1E98[] = { 8 | /*0 - null*/ 9 | /*D_19F2*/"", 10 | /*1 - sea creatures D_1E9A*/ 11 | /*D_19F3*/"Pirate", 12 | /*D_19FA*/"Pirate", 13 | /*D_1901*/"Nixie", 14 | /*D_1907*/"Squid", 15 | /*D_1A0D*/"Serpent", 16 | /*D_1A15*/"Seahorse", 17 | /*D_1A1E*/"Whirlpool", 18 | /*D_1A28*/"Twister", 19 | /*9 - creatures D_1EAA*/ 20 | /*D_1A30*/"Rat", 21 | /*D_1A34*/"Bat", 22 | /*D_1A38*/"Spider", 23 | /*D_1A3F*/"Ghost", 24 | /*D_1A45*/"Slime", 25 | /*D_1A4B*/"Troll", 26 | /*D_1A51*/"Gremlin", 27 | /*D_1A59*/"Mimic", 28 | /*D_1A5F*/"Reaper", 29 | /*D_1A66*/"Insects", 30 | /*D_1A6E*/"Gazer", 31 | /*D_1A74*/"Phantom", 32 | /*D_1A7C*/"Orc", 33 | /*D_1A80*/"Skeleton", 34 | /*D_1A89*/"Rogue", 35 | /*D_1A8F*/"Python", 36 | /*D_1A96*/"Ettin", 37 | /*D_1A9C*/"Headless", 38 | /*D_1AA5*/"Cyclops", 39 | /*D_1AAD*/"Wisp", 40 | /*D_1AB2*/"Mage", 41 | /*D_1AB7*/"Liche", 42 | /*D_1ABD*/"Lava Lizard", 43 | /*D_1AC9*/"Zorn", 44 | /*D_1ACE*/"Daemon", 45 | /*D_1AD5*/"Hydra", 46 | /*D_1ADB*/"Dragon", 47 | /*D_1AE2*/"Balron", 48 | /*37 - weapons D_1EE2*/ 49 | /*D_1AE9*/"Hands", 50 | /*D_1AEF*/"Staff", 51 | /*D_1AF5*/"Dagger", 52 | /*D_1AFC*/"Sling", 53 | /*D_1B02*/"Mace", 54 | /*D_1B07*/"Axe", 55 | /*D_1B0B*/"Sword", 56 | /*D_1B11*/"Bow", 57 | /*D_1B15*/"Crossbow", 58 | /*D_1B1E*/"Flaming Oil", 59 | /*D_1B2A*/"Halberd", 60 | /*D_1B32*/"Magic Axe", 61 | /*D_1B3C*/"Magic Sword", 62 | /*D_1B48*/"Magic Bow", 63 | /*D_1B52*/"Magic Wand", 64 | /*D_1B5D*/"Mystic Sword", 65 | /*53 - armors D_1F02*/ 66 | /*D_1B6A*/"Skin", 67 | /*D_1B6F*/"Cloth", 68 | /*D_1B75*/"Leather", 69 | /*D_1B7D*/"Chain Mail", 70 | /*D_1B88*/"Plate Mail", 71 | /*D_1B93*/"Magic Chain", 72 | /*D_1B9F*/"Magic Plate", 73 | /*D_1BAB*/"Mystic Robe", 74 | /*61 - weapons short codes D_1F12*/ 75 | /*D_1BB7*/"HND", 76 | /*D_1BBB*/"STF", 77 | /*D_1BBF*/"DAG", 78 | /*D_1BC3*/"SLN", 79 | /*D_1BC7*/"MAC", 80 | /*D_1BCB*/"AXE", 81 | /*D_1BCF*/"SWD", 82 | /*D_1BD3*/"BOW", 83 | /*D_1BD7*/"XBO", 84 | /*D_1BDB*/"OIL", 85 | /*D_1BDF*/"HAL", 86 | /*D_1BE3*/"+AX", 87 | /*D_1BE7*/"+SW", 88 | /*D_1BEB*/"+BO", 89 | /*D_1BEF*/"WND", 90 | /*D_1BF3*/"^SW", 91 | /*77 - classes D_1F32*/ 92 | /*D_1BF7*/"Mage", 93 | /*D_1BFC*/"Bard", 94 | /*D_1C01*/"Fighter", 95 | /*D_1C09*/"Druid", 96 | /*D_1C0F*/"Tinker", 97 | /*D_1C16*/"Paladin", 98 | /*D_1C1E*/"Ranger", 99 | /*D_1C25*/"Shepherd", 100 | /*D_1C2E*/"Guard", 101 | /*D_1C34*/"Merchant", 102 | /*D_1C3D*/"Bard", 103 | /*D_1C42*/"Jester", 104 | /*D_1C49*/"Beggar", 105 | /*D_1C50*/"Child", 106 | /*D_1C56*/"Bull", 107 | /*D_1C5B*/"Lord British", 108 | /*96 - Reagents D_1F52*/ 109 | /*D_1C68*/"Sulfur Ash", 110 | /*D_1C73*/"Ginseng", 111 | /*D_1C7B*/"Garlic", 112 | /*D_1C82*/"Spider Silk", 113 | /*D_1C8E*/"Blood Moss", 114 | /*D_1C99*/"Black Pearl", 115 | /*D_1CA5*/"Nightshade", 116 | /*D_1CB0*/"Mandrake", 117 | /*101 - spells D_1F62*/ 118 | /*D_1CB9*/"Awaken", 119 | /*D_1CC0*/"Blink", 120 | /*D_1CC6*/"Cure", 121 | /*D_1CCB*/"Dispell", 122 | /*D_1CD3*/"Energy", 123 | /*D_1CDA*/"Fireball", 124 | /*D_1CE3*/"Gate", 125 | /*D_1CE8*/"Heal", 126 | /*D_1CED*/"Iceball", 127 | /*D_1CF5*/"Jinx", 128 | /*D_1CFA*/"Kill", 129 | /*D_1CFF*/"Light", 130 | /*D_1D05*/"Magic Misl", 131 | /*D_1D10*/"Negate", 132 | /*D_1D17*/"Open", 133 | /*D_1D1C*/"Protection", 134 | /*D_1D27*/"Quickness", 135 | /*D_1D31*/"Resurrect", 136 | /*D_1D3B*/"Sleep", 137 | /*D_1D41*/"Tremor", 138 | /*D_1D48*/"Undead", 139 | /*D_1D4F*/"View", 140 | /*D_1D54*/"Winds", 141 | /*D_1D5A*/"X-it", 142 | /*D_1D5F*/"Y-up", 143 | /*D_1D64*/"Z-down", 144 | /*127 - locations name D_1F96*/ 145 | /*D_1D6B*/"Britannia", 146 | /*D_1D75*/"The Lycaeum", 147 | /*D_1D81*/"Empath Abbey", 148 | /*D_1D8E*/"Serpents Hold", 149 | /*D_1D9C*/"Moonglow", 150 | /*D_1DA5*/"Britain", 151 | /*D_1DAD*/"Jhelom", 152 | /*D_1DB4*/"Yew", 153 | /*D_1DB8*/"Minoc", 154 | /*D_1DBE*/"Trinsic", 155 | /*D_1DC6*/"Skara Brae", 156 | /*D_1DD1*/"Magincia", 157 | /*D_1DDA*/"Paws", 158 | /*D_1DDF*/"Buccaneers Den", 159 | /*D_1DEE*/"Vesper", 160 | /*D_1DF5*/"Cove", 161 | /*D_1DFA*/"Deceit", 162 | /*D_1E01*/"Despise", 163 | /*D_1E09*/"Destard", 164 | /*D_1E11*/"Wrong", 165 | /*D_1E17*/"Covetous", 166 | /*D_1E20*/"Shame", 167 | /*D_1E26*/"Hythloth", 168 | /*D_1E2F*/"The Great Stygian Abyss!", 169 | /*151 - virtues D_1FC6*/ 170 | /*D_1E48*/"Honesty", 171 | /*D_1E50*/"Compassion", 172 | /*D_1E5B*/"Valor", 173 | /*D_1E61*/"Justice", 174 | /*D_1E69*/"Sacrifice", 175 | /*D_1E73*/"Honor", 176 | /*D_1E79*/"Spirituality", 177 | /*D_1E86*/"Humility", 178 | /*159 - villager D_1FD6*/ 179 | /*D_1E8F*/"Villager" 180 | }; 181 | -------------------------------------------------------------------------------- /forVS/UN_U4TITLE.DSP: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="UN_U4TITLE" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 5.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=UN_U4TITLE - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "UN_U4TITLE.MAK". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "UN_U4TITLE.MAK" CFG="UN_U4TITLE - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "UN_U4TITLE - Win32 Release" (based on\ 21 | "Win32 (x86) Console Application") 22 | !MESSAGE "UN_U4TITLE - Win32 Debug" (based on\ 23 | "Win32 (x86) Console Application") 24 | !MESSAGE 25 | 26 | # Begin Project 27 | # PROP Scc_ProjName "" 28 | # PROP Scc_LocalPath "" 29 | CPP=cl.exe 30 | RSC=rc.exe 31 | 32 | !IF "$(CFG)" == "UN_U4TITLE - Win32 Release" 33 | 34 | # PROP BASE Use_MFC 0 35 | # PROP BASE Use_Debug_Libraries 0 36 | # PROP BASE Output_Dir "Release" 37 | # PROP BASE Intermediate_Dir "Release" 38 | # PROP BASE Target_Dir "" 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir "Release" 42 | # PROP Intermediate_Dir "Release" 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x411 /d "NDEBUG" 47 | # ADD RSC /l 0x411 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "UN_U4TITLE - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "Debug" 60 | # PROP BASE Intermediate_Dir "Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "Debug" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Target_Dir "" 67 | # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 68 | # ADD CPP /nologo /Gz /W3 /Gm /GX /Zi /Od /I "..\SRC-TITLE" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c 69 | # ADD BASE RSC /l 0x411 /d "_DEBUG" 70 | # ADD RSC /l 0x411 /d "_DEBUG" 71 | BSC32=bscmake.exe 72 | # ADD BASE BSC32 /nologo 73 | # ADD BSC32 /nologo 74 | LINK32=link.exe 75 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 76 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | 78 | !ENDIF 79 | 80 | # Begin Target 81 | 82 | # Name "UN_U4TITLE - Win32 Release" 83 | # Name "UN_U4TITLE - Win32 Debug" 84 | # Begin Group "U4_TITLE" 85 | 86 | # PROP Default_Filter "" 87 | # Begin Source File 88 | 89 | SOURCE="..\SRC-TITLE\DATA.C" 90 | # End Source File 91 | # Begin Source File 92 | 93 | SOURCE="..\SRC-TITLE\TITLE_0.C" 94 | # End Source File 95 | # Begin Source File 96 | 97 | SOURCE="..\SRC-TITLE\TITLE_1.C" 98 | # End Source File 99 | # Begin Source File 100 | 101 | SOURCE="..\SRC-TITLE\TITLE_X.C" 102 | # End Source File 103 | # End Group 104 | # Begin Group "U4_TITLE_h" 105 | 106 | # PROP Default_Filter "" 107 | # Begin Source File 108 | 109 | SOURCE="..\SRC-TITLE\TITLE.H" 110 | # End Source File 111 | # Begin Source File 112 | 113 | SOURCE="..\SRC-TITLE\U4_SCAN.H" 114 | # End Source File 115 | # End Group 116 | # Begin Group "lzw" 117 | 118 | # PROP Default_Filter "" 119 | # Begin Source File 120 | 121 | SOURCE=.\lzw.c 122 | # End Source File 123 | # Begin Source File 124 | 125 | SOURCE=.\lzw.h 126 | # End Source File 127 | # End Group 128 | # Begin Source File 129 | 130 | SOURCE=.\common.c 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=.\common.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=.\u4title_main.c 139 | # End Source File 140 | # End Target 141 | # End Project 142 | -------------------------------------------------------------------------------- /SRC/U4_INIT.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | #include 11 | 12 | C_C445() {} 13 | C_C44A() {} 14 | C_C44F() {} 15 | 16 | static int D_9138; 17 | 18 | /*confirmFileInDrive?*/ 19 | C_C454(bp06, bp04) 20 | char *bp06; 21 | char *bp04; 22 | { 23 | int bp_02; 24 | 25 | if(!C_182F(bp04)) { 26 | CurMode = MOD_VISION; 27 | txt_Y = 10; 28 | txt_X = (unsigned int)(40 - strlen(bp06)) >> 1; 29 | u4_puts(bp06); 30 | txt_Y ++; 31 | txt_X = 18; 32 | u4_puts(/*D_3024*/"and"); 33 | txt_Y ++; 34 | txt_X = 11; 35 | u4_puts(/*D_3028*/"press drive letter"); 36 | while(!u_kbhit()); 37 | do { 38 | bp_02 = (unsigned char)u_kbread(); 39 | u4_toupper(bp_02); 40 | if(bp_02 != 'B' || D_9138 != 0) { 41 | if(bp_02 >= 'A' && bp_02 <= 'P') { 42 | bp_02 &= 0xf; 43 | C_181D(bp_02); 44 | } 45 | } 46 | if(C_1814() == bp_02 && C_182F(bp04)) 47 | return; 48 | sound(1); 49 | while(!u_kbhit()); 50 | } while(1); 51 | } 52 | } 53 | 54 | #define NPARAM (far_psp->_80[0]) 55 | #define PARAM0 (far_psp->_80[2]) 56 | #define PARAM1 (far_psp->_80[4]) 57 | 58 | C_C51C() 59 | { 60 | int bp_02, bp_04; 61 | 62 | u4_toupper(PARAM1); 63 | u4_toupper(PARAM0); 64 | /*set drive number*/ 65 | if(NPARAM < 4) { 66 | D_9138 = ((equip_flags & 0xc0) >> 6)?1:0; 67 | PARAM1 = D_9138 + '0'; 68 | } else if (PARAM1 == '0') { 69 | D_9138 = 0; 70 | } else if (PARAM1 == '1') { 71 | D_9138 = 1; 72 | } else { 73 | D_9138 = ((equip_flags & 0xc0) >> 6)?1:0; 74 | } 75 | /*set graphic type*/ 76 | if(NPARAM < 2) { 77 | D_943A = low_gra(); 78 | } else if(PARAM0 == 'C') { 79 | D_943A = 1; 80 | } else if(PARAM0 == 'E') { 81 | D_943A = 2; 82 | } else if(PARAM0 == 'T') { 83 | D_943A = 3; 84 | } else { 85 | D_943A = low_gra(); 86 | } 87 | /* */ 88 | pShapes = dalloc((D_943A == 1)?0x4000:0x8000); 89 | pCharset = dalloc((D_943A == 1)?0x0800:0x1000); 90 | if(pShapes == 0 || pCharset == 0) 91 | exit(3); 92 | if(Load((D_943A == 1)?/*D_303B*/"CHARSET.CGA":/*D_3047*/"CHARSET.EGA", (D_943A == 1)?0x0800:0x1000, pCharset) == -1) 93 | exit(3); 94 | if(D_943A == 1) { 95 | if(Load(/*D_3053*/"SHAPES.CGA", 0x4000, pShapes) == -1) 96 | exit(3); 97 | } 98 | bp_02 = C_1814(); 99 | switch(D_943A) { 100 | case 1: 101 | dfree(patch_tandy); 102 | patch_tandy = 0; 103 | C_20C1(/*D_305E*/"CGA.DRV"); 104 | break; 105 | case 2: 106 | dfree(patch_tandy); 107 | patch_tandy = 0; 108 | C_20C1(/*D_3066*/"EGA.DRV"); 109 | break; 110 | case 3: 111 | C_20C1(/*D_306E*/"TANDY.DRV"); 112 | break; 113 | case -1: 114 | Console(/*D_3078*/"I can't find a color graphics card.\r\n"); 115 | exit(2); 116 | break; 117 | } 118 | bp_04 = C_184F();/*piracy check function ?*/ 119 | Gra_init(&pShapes, &pCharset, exit); 120 | if(D_943A == 2) 121 | sizzleCharset(); 122 | C_18A2(); 123 | if(D_943A == 1) 124 | speed_info ++; 125 | Gra_clrscr(); 126 | if(PARAM1 >= (char)'A' && PARAM1 <= (char)'P') { 127 | if(C_1814() == (PARAM1 & 0x0f)) { 128 | C_C454(/*D_30A8*/"Re-Insert PLAYER Disk", /*D_309E*/"WORLD.MAP"); 129 | } else { 130 | C_181D((unsigned char)PARAM1 & 0x0f); 131 | } 132 | } 133 | C_C454(/*D_30C8*/"Insert PLAYER disk", /*D_30BE*/"WORLD.MAP"); 134 | if(D_943A != 1) { 135 | if(Load(/*D_30DB*/"SHAPES.EGA", 0x8000, pShapes) == -1) 136 | exit(3); 137 | } 138 | if(D_943A == 2) 139 | sizzleShapes(); 140 | if(Load(/*D_30E6*/"PARTY.SAV", sizeof(struct tParty), &Party) == -1) 141 | exit(3); 142 | #if 0/*def WIN32*/ 143 | /*for debug*/ 144 | Party._x = 0x5b; Party._y = 0x44; 145 | #endif 146 | if(Party.f_1d8 == 0) { 147 | Gra_clrscr(); 148 | txt_Y = 8; 149 | txt_X = 12; 150 | u4_puts(/*D_30F0*/"No party formed!"); 151 | sound(8); 152 | u_delay(3, 0); 153 | u_kbflush(); 154 | if(bp_02 == C_1814()) { 155 | C_C454(/*D_310B*/"Re-Insert PROGRAM Disk", /*D_3010*/"TITLE.EXE"); 156 | } else { 157 | C_181D(bp_02); 158 | C_C454(/*D_312C*/"Insert PROGRAM disk", /*D_3122*/"TITLE.EXE"); 159 | } 160 | low_clean(); 161 | exit(4); 162 | } 163 | if(Load(/*D_3140*/"MONSTERS.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) 164 | exit(3); 165 | if((File_MAP = dopen(/*D_314D*/"WORLD.MAP", 0)) == -1) { 166 | Console(/*D_3157*/"Can't open map file\r\n"); 167 | exit(3); 168 | } 169 | File_TLK = 0; 170 | D_9445 = D_0814[Party._trammel]; 171 | D_9448 = D_081C[Party._felucca]; 172 | C_213B();/*draw game screen frame*/ 173 | Gra_CR(); 174 | spell_sta = 7; 175 | spell_cnt = 0; 176 | D_9440 = (Party.f_1dc == 0);/*flying status*/ 177 | D_95C6 = 0; 178 | CurMode = MOD_OUTDOORS; 179 | WindDir = DIR_N; 180 | SoundFlag = 1; 181 | dspl_Stats(); 182 | C_26B6(); 183 | } 184 | -------------------------------------------------------------------------------- /SRC/U4_COMBB.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | /*---------------------------------------- 10 | Whirlpool and Twister management? 11 | ----------------------------------------*/ 12 | 13 | /*remove monster?*/ 14 | C_7821(si/*bp06*/, bp04) 15 | register int si; 16 | int bp04; 17 | { 18 | register int di; 19 | 20 | for(di = 31; di >= 0; di --) { 21 | if( 22 | di != si && 23 | D_8742._npc._tile[di] && 24 | D_8742._npc._x[di] == D_8742._npc._x[si] && 25 | D_8742._npc._y[di] == D_8742._npc._y[si] 26 | ) { 27 | D_8742._npc._tile[di] = D_8742._npc._gtile[di] = 0; 28 | t_callback(); 29 | sound(bp04); 30 | } 31 | } 32 | } 33 | 34 | /*whirlpool contact?*/ 35 | C_786F(si/*bp04*/) 36 | register int si; 37 | { 38 | if(Party._x == D_8742._npc._x[si] && Party._y == D_8742._npc._y[si]) { 39 | t_callback(); 40 | hit_y = hit_x = 5; 41 | hit_tile = TIL_8C; 42 | C_36C7(); 43 | Party._x = 0x7f; 44 | Party._y = 0x4e; 45 | sound(11); 46 | C_1584(); 47 | Party._tile = TIL_10; 48 | hit_tile = 0; 49 | C_26B6(); 50 | } 51 | C_7821(si, 11); 52 | } 53 | 54 | /*twister contact?*/ 55 | C_78D1(si/*bp04*/) 56 | register int si; 57 | { 58 | if(Party._x == D_8742._npc._x[si] && Party._y == D_8742._npc._y[si]) { 59 | t_callback(); 60 | sound(12); 61 | C_1584(); 62 | C_1584(); 63 | C_1584(); 64 | C_1584(); 65 | hit_tile = 0; 66 | } 67 | C_7821(si, 12); 68 | } 69 | 70 | C_7918() 71 | { 72 | register int si; 73 | 74 | if(CurMode != MOD_OUTDOORS) 75 | return; 76 | 77 | for(si = 3; si >= 0; si--) { 78 | if(D_8742._npc._tile[si] == TIL_8C) 79 | C_786F(si); 80 | else if(D_8742._npc._tile[si] == TIL_8E) 81 | C_78D1(si); 82 | } 83 | } 84 | 85 | /*---------------------------------------- 86 | 87 | ----------------------------------------*/ 88 | 89 | /*C_794D*/w_SameExit() 90 | { 91 | u4_puts(/*D_239E*/"All must use same exit!\n"); 92 | sound(1); 93 | } 94 | 95 | /*exit combat zone*/ 96 | C_7962() 97 | { 98 | Combat._charaX[activeChara] = Combat._charaY[activeChara] = 0x80; 99 | Fighters._chtile[activeChara] = 0; 100 | sound(8); 101 | if(CurMode == MOD_COMBAT && !C_0AFE(D_96F8) && Party.chara[activeChara]._HP[0] == Party.chara[activeChara]._HP[1]) { 102 | karma_dec(&(Party._valor), 2); 103 | karma_dec(&(Party._sacri), 2); 104 | } 105 | } 106 | 107 | /*exiting fight*/ 108 | C_79C9(bp06, bp04) 109 | unsigned char bp06; 110 | unsigned char bp04; 111 | { 112 | if(CurMode == MOD_COM_ROOM) { 113 | /*-- dungeon room --*/ 114 | /*someone already exited W/E*/ 115 | if(D_96EE != 0) { 116 | if(bp06 != (unsigned char)D_96EE) { 117 | w_SameExit(); 118 | return; 119 | } 120 | C_7962(); 121 | return; 122 | } 123 | /*someone already exited N/S*/ 124 | if(D_96F4 != 0) { 125 | if(bp04 != (unsigned char)D_96F4) { 126 | w_SameExit(); 127 | return; 128 | } 129 | C_7962(); 130 | return; 131 | } 132 | /*-- --*/ 133 | if(bp06 > 10) 134 | D_96EE = bp06; 135 | else 136 | D_96F4 = bp04; 137 | } 138 | C_7962(); 139 | } 140 | 141 | /*room special tiles*/ 142 | C_7A15(bp06, bp04) 143 | unsigned char bp06; 144 | unsigned char bp04; 145 | { 146 | register int /*si*/loc_A; 147 | int loc_B, loc_C/*bp_04, bp_06*/; 148 | 149 | for(loc_A = 3; loc_A >= 0; loc_A --) { 150 | if(D_95B2[(loc_A << 2)]) { 151 | if( 152 | (bp06 << 12) == (*(U16 *)(D_95B2+(loc_A << 2)) & 0xf000) && 153 | (bp04 << 8) == (*(U16 *)(D_95B2+(loc_A << 2)) & 0x0f00) 154 | ) { 155 | loc_B = *(U16 *)(D_95B2+(loc_A << 2)+2) & 0xf; 156 | if( 157 | loc_B | 158 | (loc_C = (*(U16 *)(D_95B2+(loc_A << 2)+2) >> 4) & 0xf) 159 | ) Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; 160 | loc_B = (*(U16 *)(D_95B2+(loc_A << 2)+2) >> 8) & 0xf; 161 | if( 162 | loc_B | 163 | (loc_C = (*(U16 *)(D_95B2+(loc_A << 2)+2) >> 12) & 0xf) 164 | ) Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)] & 0xff; 165 | } 166 | } 167 | } 168 | } 169 | 170 | /*move [fight]*/ 171 | C_7AE3(si/*bp08*/, bp06, bp04) 172 | register int si; 173 | unsigned char bp06; 174 | unsigned char bp04; 175 | { 176 | register unsigned char *di; 177 | 178 | sound(0); 179 | /*-- out of bounds=>exiting*/ 180 | if((unsigned)bp06 > 10 || (unsigned)bp04 > 10) { 181 | C_79C9(bp06, bp04); 182 | return; 183 | } 184 | di = &(D_96F9[bp04*11 + bp06]); 185 | if(!C_2999(*di)) { 186 | w_Blocked(); 187 | return; 188 | } 189 | if(C_29EF(*di)) { 190 | w_SlowProgress(); 191 | return; 192 | } 193 | Combat._charaX[si] = bp06; 194 | Combat._charaY[si] = bp04; 195 | sound(0); 196 | if(CurMode == MOD_COM_ROOM) 197 | C_7A15(bp06, bp04); 198 | } 199 | 200 | /*North [combat]*/ 201 | C_7B89() 202 | { 203 | u4_puts(/*D_23B7*/"North\n"); 204 | C_7AE3(activeChara, Combat._charaX[activeChara], Combat._charaY[activeChara] - 1); 205 | } 206 | 207 | /*South [combat]*/ 208 | C_7BAF() 209 | { 210 | u4_puts(/*D_23BE*/"South\n"); 211 | C_7AE3(activeChara, Combat._charaX[activeChara], Combat._charaY[activeChara] + 1); 212 | } 213 | 214 | /*East [combat]*/ 215 | C_7BD5() 216 | { 217 | u4_puts(/*D_23C5*/"East\n"); 218 | C_7AE3(activeChara, Combat._charaX[activeChara] + 1, Combat._charaY[activeChara]); 219 | } 220 | 221 | /*West [combat]*/ 222 | C_7BFD() 223 | { 224 | u4_puts(/*D_23CB*/"West\n"); 225 | C_7AE3(activeChara, Combat._charaX[activeChara] - 1, Combat._charaY[activeChara]); 226 | } 227 | -------------------------------------------------------------------------------- /SRC/U4_GET.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | C_70CE(bp04) 10 | int bp04; 11 | { 12 | C_09D9(bp04); 13 | hitChara(bp04, U4_RND3(30)); 14 | } 15 | 16 | C_70F1() 17 | { 18 | register int si; 19 | 20 | u4_puts(/*D_2240*/"The Chest Holds:\n"); 21 | si = U4_RND3(80) + U4_RND1(7) + 10; 22 | u4_putl(si, 1, ' '); 23 | u4_puts(/*D_2252*/" Gold\n"); 24 | Party._gold = (Party._gold + si <= 9999)?Party._gold + si:9999; 25 | } 26 | 27 | /*trapped chest ?*/ 28 | C_7150(bp04) 29 | int bp04; 30 | { 31 | register unsigned si; 32 | 33 | if(((si = U4_RND1(3))&1) == 0) { 34 | /*note:si's bit 0 is always reset when reaching here, 35 | therefore, Sleep or Poison trap never occur.*/ 36 | si &= u_rand_a(); 37 | if(si == 0) 38 | u4_puts(/*D_2259*/"Acid"); 39 | else if(si == 1) 40 | u4_puts(/*D_225E*/"Sleep"); 41 | else if(si == 2) 42 | u4_puts(/*D_2264*/"Poison"); 43 | else 44 | u4_puts(/*D_226B*/"Bomb"); 45 | u4_puts(/*D_2270*/" Trap!\n"); 46 | if(bp04 == -1 || U4_RND3(100) <= Party.chara[bp04]._dex + 25) { 47 | u4_puts(/*D_2278*/"Evaded!\n"); 48 | sound(8); 49 | } else if(si == 0) {/*Acid*/ 50 | C_70CE(bp04); 51 | } else if(si == 1) {/*Sleep*/ 52 | Party.chara[bp04]._stat = 'S'; 53 | if(CurMode >= MOD_COMBAT) 54 | Fighters._chtile[bp04] = TIL_38; 55 | C_09D9(bp04); 56 | } else if(si == 2) {/*Poison*/ 57 | Party.chara[bp04]._stat = 'P'; 58 | dspl_Stats(); 59 | C_09D9(bp04); 60 | } else {/*Bomb*/ 61 | C_1584(); 62 | } 63 | } 64 | C_70F1(); 65 | } 66 | 67 | C_722F(bp04) 68 | int bp04; 69 | { 70 | if(CurMode == MOD_DUNGEON) { 71 | if(tile_cur != 0x40) { 72 | w_NotHere(); 73 | return; 74 | } 75 | D_8742._map.x8x8x8[Party._z][Party._y][Party._x] = 0; 76 | } else { 77 | if(tile_cur != TIL_3C) { 78 | w_NotHere(); 79 | return; 80 | } 81 | if(Party._loc != 0 && D_8742._map.x32x32[Party._y][Party._x] == TIL_3C) { 82 | D_8742._map.x32x32[Party._y][Party._x] = TIL_3E; 83 | karma_dec(&(Party._hones), 1); 84 | karma_dec(&(Party._justi), 1); 85 | karma_dec(&(Party._honor), 1); 86 | } else { 87 | register int si; 88 | 89 | for(si = 0x1f; si >= 0; si --) 90 | if( 91 | D_8742._npc._tile[si] == TIL_3C && 92 | Party._x == D_8742._npc._x[si] && 93 | Party._y == D_8742._npc._y[si] 94 | ) break; 95 | D_8742._npc._tile[si] = D_8742._npc._gtile[si] = 0; 96 | } 97 | } 98 | C_7150(bp04); 99 | } 100 | 101 | /*C_72EC*/CMD_Get() 102 | { 103 | register int si; 104 | 105 | if(Party.f_1dc != 0 && Party._tile == TIL_18) { 106 | u4_puts(/*D_2281*/"Get chest\n"); 107 | w_DriftOnly(); 108 | return; 109 | } 110 | u4_puts(/*D_228C*/"Get Chest!\n"); 111 | if((si = AskChara(/*D_2298*/"Who opens?\x12\x12\b")) < 0) 112 | return; 113 | if(!isCharaConscious(si)) { 114 | w_Disabled(); 115 | return; 116 | } 117 | C_722F(si); 118 | } 119 | 120 | C_7337() 121 | { 122 | if(Combat_MAP(Combat._charaY[activeChara], Combat._charaX[activeChara]) != TIL_3C) { 123 | w_NotHere(); 124 | return; 125 | } 126 | Combat_MAP(Combat._charaY[activeChara], Combat._charaX[activeChara]) = TIL_16; 127 | if(D_8742._map.x8x8x8[Party._z][Party._y][Party._x] == 0x40) 128 | D_8742._map.x8x8x8[Party._z][Party._y][Party._x] = 0; 129 | C_7150(activeChara); 130 | } 131 | 132 | /*(G)et chest [combat]*/ 133 | C_73B8() 134 | { 135 | u4_puts(/*D_22A6*/"Get Chest!\n"); 136 | C_7337(); 137 | } 138 | 139 | /*---------------------------------------- 140 | FIRE 141 | ----------------------------------------*/ 142 | 143 | char D_22C8[] = "Broadsides Only!\n"; 144 | 145 | /*C_73C9*/CMD_Fire() 146 | { 147 | int loc_A, loc_B, loc_C, loc_D, loc_E, loc_F; 148 | 149 | u4_puts(/*D_22B2*/"Fire "); 150 | if(Party._tile < TIL_10 || Party._tile > TIL_13) { 151 | w_What(); 152 | return; 153 | } 154 | u4_puts(/*D_22B8*/"Cannon!\n"); 155 | AskDir(/*D_22C1*/"Dir: ", &loc_C, &loc_D); 156 | if(!(loc_C|loc_D)) 157 | return; 158 | if(loc_C != 0) { 159 | if(Party._tile != TIL_11 && Party._tile != TIL_13) { 160 | u4_puts(D_22C8); 161 | sound(2); 162 | return; 163 | } 164 | } else if(Party._tile != TIL_10 && Party._tile != TIL_12) { 165 | u4_puts(D_22C8); 166 | sound(2); 167 | return; 168 | } 169 | /*-- FIRING --*/ 170 | sound(3); 171 | loc_F = Party._x + loc_C; 172 | loc_B = Party._y + loc_D; 173 | hit_x = loc_C + 5; 174 | hit_y = loc_D + 5; 175 | hit_tile = TIL_4D; 176 | for(loc_E = 1; ; loc_E++) { 177 | if(loc_E > 3 || ( 178 | ((loc_A = C_0A58(0x1f, loc_F, loc_B)) != -1) && 179 | (D_8742._npc._tile[loc_A] != TIL_8C && D_8742._npc._tile[loc_A] != TIL_18) 180 | )) { 181 | hit_tile = 0; 182 | if(loc_A == -1) 183 | return; 184 | /*-- HIT SOMETHING --*/ 185 | hit_tile = TIL_4F; C_36C7(); hit_tile = 0; 186 | sound(6); 187 | if(loc_A < 8 && U4_RND1(3)) 188 | return; 189 | if(D_8742._npc._tile[loc_A] == TIL_5E) 190 | return; 191 | break; 192 | } 193 | C_36C7(); 194 | hit_x += loc_C; loc_F += loc_C; 195 | hit_y += loc_D; loc_B += loc_D; 196 | loc_A = -1; 197 | } 198 | D_8742._npc._tile[loc_A] = D_8742._npc._gtile[loc_A] = 0; 199 | } 200 | 201 | /*---------------------------------------- 202 | IGNITE 203 | ----------------------------------------*/ 204 | 205 | /*C_7525*/CMD_Ignite() 206 | { 207 | u4_puts(/*D_22DA*/"Ignite Torch!\n"); 208 | if(CurMode != MOD_DUNGEON) { 209 | w_NotHere(); 210 | return; 211 | } 212 | if(Party._torches == 0) { 213 | w_NoneLeft(); 214 | return; 215 | } 216 | Party._torches --; 217 | Party.f_1dc += 100; 218 | if(CurMode == MOD_DUNGEON) 219 | C_AE41(); 220 | } 221 | -------------------------------------------------------------------------------- /SRC/U4_SHRIN.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | #include 11 | 12 | /*---- mantras*/ 13 | char *D_8322[] = { 14 | /*D_7B62*/"ahm", 15 | /*D_7B66*/"mu", 16 | /*D_7B69*/"ra", 17 | /*D_7B6C*/"beh", 18 | /*D_7B70*/"cah", 19 | /*D_7B74*/"summ", 20 | /*D_7B79*/"om", 21 | /*D_7B7C*/"lum" 22 | }; 23 | /*---- visions*/ 24 | char *D_8332[][3] = { 25 | { 26 | /*D_7B80*/"Take not the gold of others found in towns and castles for yours it is not!\n", 27 | /*D_7BCD*/"Cheat not the merchants and peddlers for tis an evil thing to do!\n", 28 | /*D_7C10*/"Second, read the Book of Truth at the entrance to the Great Stygian Abyss!\n", 29 | }, { 30 | /*D_7C5C*/"Kill not the non-evil beasts of the land, and do not attack the fair people!\n", 31 | /*D_7CAA*/"Give of thy purse to those who beg and thy deed shall not be forgotten!\n", 32 | /*D_7CF3*/"Third, light the Candle of Love at the entrance to the Great Stygian Abyss!\n", 33 | }, { 34 | /*D_7D40*/"Victories scored over evil creatures help to build a valorous soul!\n", 35 | /*D_7D85*/"To flee from battle with less than grievous wounds often shows a coward!\n", 36 | /*D_7DCF*/"First, ring the Bell of Courage at the entrance to the Great Stygian Abyss!\n", 37 | }, { 38 | /*D_7E1C*/"To take the gold of others is injustice not soon forgotten. Take only thy due!\n", 39 | /*D_7E6C*/"Attack not a peaceful citizen for that action deserves strict punishment!\n", 40 | /*D_7EB7*/"Kill not a non-evil beast for they deserve not death, even if in hunger they attack thee!", 41 | }, { 42 | /*D_7F11*/"To give thy last gold piece unto the needy shows good measure of self-sacrifice!\n", 43 | /*D_7F63*/"For thee to flee and leave thy companions is a self-serving action to be avoided!\n", 44 | /*D_7FB6*/"To give of thy life's blood so that others may live is a virtue of great praise!\n", 45 | }, { 46 | /*D_8008*/"Take not the gold of others for this shall bring dishonor upon thee!\n", 47 | /*D_804E*/"To strike first a non-evil being is by no means an honorable deed!\n", 48 | /*D_8092*/"Seek ye to solve the many Quests before thee, and honor shall be a reward!\n", 49 | }, { 50 | /*D_80DE*/"Seek ye to know thyself. Visit the seer often for he can see into thy inner being!\n", 51 | /*D_8133*/"Meditation leads to enlightenment Seek ye all Wisdom and Knowledge!\n", 52 | /*D_8178*/"If thou dost seek the White Stone, search ye not under the ground, but in Serpent's Spine!\n", 53 | }, { 54 | /*D_81D4*/"Claim not to be that which thou art not. Humble actions speak well of thee!\n", 55 | /*D_8222*/"Strive not to wield the Great Force of Evil for its power will overcome thee!\n", 56 | /*D_8271*/"If thou dost seek the Black Stone, search ye at the Time and Place of the Gate on the darkest of all nights!\n" 57 | } 58 | }; 59 | /*---- visions 2*/ 60 | char *D_8362[] = { 61 | /*D_82DF*/"rune_1",/*I*/ 62 | /*D_82E6*/"rune_2",/*N*/ 63 | /*D_82ED*/"rune_0",/*F*/ 64 | /*D_82F4*/"rune_1",/*I*/ 65 | /*D_82FB*/"rune_2",/*N*/ 66 | /*D_8302*/"rune_1",/*I*/ 67 | /*D_8309*/"rune_3",/*T*/ 68 | /*D_8310*/"rune_4" /*Y*/ 69 | }; 70 | 71 | /*display avatarhood vision I.N.F.I.N.I.T.Y*/ 72 | C_E6DF(bp04) 73 | int bp04; 74 | { 75 | char bp_14[20]; 76 | 77 | CurMode = MOD_VISION; 78 | strcpy(bp_14, D_8362[bp04]); 79 | strcat(bp_14, (D_943A == 1)?/*D_8317*/".pic":/*D_831C*/".ega"); 80 | Gra_10(); 81 | Gra_16(bp_14, 0, 0); 82 | } 83 | 84 | /*enter a shrine*/ 85 | C_E72C() 86 | { 87 | int loc_A, loc_B, loc_C; 88 | char loc_D[16]; 89 | int loc_E; 90 | 91 | loc_A = Party._loc - 0x19;/*shrine "number"*/ 92 | if(!TST_MSK(Party.mRunes, loc_A)) { 93 | u4_puts(/*D_8372*/"\nThou dost not bear the rune of entry! A strange force keeps you out!\n"); 94 | C_E755: 95 | CurMode = MOD_OUTDOORS; 96 | Party._loc = 0; 97 | return; 98 | } 99 | if(Load(/*D_83BA*/"SHRINE.CON", 11 * 11, Combat._map) == -1) 100 | exit(3); 101 | CurMode = MOD_SHRINE; 102 | u4_puts(/*D_83C5*/"\nYou enter the ancient shrine and sit before the altar...\nUpon what virtue dost thou meditate?\n"); 103 | u4_gets(loc_D, 15); 104 | Gra_CR(); 105 | u4_puts(/*D_8425*/"\nFor how many\n"); 106 | loc_E = AskLetter(/*D_8434*/"Cycles (0-3)?\x12\x12\b", '0', '3'); 107 | if(loc_E < 0) { 108 | goto C_E755; 109 | } 110 | loc_E -= '0'; 111 | if(loc_E == 0 || strnicmp(loc_D, D_1E98[151 + loc_A], 16)) { 112 | u4_puts(/*D_8445*/"\nThou art unable to focus thy thoughts on this subject!\n"); 113 | goto C_E755; 114 | } 115 | if(Party._moves / 100 == Party.f_1ea) { 116 | u4_puts(/*D_847E*/"\nThy mind is still weary from thy last Meditation!\n"); 117 | goto C_E755; 118 | } 119 | Party.f_1ea = Party._moves / 100; 120 | u4_puts(/*D_84B2*/"Begin Meditation\n"); 121 | for(loc_B = 0; loc_B < loc_E; loc_B ++) { 122 | for(loc_C = 0; loc_C < 0x10; loc_C ++) { 123 | u_delay(1, 0); 124 | u4_putc('.'); 125 | } 126 | u_kbflush(); 127 | u4_puts(/*D_84C4*/"\nMantra: "); 128 | u4_gets(loc_D, 15); 129 | Gra_CR(); 130 | if(strnicmp(loc_D, D_8322[loc_A], 0x10)) { 131 | u4_puts(/*D_84CE*/"\nThou art not able to focus thy thoughts with that Mantra!\n"); 132 | karma_dec(&(Party._spiri), 3); 133 | goto C_E755; 134 | } 135 | } 136 | if(loc_E != 3 || *(pKarmas[loc_A]) != 99) { 137 | u4_puts(/*D_850A*/"\nThy thoughts are pure. Thou art granted a vision!\n"); 138 | karma_inc(&(Party._spiri), loc_E * 3); 139 | u_kbflush(); 140 | u_kbread(); 141 | Gra_CR(); 142 | u4_puts(D_8332[loc_A][loc_E - 1]); 143 | } else { 144 | u4_puts(/*D_853E*/"\nThou hast achieved partial Avatarhood in the Virtue of\n"); 145 | u4_puts(D_1E98[151 + loc_A]); 146 | Gra_09(); sound(9, 0xff); Gra_09(); 147 | Gra_CR(); 148 | *(pKarmas[loc_A]) = 0; 149 | dspl_Stats(); 150 | u_kbflush(); 151 | u_kbread(); 152 | u4_puts(/*D_8577*/"\n\nThou art granted a vision!\n"); 153 | C_E6DF(loc_A); 154 | u_kbflush(); 155 | } 156 | u_kbread(); 157 | Gra_CR(); 158 | goto C_E755; 159 | } 160 | -------------------------------------------------------------------------------- /SRC/U4_SHAPE.H: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #ifndef __U4_SHAPE_H__ 8 | #define __U4_SHAPE_H__ 9 | 10 | /*deep water*/ 11 | #define TIL_00 0x00 12 | /*medium water*/ 13 | #define TIL_01 0x01 14 | /*shallow water*/ 15 | #define TIL_02 0x02 16 | /*swamp*/ 17 | #define TIL_03 0x03 18 | /*grass*/ 19 | #define TIL_04 0x04 20 | /*scrub*/ 21 | #define TIL_05 0x05 22 | /*forest*/ 23 | #define TIL_06 0x06 24 | /*hills*/ 25 | #define TIL_07 0x07 26 | /*mountains*/ 27 | #define TIL_08 0x08 28 | /*dungeon*/ 29 | #define TIL_09 0x09 30 | /*town*/ 31 | #define TIL_0A 0x0A 32 | /*castle*/ 33 | #define TIL_0B 0x0B 34 | /*village*/ 35 | #define TIL_0C 0x0C 36 | /*LB castle left wing*/ 37 | #define TIL_0D 0x0D 38 | /*LB castle entrance*/ 39 | #define TIL_0E 0x0E 40 | /*LB castle right wing*/ 41 | #define TIL_0F 0x0F 42 | 43 | /*ship W/N/E/S*/ 44 | #define TIL_10 0x10 45 | #define TIL_11 0x11 46 | #define TIL_12 0x12 47 | #define TIL_13 0x13 48 | 49 | /*horse W/E*/ 50 | #define TIL_14 0x14 51 | #define TIL_15 0x15 52 | 53 | /*tiled floor*/ 54 | #define TIL_16 0x16 55 | /*bridge*/ 56 | #define TIL_17 0x17 57 | /*balloon*/ 58 | #define TIL_18 0x18 59 | /**/ 60 | #define TIL_19 0x19 61 | /**/ 62 | #define TIL_1A 0x1A 63 | /*ladder up*/ 64 | #define TIL_1B 0x1B 65 | /*ladder down*/ 66 | #define TIL_1C 0x1C 67 | /*ruins*/ 68 | #define TIL_1D 0x1D 69 | /*shrine*/ 70 | #define TIL_1E 0x1E 71 | /*on foot party*/ 72 | #define TIL_1F 0x1F 73 | 74 | /*====---- 2-tile animation "human" ----====*/ 75 | 76 | /*mage*/ 77 | #define TIL_20 0x20 78 | /*bard*/ 79 | #define TIL_22 0x22 80 | /*fighter*/ 81 | #define TIL_24 0x24 82 | /*druid*/ 83 | #define TIL_26 0x26 84 | /*tinker*/ 85 | #define TIL_28 0x28 86 | /*paladin*/ 87 | #define TIL_2A 0x2A 88 | /*ranger*/ 89 | #define TIL_2C 0x2C 90 | /*shepherd*/ 91 | #define TIL_2E 0x2E 92 | 93 | /*====---- ----====*/ 94 | 95 | #define TIL_30 0x30 96 | #define TIL_31 0x31 97 | #define TIL_32 0x32 98 | #define TIL_33 0x33 99 | #define TIL_34 0x34 100 | #define TIL_35 0x35 101 | #define TIL_36 0x36 102 | #define TIL_37 0x37 103 | /*sleep*/ 104 | #define TIL_38 0x38 105 | /**/ 106 | #define TIL_39 0x39 107 | /*locked door*/ 108 | #define TIL_3A 0x3A 109 | /*door*/ 110 | #define TIL_3B 0x3B 111 | /*chest*/ 112 | #define TIL_3C 0x3C 113 | /*ankh*/ 114 | #define TIL_3D 0x3D 115 | /*brick floor*/ 116 | #define TIL_3E 0x3E 117 | /*wood floor*/ 118 | #define TIL_3F 0x3F 119 | 120 | /*moongate 4 phases*/ 121 | #define TIL_40 0x40 122 | #define TIL_41 0x41 123 | #define TIL_42 0x42 124 | #define TIL_43 0x43 125 | 126 | /*poison field*/ 127 | #define TIL_44 0x44 128 | /*energy field*/ 129 | #define TIL_45 0x45 130 | /*fire field*/ 131 | #define TIL_46 0x46 132 | /*sleep field*/ 133 | #define TIL_47 0x47 134 | 135 | #define TIL_48 0x48 136 | #define TIL_49 0x49 137 | #define TIL_4A 0x4A 138 | #define TIL_4B 0x4B 139 | /*lava*/ 140 | #define TIL_4C 0x4C 141 | /*missile*/ 142 | #define TIL_4D 0x4D 143 | #define TIL_4E 0x4E 144 | #define TIL_4F 0x4F 145 | 146 | /*====---- 2-tile animation NPC ----====*/ 147 | 148 | /*guard*/ 149 | #define TIL_50 0x50 150 | /*merchant*/ 151 | #define TIL_52 0x52 152 | /*bard*/ 153 | #define TIL_54 0x54 154 | /*jester*/ 155 | #define TIL_56 0x56 156 | /*beggar*/ 157 | #define TIL_58 0x58 158 | /*child*/ 159 | #define TIL_5A 0x5A 160 | /*bull*/ 161 | #define TIL_5C 0x5C 162 | /*lord british*/ 163 | #define TIL_5E 0x5E 164 | 165 | /*====---- Alphabet ----====*/ 166 | 167 | #define TIL_60 0x60 168 | #define TIL_61 0x61 169 | #define TIL_62 0x62 170 | #define TIL_63 0x63 171 | #define TIL_64 0x64 172 | #define TIL_65 0x65 173 | #define TIL_66 0x66 174 | #define TIL_67 0x67 175 | #define TIL_68 0x68 176 | #define TIL_69 0x69 177 | #define TIL_6A 0x6A 178 | #define TIL_6B 0x6B 179 | #define TIL_6C 0x6C 180 | #define TIL_6D 0x6D 181 | #define TIL_6E 0x6E 182 | #define TIL_6F 0x6F 183 | #define TIL_70 0x70 184 | #define TIL_71 0x71 185 | #define TIL_72 0x72 186 | #define TIL_73 0x73 187 | #define TIL_74 0x74 188 | #define TIL_75 0x75 189 | #define TIL_76 0x76 190 | #define TIL_77 0x77 191 | #define TIL_78 0x78 192 | #define TIL_79 0x79 193 | /**/ 194 | #define TIL_7A 0x7A 195 | 196 | #define TIL_7B 0x7B 197 | #define TIL_7C 0x7C 198 | #define TIL_7D 0x7D 199 | #define TIL_7E 0x7E 200 | #define TIL_7F 0x7F 201 | 202 | /*====---- 2-tile monsters ----====*/ 203 | 204 | /*pirate*/ 205 | #define TIL_80 0x80 206 | #define TIL_81 0x81 207 | /*pirate*/ 208 | #define TIL_82 0x82 209 | #define TIL_83 0x83 210 | /*nixie*/ 211 | #define TIL_84 0x84 212 | /*squid*/ 213 | #define TIL_86 0x86 214 | /*serpent*/ 215 | #define TIL_88 0x88 216 | /*seahorse*/ 217 | #define TIL_8A 0x8A 218 | /*whirlpool*/ 219 | #define TIL_8C 0x8C 220 | /*twister*/ 221 | #define TIL_8E 0x8E 222 | #define TIL_8F 0x8F 223 | 224 | /*====---- 4-tile monsters ----====*/ 225 | 226 | /*rat*/ 227 | #define TIL_90 0x90 228 | /*bat*/ 229 | #define TIL_94 0x94 230 | /*spider*/ 231 | #define TIL_98 0x98 232 | /*ghost*/ 233 | #define TIL_9C 0x9C 234 | /*slime*/ 235 | #define TIL_A0 0xA0 236 | /*troll*/ 237 | #define TIL_A4 0xA4 238 | /*gremlin*/ 239 | #define TIL_A8 0xA8 240 | /*mimic*/ 241 | #define TIL_AC 0xAC 242 | /*reaper*/ 243 | #define TIL_B0 0xB0 244 | /*insects*/ 245 | #define TIL_B4 0xB4 246 | /*gazer*/ 247 | #define TIL_B8 0xB8 248 | /*phantom*/ 249 | #define TIL_BC 0xBC 250 | /*orc*/ 251 | #define TIL_C0 0xC0 252 | /*skeleton*/ 253 | #define TIL_C4 0xC4 254 | /*rogue*/ 255 | #define TIL_C8 0xC8 256 | /*python*/ 257 | #define TIL_CC 0xCC 258 | /*ettin*/ 259 | #define TIL_D0 0xD0 260 | /*headless*/ 261 | #define TIL_D4 0xD4 262 | /*cyclops*/ 263 | #define TIL_D8 0xD8 264 | /*wisp*/ 265 | #define TIL_DC 0xDC 266 | /*mage*/ 267 | #define TIL_E0 0xE0 268 | /*lyche*/ 269 | #define TIL_E4 0xE4 270 | /*lava lizard*/ 271 | #define TIL_E8 0xE8 272 | #define TIL_E9 0xE9 273 | /*zorn*/ 274 | #define TIL_EC 0xEC 275 | /*daemon*/ 276 | #define TIL_F0 0xF0 277 | /*hydra*/ 278 | #define TIL_F4 0xF4 279 | /*dragon*/ 280 | #define TIL_F8 0xF8 281 | /*balron*/ 282 | #define TIL_FC 0xFC 283 | 284 | #endif 285 | -------------------------------------------------------------------------------- /SRC-TITLE/TITLE.H: -------------------------------------------------------------------------------- 1 | #ifndef __TITLE_H__ 2 | #define __TITLE_H__ 3 | 4 | #ifdef WIN32 5 | #define far 6 | #pragma pack(1) 7 | typedef unsigned short U16; 8 | typedef short S16; 9 | #else 10 | typedef unsigned U16; 11 | typedef int S16; 12 | #endif 13 | 14 | #include "u4_scan.h" 15 | 16 | #define u4_lower(c) ((c) + 'a' - 'A') 17 | #define u4_isupper(c) ((c) >= 'A' && (c) <= 'Z') 18 | #define u4_islower(c) ((c) >= 'a' && (c) <= 'z') 19 | #define u4_toupper(c) if(u4_islower(c)) (c) -= 'a' - 'A' 20 | #define u4_toupper2(c) if(u4_islower(c)) (c) += 'A' - 'a' 21 | #define u4_tolower(c) if(u4_isupper(c)) (c) += 'a' - 'A' 22 | 23 | extern unsigned D_0036; 24 | extern unsigned D_0038; 25 | 26 | struct tPSP { 27 | unsigned char _00[0x80]; 28 | unsigned char _80[0x80]; 29 | }; 30 | 31 | extern struct tPSP far *far_psp;/*D_041C*/ 32 | 33 | extern unsigned /*D_31BC*/cursor_rate; 34 | extern unsigned D_31C0; 35 | 36 | extern unsigned char D_3380[]; 37 | extern unsigned char D_33F8[]; 38 | extern unsigned char D_3438[]; 39 | extern unsigned char D_344A[]; 40 | extern unsigned char D_345C[]; 41 | extern unsigned char D_346E[]; 42 | extern unsigned char D_3683[19*5]; 43 | extern unsigned char D_36E2[]; 44 | 45 | /*====---- ----====*/ 46 | 47 | extern unsigned /*D_692E*/speed_info; 48 | extern unsigned /*D_6931*/equip_flags; 49 | 50 | struct tNPC { 51 | unsigned char _000[32];/*__6D76*/ 52 | unsigned char _020[32];/*__6D96*/ 53 | unsigned char _040[32];/*__6DB6*/ 54 | unsigned char _060[32];/*__6DD6*/ 55 | unsigned char _080[32];/*__6DF6*/ 56 | unsigned char _0A0[32];/*__6E16*/ 57 | unsigned char _0C0[32];/*__6E36*/ 58 | unsigned char _0E0[32];/*__6E56*/ 59 | }; 60 | 61 | typedef unsigned char tMap32x32[32][32]; 62 | typedef unsigned char tMap8x8x8[8][8][8]; 63 | 64 | /* *.ULT/*.DNG */ 65 | struct t_500 { 66 | /*DNGMAP.SAV*/ 67 | union { 68 | tMap8x8x8 x8x8x8; 69 | tMap32x32 x32x32; 70 | } /*__6976.__000*/_map; 71 | /*MONSTERS.SAV/OUTMONST.SAV/*.ULT(last 0x100 bytes)*/ 72 | struct tNPC /*__6D76/__6976.__400*/_npc; 73 | }; 74 | 75 | extern struct t_500 D_6976; 76 | 77 | /*====---- c_common ----====*/ 78 | extern unsigned /*D_6E80*/D_6E80; 79 | 80 | 81 | struct tChara /*size:0x27*/ { 82 | /*+00*/U16 _HP[2]; 83 | /*+04*/U16 _XP; 84 | /*+06*/U16 _str; 85 | /*+08*/U16 _dex; 86 | /*+0a*/U16 _int; 87 | /*+0c*/U16 _MP; 88 | /*+0e*/char __0e[2]; 89 | /*+10*/U16 _weapon; 90 | /*+12*/U16 _armor; 91 | /*+14*/char _name[16]; 92 | /*+24*/char p_24; 93 | /*+25*/char _class; 94 | /*+26*/char _stat; 95 | }; 96 | 97 | struct tParty /*size:0x1f6*/ { 98 | /*+000*/unsigned long f_000;/*a counter*/ 99 | /* */ 100 | /*+004*/unsigned long _moves; 101 | /*+008*/struct tChara chara[8]; 102 | /*+140*/long _food; 103 | /*+144*/U16 _gold; 104 | /*karmas*/ 105 | /*+146*/U16 _hones; 106 | /*+148*/U16 _compa; 107 | /*+14a*/U16 _valor; 108 | /*+14c*/U16 _justi; 109 | /*+14e*/U16 _sacri; 110 | /*+150*/U16 _honor; 111 | /*+152*/U16 _spiri; 112 | /*+154*/U16 _humil; 113 | /* */ 114 | /*+156*/U16 f_156;/*torches*/ 115 | /*+158*/U16 f_158;/*Gems*/ 116 | /*+15a*/U16 f_15a;/*Keys*/ 117 | /*+15c*/U16 f_15c;/*Sextants*/ 118 | /*+15e*/U16 f_15e[8];/*Armors*/ 119 | /*+16e*/U16 f_16e[16];/*Weapons*/ 120 | /*+18e*/U16 f_18e[8];/*Reagents*/ 121 | /*+19e*/U16 f_19e[26];/*Mixtures*/ 122 | /*+1d2*/U16 f_1d2;/*Items mask*/ 123 | /*+1d4,+1d5*/unsigned char _x, _y; 124 | /*+1d6*/unsigned char f_1d6;/*Stones mask*/ 125 | /*+1d7*/unsigned char f_1d7;/*Runes mask*/ 126 | /*+1d8*/U16 f_1d8;/*characters #*/ 127 | /*+1da*/U16 f_1da; 128 | /*+1dc*/U16 f_1dc; 129 | /*+1de/+1e0*/U16 f_1de,f_1e0;/*moons phase*/ 130 | /*+1e2*/U16 f_1e2;/*hull integrity*/ 131 | /*+1e4*/U16 f_1e4;/*did met with LB*/ 132 | /*+1e6*/U16 f_1e6;/*last hole up&camp*/ 133 | /*+1e8*/U16 f_1e8;/*last found*/ 134 | /*+1ea*/U16 f_1ea;/*last meditation/Hawkwind*/ 135 | /*+1ec*/U16 f_1ec;/*last karma-conversation*/ 136 | /*+1ee/+1ef*/unsigned char f_1ee, f_1ef; 137 | /*+1f0*/U16 _dir;/*[dungeon]*/ 138 | /*+1f2*/S16 _z;/*[dungeon]*/ 139 | /*+1f4*/U16 _loc; 140 | }; 141 | 142 | #ifdef WIN32 143 | #pragma pack() 144 | #endif 145 | 146 | extern struct tParty /*D_6E82*/Party; 147 | extern unsigned /*D_7078*/D_7078; 148 | extern void far /*D_707A*/*pShapes; 149 | extern void far /*D_707E*/*pAnim; 150 | extern unsigned /*D_7082*/D_7082; 151 | extern void far /*D_7084*/*pCharset; 152 | extern unsigned /*D_7088*/txt_X; 153 | extern unsigned /*D_708A*/txt_Y; 154 | extern void far /*D_708C*/*pTitle; 155 | /*====---- ----====*/ 156 | 157 | /*====---- ----====*/ 158 | 159 | extern /*C_0010*/Console(char *); 160 | extern /*C_0051*/Load(char *, unsigned, void far *); 161 | extern /*C_0110*/Save(char *, unsigned, void /*far */*); 162 | 163 | extern /*C_027A*/u4_putc(); 164 | 165 | extern cdecl Gra_0( 166 | #if 0 167 | #endif 168 | ); 169 | extern cdecl Gra_dot(); 170 | extern Gra_2(); 171 | extern cdecl Gra_3( 172 | #if 0 173 | int w/*in 8 pixels blocs*/, int h, 174 | int src_x/*in 8 pixels blocs*/, int src_y, 175 | void far *pic_data, 176 | int dst_y, 177 | int rand_pts,/*only works for cga?*/ 178 | int dst_x 179 | #endif 180 | ); 181 | extern cdecl Gra_inflate( 182 | #if 0 183 | #endif 184 | ); 185 | extern Gra_5(); 186 | extern Gra_init(); 187 | extern Gra_animFlow(); 188 | extern Gra_animFlag(); 189 | extern Gra_clrscr(); 190 | extern Gra_putchar(); 191 | extern cdecl Gra_B( 192 | #if 0 193 | int w/*in 8 pixels blocs*/, int h, 194 | int src_x/*in 8 pixels blocs*/, int src_y, 195 | void far *pic_data, 196 | int dst_y, 197 | int rand_pts, 198 | int dst_x 199 | #endif 200 | ); 201 | extern cdecl Gra_C( 202 | #if 0 203 | #endif 204 | ); 205 | extern sizzleShapes(); 206 | extern C_217E(char *, void far *); 207 | 208 | /*low.asm*/ 209 | extern /*C_244E*/low_init(); 210 | extern /*C_2551*/low_clean(); 211 | extern /*C_2583*/low_gra(); 212 | 213 | extern C_3030(); 214 | 215 | extern cdecl /*C_3149*/u_delay(unsigned, unsigned); 216 | extern /*C_31ED*/u_rand_a(); 217 | extern unsigned char /*C_321E*/u_rand_b(); 218 | extern C_3290(); 219 | extern C_3299(); 220 | extern C_32AB(); 221 | extern C_331E(); 222 | 223 | extern C_3F77(unsigned long, unsigned long*); 224 | 225 | #endif 226 | -------------------------------------------------------------------------------- /SRC/U4_DNG.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | /*C_891E(); 10 | C_895F(); 11 | C_899F(); 12 | C_89BD(); 13 | C_89DB(); 14 | C_8A1F(); 15 | C_87E2();*/ 16 | 17 | /*C_84D2*/DNG_main() 18 | { 19 | register unsigned si; 20 | int bp_04; 21 | 22 | D_9446 = 1; 23 | u_kbflush(); 24 | bp_04 = 0; 25 | do { 26 | C_9209(); 27 | u4_putc(0x10); 28 | t_callback(); 29 | if(C_10FD()) { 30 | u_delay(25, 1); 31 | si = u_kbhit()?u_kbread():KBD_SPACE; 32 | if(u4_isupper((unsigned char)si)) 33 | si = (si & 0xff00) | u4_lower((unsigned char)si); 34 | switch(si) { 35 | case KBD_SPACE: w_Pass(); break; 36 | case KBD_UP: 37 | case 0x487e: C_891E(); break; 38 | case KBD_LEFT: 39 | case 0x4b7c: C_899F(); break; 40 | case KBD_DOWN: 41 | case 0x5060: C_895F(); break; 42 | case KBD_RIGHT: 43 | case 0xf400: C_89BD(); break; 44 | case KBD_C: CMD_Cast(); break; 45 | case KBD_D: C_8A1F(); break;/*(D)escend [dungeon]*/ 46 | case KBD_G: CMD_Get(); break; 47 | case KBD_H: CMD_HoleUp(); break; 48 | case KBD_I: CMD_Ignite(); break; 49 | case KBD_K: C_89DB(); break;/*(K)limb [dungeon]*/ 50 | case KBD_M: CMD_Mix(); break; 51 | case KBD_N: CMD_NewOrder(); break; 52 | case KBD_P: CMD_Peer(); break; 53 | case KBD_Q: CMD_Quit(); break; 54 | case KBD_R: CMD_Ready(); break; 55 | case KBD_S: C_B9B2(); break;/*(S)earch [dungeon]*/ 56 | case KBD_U: CMD_Use(); break; 57 | case KBD_V: CMD_Volume(); break; 58 | case KBD_W: CMD_Wear(); break; 59 | case KBD_Z: CMD_Ztats(); break; 60 | case KBD_A: 61 | case KBD_B: 62 | case KBD_E: 63 | case KBD_F: 64 | case KBD_J: 65 | case KBD_L: 66 | case KBD_O: 67 | case KBD_T: 68 | case KBD_X: 69 | case KBD_Y: w_NotHere(); sound(2); break; 70 | case KBD_CTRL_S: 71 | if(bp_04 == KBD_ALT_Z) { 72 | C_1C21(); 73 | break; 74 | } 75 | default: 76 | u4_puts(/*D_2626*/"Bad command\n"); 77 | sound(2); 78 | D_07F8 = 0; 79 | } 80 | C_AE41(); 81 | } else { 82 | u4_puts(/*D_2633*/"Zzzzz\n"); 83 | } 84 | if(D_07F8 != 0 && Party._z >= 0) 85 | C_87E2(); 86 | else 87 | D_07F8 = 1; 88 | bp_04 = si; 89 | } while(Party._z >= 0); 90 | C_2747(); 91 | dclose(File_DNG); 92 | File_DNG = 0; 93 | } 94 | 95 | C_8743() 96 | { 97 | register int si; 98 | 99 | if( 100 | (tile_cur & 0x0f) == 0 || 101 | (tile_cur & 0xf0) == 0x80 || 102 | (tile_cur & 0xf0) == 0x90 || 103 | (tile_cur & 0xf0) == 0xA0 || 104 | (tile_cur & 0xf0) == 0xD0 || 105 | (tile_cur & 0xf0) == 0xF0 106 | ) return 0; 107 | D_96F8 = D_9452 = TIL_90 + (tile_cur & 0x0f) * 4 - 4; 108 | D_8742._map.x8x8x8[Party._z][Party._y][Party._x] &= 0xf0; 109 | for(si = 0x1f; si >= 0; si --) { 110 | if( 111 | D_8742._npc._var[si] == Party._z && 112 | D_8742._npc._x[si] == Party._x && 113 | D_8742._npc._y[si] == Party._y 114 | ) { 115 | D_8742._npc._var[si] = 116 | D_8742._npc._tile[si] = 117 | D_8742._npc._x[si] = 118 | D_8742._npc._y[si] = 0; 119 | break; 120 | } 121 | } 122 | C_7D50(); 123 | 124 | return 1; 125 | } 126 | 127 | C_87E2() 128 | { 129 | register int si; 130 | register struct tChara *di; 131 | 132 | C_10FD(); 133 | for(di = &(Party.chara[0]), si = 0; si < Party.f_1d8; di ++, si++) { 134 | if(di->_stat == 'S' && U4_RND1(7) == 0) { 135 | di->_stat = 'G'; 136 | } else if(di->_stat == 'P') { 137 | hitChara(si, 2); 138 | Gra_11(si); 139 | sound(6); 140 | Gra_11(si); 141 | } 142 | } 143 | if(food_dec(Party.f_1d8)) { 144 | u4_puts(/*D_263A*/"\nStarving!!!\n"); 145 | for(si = 0; si < Party.f_1d8; si++) { 146 | if(isCharaAlive(si)) 147 | hitChara(si, 2); 148 | } 149 | for(si = Party.f_1d8; --si >= 0; ) 150 | Gra_11(si); 151 | sound(6); 152 | for(si = Party.f_1d8; --si >= 0; ) 153 | Gra_11(si); 154 | } 155 | MP_recover(); 156 | C_9414(); 157 | C_95AA(); 158 | if(Party.f_1dc) 159 | Party.f_1dc --; 160 | Party._moves ++; 161 | if(spell_cnt) { 162 | if(--spell_cnt == 0) 163 | spell_sta = 7; 164 | } 165 | if(Party.f_1dc == 0) 166 | u4_puts(/*D_2648*/"It's Dark!\n"); 167 | dspl_Stats(); 168 | if(C_8743() == 0) { 169 | while((tile_cur & 0xf0) == 0xd0) { 170 | C_10FD();/*check death*/ 171 | C_7FFD();/*enter dungeon room*/ 172 | C_B677();/*render 3d*/ 173 | } 174 | } 175 | } 176 | 177 | C_88E8(bp06, bp04) 178 | unsigned char bp06; 179 | unsigned bp04; 180 | { 181 | if(bp04 == 0) { 182 | if( 183 | (bp06 & 0xf0) == 0xc0 || 184 | (bp06 & 0xf0) == 0xe0 || 185 | (bp06 & 0xf0) == 0xd0 186 | ) return 1; 187 | } 188 | if(bp06 != 0xa1 && bp06 < 0xc0) 189 | return 1; 190 | return 0; 191 | } 192 | 193 | /*Advance*/ 194 | C_891E() 195 | { 196 | u4_puts(/*D_2654*/"Advance\n"); 197 | if(!C_88E8(tile_forward, 0)) { 198 | w_Blocked(); 199 | return; 200 | } 201 | Party._x = DNG_X_p(Party._x, Party._dir); 202 | Party._y = DNG_Y_p(Party._y, Party._dir); 203 | } 204 | 205 | /*Retreat*/ 206 | C_895F() 207 | { 208 | u4_puts(/*D_265D*/"Retreat\n"); 209 | if(!C_88E8(tile_back, 1)) { 210 | w_Blocked(); 211 | return; 212 | } 213 | Party._x = DNG_X_m(Party._x, Party._dir); 214 | Party._y = DNG_Y_m(Party._y, Party._dir); 215 | } 216 | 217 | /*Turn Left*/ 218 | C_899F() 219 | { 220 | u4_puts(/*D_2666*/"Turn Left\n"); 221 | Party._dir = (Party._dir - 1) & 3; 222 | D_07F8 = 0; 223 | } 224 | 225 | /*Turn Right*/ 226 | C_89BD() 227 | { 228 | u4_puts(/*D_2671*/"Turn Right\n"); 229 | Party._dir = (Party._dir + 1) & 3; 230 | D_07F8 = 0; 231 | } 232 | 233 | /*(K)limb [dungeon]*/ 234 | C_89DB() 235 | { 236 | u4_puts(/*D_267D*/"Klimb "); 237 | if( 238 | (tile_cur & 0xf0) == 0x10 || 239 | (tile_cur & 0xf0) == 0x30 240 | ) { 241 | u4_puts(/*D_2684*/"up!\n"); 242 | if(--Party._z >= 0) { 243 | u4_puts(/*D_2689*/"To level "); 244 | u4_putc(Party._z + '1'); 245 | Gra_CR(); 246 | } 247 | } else { 248 | w_What(); 249 | } 250 | } 251 | 252 | /*(D)escend [dungeon]*/ 253 | C_8A1F() 254 | { 255 | u4_puts(/*D_2693*/"Descend "); 256 | if( 257 | (tile_cur & 0xf0) == 0x20 || 258 | (tile_cur & 0xf0) == 0x30 259 | ) { 260 | Party._z ++; 261 | u4_puts(/*D_269C*/"down to level "); 262 | u4_putc(Party._z + '1'); 263 | Gra_CR(); 264 | } else { 265 | w_What(); 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /SRC/LOW.ASM: -------------------------------------------------------------------------------- 1 | PUBLIC far_psp 2 | PUBLIC speed_info,equip_flags,patch_tandy 3 | 4 | EXTRN seed_128:BYTE 5 | 6 | EXTRN __psp:WORD 7 | 8 | DGROUP GROUP _DATA,_BSS 9 | ;######################################## 10 | _DATA SEGMENT PUBLIC WORD 'DATA' 11 | ASSUME DS:DGROUP 12 | ;---------------------------------------- 13 | far_psp dw 0,0 ;D_0078 14 | D_007C db "andy" 15 | ;---------------------------------------- 16 | _DATA ENDS 17 | ;######################################## 18 | _BSS SEGMENT PUBLIC WORD 'BSS' 19 | ;---------------------------------------- 20 | D_8720 dw ?,? ;original vector int 0x1c 21 | D_8724 dw ?,? ;original vector int 0x24 22 | speed_info dw ? ;D_8728 23 | D_872A db ? ;original graphic mode 24 | equip_flags dw ? ;D_872B 25 | patch_tandy dw ?,? ;D_872D 26 | db ? ;padding? 27 | ;---------------------------------------- 28 | _BSS ENDS 29 | ;######################################## 30 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 31 | ASSUME CS:_TEXT 32 | ;---------------------------------------- 33 | C_0010 dw 0 34 | PUBLIC low_init ;C_0012 35 | low_init PROC NEAR 36 | PUSH BP 37 | MOV BP,SP 38 | SUB SP,4 39 | ;-- 40 | PUSH ES 41 | ;------------------------- 42 | ;-- Get equipment flags -- 43 | ;------------------------- 44 | INT 11h ;bios equipment flag 45 | MOV CX,AX 46 | MOV equip_flags,AX 47 | ;----------------------- 48 | ;-- Save graphic mode -- 49 | ;----------------------- 50 | MOV AH,0Fh 51 | PUSH BP 52 | INT 10h 53 | POP BP 54 | MOV D_872A,AL 55 | ;-------------------------- 56 | ;-- Create PSP variable -- 57 | ;-------------------------- 58 | MOV AX,__psp 59 | MOV far_psp+2,AX ;transform psp into a far ptr 60 | ;----- 61 | ;-- -- 62 | ;----- 63 | MOV AH,48h ;allocate memory 64 | MOV BX,0FFFFh 65 | INT 21h 66 | SUB BX,400h + 1 67 | MOV [BP-04],BX 68 | ;%% 69 | MOV AH,48h ;allocate memory 70 | INT 21h 71 | MOV [BP-02],AX 72 | ;-- 73 | MOV AH,48h ;allocate memory 74 | MOV BX,400h 75 | INT 21h 76 | MOV patch_tandy+2,AX 77 | MOV BX,50h 78 | MOV ES,BX 79 | MOV BX,10h 80 | MOV ES:[BX],AX ;0050:0010 81 | ;-- 82 | MOV ES,[BP-02] 83 | MOV AH,49h ;free allocated memory 84 | INT 21h 85 | ;------------------ 86 | ;-- Save int 24h -- 87 | ;------------------ 88 | MOV AH,35h 89 | MOV AL,24h 90 | INT 21h 91 | MOV D_8724,BX 92 | MOV D_8724+2,ES 93 | ;---------------------------- 94 | ;-- Reset random generator -- 95 | ;---------------------------- 96 | MOV AH,2Ch 97 | INT 21h 98 | MOV WORD PTR seed_128[0],DX 99 | MOV WORD PTR seed_128[2],CX 100 | MOV WORD PTR seed_128[8],DX 101 | MOV WORD PTR seed_128[0Ah],CX 102 | ;-- 103 | MOV AH,2Ah 104 | INT 21h 105 | MOV WORD PTR seed_128[4],DX 106 | MOV WORD PTR seed_128[6],CX 107 | MOV WORD PTR seed_128[0Ch],DX 108 | MOV WORD PTR seed_128[0Eh],CX 109 | ;-------------------------- 110 | ;-- Check computer speed -- 111 | ;-------------------------- 112 | MOV CS:C_0010,0 113 | ;-- 114 | MOV speed_info,0 115 | ;-- save int 1ch 116 | MOV AH,35h 117 | MOV AL,1Ch 118 | INT 21h 119 | MOV D_8720,BX 120 | MOV D_8720+2,ES 121 | ;-- set new int 1ch 122 | PUSH DS 123 | LEA DX,INT_0141 124 | MOV AX,CS 125 | MOV DS,AX 126 | MOV AH,25h 127 | MOV AL,1Ch 128 | INT 21h 129 | POP DS 130 | ;-- wait for C_0010 to reset 131 | MOV AX,0 132 | C_00C4: CMP CS:C_0010,AX 133 | JZ C_00C4 134 | ;-- 135 | MOV AX,CS:C_0010 136 | C_00CF: INC speed_info 137 | JS C_00EE 138 | MOV DX,[BX+1F40h] 139 | MOV DX,ES:[BX+SI+1F40h] 140 | MOV DX,[BP+SI] 141 | MOV DX,0 142 | MOV CL,14h 143 | RCR DX,CL 144 | CMP CS:C_0010,AX 145 | JZ C_00CF 146 | C_00EE: ;-- restore int 1ch 147 | PUSH DS 148 | MOV AH,25h 149 | MOV AL,1Ch 150 | LDS DX,DWORD PTR D_8720 151 | INT 21h 152 | POP DS 153 | ;-- 154 | MOV DX,0 155 | MOV AX,speed_info 156 | MOV CX,1000 157 | DIV CX 158 | TEST AX,0FFFFh 159 | JNZ C_010D 160 | MOV AX,1 161 | C_010D: MOV speed_info,AX 162 | ;-- 163 | POP ES 164 | ;-- 165 | MOV SP,BP 166 | POP BP 167 | RET 168 | low_init ENDP 169 | ;---- 170 | PUBLIC low_clean ;C_0115 171 | low_clean PROC NEAR 172 | PUSH BP 173 | MOV BP,SP 174 | PUSH ES 175 | ;-------------------------- 176 | ;-- Restore graphic mode -- 177 | ;-------------------------- 178 | MOV AH,0 179 | MOV AL,D_872A 180 | INT 10h 181 | ;----- 182 | ;-- -- 183 | ;----- 184 | TEST patch_tandy+2,0FFFFh 185 | JZ C_0132 186 | ;-- 187 | MOV ES,patch_tandy+2 188 | MOV AH,49h ;free memory ? 189 | INT 21h 190 | JNB C_013E 191 | C_0132: ;--------------------- 192 | ;-- restore int 24h -- 193 | ;--------------------- 194 | PUSH DS 195 | MOV AH,25h 196 | MOV AL,24h 197 | LDS DX,DWORD PTR D_8724 198 | INT 21h 199 | POP DS 200 | C_013E: ;-- 201 | POP ES 202 | POP BP 203 | RET 204 | low_clean ENDP 205 | ;---- 206 | INT_0141: 207 | INC CS:C_0010 208 | IRET 209 | ;---------------------------------------- 210 | ;determine graphic adapter type 211 | PUBLIC low_gra ;C_0147 212 | low_gra PROC NEAR 213 | PUSH SI 214 | PUSH DI 215 | PUSH ES 216 | ;-- check f000:fffe 217 | MOV AX,0F000h 218 | MOV ES,AX 219 | MOV DI,0FFFEh 220 | CMP BYTE PTR ES:[DI],0FDh 221 | MOV AX,1 222 | JZ C_0186 ;is 0xfd? 223 | CMP BYTE PTR ES:[DI],0FFh 224 | JNZ C_01BD 225 | ;-- is 0xff - look for 'Tandy' 226 | MOV DI,0A000h 227 | MOV CX,5FFFh 228 | C_0167: MOV AL,'T' 229 | REPNZ SCASB 230 | JNZ C_01BD 231 | PUSH DI 232 | PUSH CX 233 | MOV CX,4 234 | LEA SI,D_007C ;"andy" 235 | REPZ CMPSB 236 | POP CX 237 | POP DI 238 | JNZ C_0167 ;try next 239 | ;-- return 3 - Tandy? 240 | MOV AX,3 241 | JMP SHORT C_01DD 242 | C_0181: ;-- returns -1 243 | MOV AX,-1 244 | JMP SHORT C_01DD 245 | C_0186: ;-- check b800:0000 246 | MOV AX,0B800h 247 | MOV ES,AX 248 | MOV BX,0 249 | MOV AX,ES:[BX] 250 | MOV WORD PTR ES:[BX],5555h 251 | CMP WORD PTR ES:[BX],5555h 252 | JNZ C_0181 ;returns -1 253 | MOV WORD PTR ES:[BX],0AAAAh 254 | CMP WORD PTR ES:[BX],0AAAAh 255 | JNZ C_0181 ;returns -1 256 | MOV WORD PTR ES:[BX],0D221h 257 | CMP WORD PTR ES:[BX],0D221h 258 | JNZ C_0181 ;returns -1 259 | MOV ES:[BX],AX 260 | ;-- return 1 - cga? 261 | MOV AX,1 262 | JMP SHORT C_01DD 263 | C_01BD: ;-- 264 | MOV AH,12h 265 | MOV BL,10h 266 | MOV CX,0FFFFh 267 | INT 10h 268 | CMP CX,-1 269 | JZ C_0186 270 | MOV AL,BH 271 | AND AX,1 272 | XOR AL,1 273 | CMP AL,0 274 | JZ C_0181 ;returns -1 275 | CMP AL,1 276 | JNZ C_0186 277 | ;-- return 2 - ega? 278 | MOV AX,2 279 | C_01DD: ;-- 280 | POP ES 281 | POP DI 282 | POP SI 283 | RET 284 | low_gra ENDP 285 | ;---------------------------------------- 286 | _TEXT ENDS 287 | ;######################################## 288 | END 289 | -------------------------------------------------------------------------------- /SRC-TITLE/LOW.ASM: -------------------------------------------------------------------------------- 1 | PUBLIC far_psp 2 | PUBLIC speed_info,equip_flags,patch_tandy 3 | 4 | EXTRN seed_128:BYTE 5 | 6 | EXTRN __psp:WORD 7 | 8 | DGROUP GROUP _DATA,_BSS 9 | ;######################################## 10 | _DATA SEGMENT PUBLIC WORD 'DATA' 11 | ASSUME DS:DGROUP 12 | ;---------------------------------------- 13 | far_psp dw 0,0 ;D_041C 14 | D_0420 db "andy" 15 | ;---------------------------------------- 16 | _DATA ENDS 17 | ;######################################## 18 | _BSS SEGMENT PUBLIC WORD 'BSS' 19 | ;---------------------------------------- 20 | D_6926 dw ?,? ;original vector int 0x1c 21 | D_692A dw ?,? ;original vector int 0x24 22 | speed_info dw ? ;D_692E 23 | D_6930 db ? ;original graphic mode 24 | equip_flags dw ? ;D_6931 25 | patch_tandy dw ?,? ;D_6933 26 | db ? ;padding? 27 | ;---------------------------------------- 28 | _BSS ENDS 29 | ;######################################## 30 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 31 | ASSUME CS:_TEXT 32 | ;---------------------------------------- 33 | C_244C dw 0 34 | PUBLIC low_init ;C_244E 35 | low_init PROC NEAR 36 | PUSH BP 37 | MOV BP,SP 38 | SUB SP,4 39 | ;-- 40 | PUSH ES 41 | ;------------------------- 42 | ;-- Get equipment flags -- 43 | ;------------------------- 44 | INT 11h ;bios equipment flag 45 | MOV CX,AX 46 | MOV equip_flags,AX 47 | ;----------------------- 48 | ;-- Save graphic mode -- 49 | ;----------------------- 50 | MOV AH,0Fh 51 | PUSH BP 52 | INT 10h 53 | POP BP 54 | MOV D_6930,AL 55 | ;-------------------------- 56 | ;-- Create PSP variable -- 57 | ;-------------------------- 58 | MOV AX,__psp 59 | MOV far_psp+2,AX ;transform psp into a far ptr 60 | ;----- 61 | ;-- -- 62 | ;----- 63 | MOV AH,48h ;allocate memory 64 | MOV BX,0FFFFh 65 | INT 21h 66 | SUB BX,400h + 1 67 | MOV [BP-04],BX 68 | ;%% 69 | MOV AH,48h ;allocate memory 70 | INT 21h 71 | MOV [BP-02],AX 72 | ;-- 73 | MOV AH,48h ;allocate memory 74 | MOV BX,400h 75 | INT 21h 76 | MOV patch_tandy+2,AX 77 | MOV BX,50h 78 | MOV ES,BX 79 | MOV BX,10h 80 | MOV ES:[BX],AX ;0050:0010 81 | ;-- 82 | MOV ES,[BP-02] 83 | MOV AH,49h ;free allocated memory 84 | INT 21h 85 | ;------------------ 86 | ;-- Save int 24h -- 87 | ;------------------ 88 | MOV AH,35h 89 | MOV AL,24h 90 | INT 21h 91 | MOV D_692A,BX 92 | MOV D_692A+2,ES 93 | ;---------------------------- 94 | ;-- Reset random generator -- 95 | ;---------------------------- 96 | MOV AH,2Ch 97 | INT 21h 98 | MOV WORD PTR seed_128[0],DX 99 | MOV WORD PTR seed_128[2],CX 100 | MOV WORD PTR seed_128[8],DX 101 | MOV WORD PTR seed_128[0Ah],CX 102 | ;-- 103 | MOV AH,2Ah 104 | INT 21h 105 | MOV WORD PTR seed_128[4],DX 106 | MOV WORD PTR seed_128[6],CX 107 | MOV WORD PTR seed_128[0Ch],DX 108 | MOV WORD PTR seed_128[0Eh],CX 109 | ;-------------------------- 110 | ;-- Check computer speed -- 111 | ;-------------------------- 112 | MOV CS:C_244C,0 113 | ;-- 114 | MOV speed_info,0 115 | ;-- save int 1ch 116 | MOV AH,35h 117 | MOV AL,1Ch 118 | INT 21h 119 | MOV D_6926,BX 120 | MOV D_6926+2,ES 121 | ;-- set new int 1ch 122 | PUSH DS 123 | LEA DX,INT_257D 124 | MOV AX,CS 125 | MOV DS,AX 126 | MOV AH,25h 127 | MOV AL,1Ch 128 | INT 21h 129 | POP DS 130 | ;-- wait for C_0010 to reset 131 | MOV AX,0 132 | C_2500: CMP CS:C_244C,AX 133 | JZ C_2500 134 | ;-- 135 | MOV AX,CS:C_244C 136 | C_250B: INC speed_info 137 | JS C_252A 138 | MOV DX,[BX+1F40h] 139 | MOV DX,ES:[BX+SI+1F40h] 140 | MOV DX,[BP+SI] 141 | MOV DX,0 142 | MOV CL,14h 143 | RCR DX,CL 144 | CMP CS:C_244C,AX 145 | JZ C_250B 146 | C_252A: ;-- restore int 1ch 147 | PUSH DS 148 | MOV AH,25h 149 | MOV AL,1Ch 150 | LDS DX,DWORD PTR D_6926 151 | INT 21h 152 | POP DS 153 | ;-- 154 | MOV DX,0 155 | MOV AX,speed_info 156 | MOV CX,1000 157 | DIV CX 158 | TEST AX,0FFFFh 159 | JNZ C_2549 160 | MOV AX,1 161 | C_2549: MOV speed_info,AX 162 | ;-- 163 | POP ES 164 | ;-- 165 | MOV SP,BP 166 | POP BP 167 | RET 168 | low_init ENDP 169 | ;---- 170 | PUBLIC low_clean ;C_2551 171 | low_clean PROC NEAR 172 | PUSH BP 173 | MOV BP,SP 174 | PUSH ES 175 | ;-------------------------- 176 | ;-- Restore graphic mode -- 177 | ;-------------------------- 178 | MOV AH,0 179 | MOV AL,D_6930 180 | INT 10h 181 | ;----- 182 | ;-- -- 183 | ;----- 184 | TEST patch_tandy+2,0FFFFh 185 | JZ C_256E 186 | ;-- 187 | MOV ES,patch_tandy+2 188 | MOV AH,49h ;free allocated memory 189 | INT 21h 190 | JNB C_257A 191 | C_256E: ;--------------------- 192 | ;-- restore int 24h -- 193 | ;--------------------- 194 | PUSH DS 195 | MOV AH,25h 196 | MOV AL,24h 197 | LDS DX,DWORD PTR D_692A 198 | INT 21h 199 | POP DS 200 | C_257A: ;-- 201 | POP ES 202 | POP BP 203 | RET 204 | low_clean ENDP 205 | ;---- 206 | INT_257D: 207 | INC CS:C_244C 208 | IRET 209 | ;---------------------------------------- 210 | ;determine graphic adapter type 211 | PUBLIC low_gra ;C_2583 212 | low_gra PROC NEAR 213 | PUSH SI 214 | PUSH DI 215 | PUSH ES 216 | ;-- check f000:fffe 217 | MOV AX,0F000h 218 | MOV ES,AX 219 | MOV DI,0FFFEh 220 | CMP BYTE PTR ES:[DI],0FDh 221 | MOV AX,1 222 | JZ C_25C2 ;is 0xfd? 223 | CMP BYTE PTR ES:[DI],0FFh 224 | JNZ C_25F9 225 | ;-- is 0xff - look for 'Tandy' 226 | MOV DI,0A000h 227 | MOV CX,5FFFh 228 | C_25A3: MOV AL,'T' 229 | REPNZ SCASB 230 | JNZ C_25F9 231 | PUSH DI 232 | PUSH CX 233 | MOV CX,4 234 | LEA SI,D_0420 ;"andy" 235 | REPZ CMPSB 236 | POP CX 237 | POP DI 238 | JNZ C_25A3 ;try next 239 | ;-- return 3 - Tandy? 240 | MOV AX,3 241 | JMP SHORT C_2619 242 | C_25BD: ;-- returns -1 243 | MOV AX,-1 244 | JMP SHORT C_2619 245 | C_25C2: ;-- check b800:0000 246 | MOV AX,0B800h 247 | MOV ES,AX 248 | MOV BX,0 249 | MOV AX,ES:[BX] 250 | MOV WORD PTR ES:[BX],5555h 251 | CMP WORD PTR ES:[BX],5555h 252 | JNZ C_25BD ;returns -1 253 | MOV WORD PTR ES:[BX],0AAAAh 254 | CMP WORD PTR ES:[BX],0AAAAh 255 | JNZ C_25BD ;returns -1 256 | MOV WORD PTR ES:[BX],0D221h 257 | CMP WORD PTR ES:[BX],0D221h 258 | JNZ C_25BD ;returns -1 259 | MOV ES:[BX],AX 260 | ;-- return 1 - cga? 261 | MOV AX,1 262 | JMP SHORT C_2619 263 | C_25F9: ;-- 264 | MOV AH,12h 265 | MOV BL,10h 266 | MOV CX,0FFFFh 267 | INT 10h 268 | CMP CX,-1 269 | JZ C_25C2 270 | MOV AL,BH 271 | AND AX,1 272 | XOR AL,1 273 | CMP AL,0 274 | JZ C_25BD ;returns -1 275 | CMP AL,1 276 | JNZ C_25C2 277 | ;-- return 2 - ega? 278 | MOV AX,2 279 | C_2619: ;-- 280 | POP ES 281 | POP DI 282 | POP SI 283 | RET 284 | low_gra ENDP 285 | ;---------------------------------------- 286 | _TEXT ENDS 287 | ;######################################## 288 | END 289 | -------------------------------------------------------------------------------- /SRC/U4_PEER.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | unsigned char D_2F72[] = { 10 | 0x0C,0x0B,0x0A,0x01,0x01,0x09,0x02,0x08,0x07,0x05,0x05,0x05,0x05,0x04,0x04,0x04, 11 | 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x04,0x05,0x04,0x04,0x05,0x05,0x06,0x06,0x05, 12 | 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, 13 | 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x05,0x05,0x07,0x06,0x06,0x05,0x00,0x03,0x04, 14 | 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x07,0x03,0x03,0x03,0x03,0x03,0x03, 15 | 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, 16 | 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 17 | 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x00,0x07 18 | }; 19 | 20 | int D_2FF2[] = {0x20, 0x06, 0x05, 0x04, 0x24, 0x20, 0x20, 0x0F, 0x54, 0x46, 0x5E, 0x00, 0x0E, 0x0E, 0x02, 0x03}; 21 | 22 | #define MK_COORD(a, b) (((a)+8)*4 + (b)) 23 | #define PT(x,y,c) Gra_dot(MK_COORD(loc_A,(x)),MK_COORD(loc_C,(y)),(c)); 24 | /*green?*/ 25 | #define PT_1(x,y) PT((x),(y),1) 26 | /*blue?*/ 27 | #define PT_2(x,y) PT((x),(y),2) 28 | /*white?*/ 29 | #define PT_3(x,y) PT((x),(y),3) 30 | 31 | static unsigned char D_8CFC[600]; 32 | static unsigned char D_8F54[22][22]; 33 | 34 | C_B9EF(bp04/*display player pos*/) 35 | unsigned bp04; 36 | { 37 | int loc_A, loc_B, loc_C; 38 | 39 | loc_B = CurMode; CurMode = MOD_VISION; 40 | Gra_10(); 41 | for(loc_A = 0; loc_A < 32; loc_A++) { 42 | for(loc_C = 0; loc_C < 32; loc_C++) { 43 | if(D_8742._map.x32x32[loc_A][loc_C] < 0x80) { 44 | switch(D_2F72[D_8742._map.x32x32[loc_A][loc_C]]) { 45 | case 1:/*grass*/ 46 | PT_1(0,1); 47 | PT_1(1,3); 48 | PT_1(2,1); 49 | PT_1(3,3); 50 | break; 51 | case 2:/*forest*/ 52 | PT_1(0,3); 53 | PT_1(1,1); 54 | PT_1(2,3); 55 | PT_1(3,1); 56 | PT_1(0,1); 57 | PT_1(1,3); 58 | PT_1(2,1); 59 | PT_1(3,3); 60 | break; 61 | case 3:/*lava*/ 62 | PT_2(0,0); 63 | PT_2(1,0); 64 | PT_2(2,0); 65 | PT_2(3,0); 66 | PT_2(0,2); 67 | PT_2(1,2); 68 | PT_2(2,2); 69 | PT_2(3,2); 70 | break; 71 | case 4:/*castle/bridge*/ 72 | PT_3(0,0); 73 | PT_3(0,1); 74 | PT_3(0,2); 75 | PT_3(0,3); 76 | PT_3(3,0); 77 | PT_3(3,1); 78 | PT_3(3,2); 79 | PT_3(3,3); 80 | break; 81 | case 5:/*dungeon/town*//*C_BCA0:*/ 82 | PT_3(1,1); 83 | PT_3(2,1); 84 | PT_3(1,2); 85 | PT_3(2,2); 86 | break; 87 | case 6:/*shrine*/ 88 | PT_3(1,0); 89 | PT_3(2,0); 90 | PT_3(1,3); 91 | PT_3(2,3); 92 | PT_3(0,0); 93 | PT_3(0,1); 94 | PT_3(0,2); 95 | PT_3(0,3); 96 | PT_3(3,0); 97 | PT_3(3,1); 98 | PT_3(3,2); 99 | PT_3(3,3); 100 | break; 101 | case 7:/*mountain*/ 102 | PT_3(1,1); 103 | PT_3(2,1); 104 | PT_3(1,2); 105 | PT_3(2,2); 106 | PT_3(1,0); 107 | PT_3(2,0); 108 | PT_3(1,3); 109 | PT_3(2,3); 110 | PT_3(0,0); 111 | PT_3(0,1); 112 | PT_3(0,2); 113 | PT_3(0,3); 114 | PT_3(3,0); 115 | PT_3(3,1); 116 | PT_3(3,2); 117 | PT_3(3,3); 118 | break; 119 | case 8:/*hill*/ 120 | PT_3(0,0); 121 | PT_3(1,0); 122 | PT_3(0,1); 123 | PT_3(1,1); 124 | PT_3(2,2); 125 | PT_3(3,2); 126 | PT_3(2,3); 127 | PT_3(3,3); 128 | break; 129 | case 9:/*bush*/ 130 | PT_1(0,1); 131 | PT_1(1,1); 132 | PT_1(2,1); 133 | PT_1(0,3); 134 | PT_1(2,3); 135 | PT_1(3,3); 136 | break; 137 | case 10:/*shallow water*/ 138 | PT_2(0,0); 139 | PT_2(2,0); 140 | PT_2(1,2); 141 | PT_2(3,2); 142 | break; 143 | case 11:/*water*/ 144 | PT_2(0,0); 145 | PT_2(2,2); 146 | break; 147 | case 12:/*deep water*/ 148 | PT_3(2*(loc_C&1),2); 149 | break; 150 | } 151 | } else {/*goto C_BCA0;*/ 152 | PT_3(1,1); 153 | PT_3(2,1); 154 | PT_3(1,2); 155 | PT_3(2,2); 156 | } 157 | /*C_BD04*/ 158 | } 159 | } 160 | /*C_BD1C*/ 161 | loc_C = 0; 162 | u_kbflush(); 163 | /*C_C174*/ 164 | for(; !u_kbhit(); loc_C++) { 165 | if(bp04) { 166 | Gra_dot_XOR(MK_COORD(D_959C.y,0), MK_COORD(D_959C.x,loc_C&3), 3); 167 | Gra_dot_XOR(MK_COORD(D_959C.y,1), MK_COORD(D_959C.x,loc_C&3), 3); 168 | Gra_dot_XOR(MK_COORD(D_959C.y,2), MK_COORD(D_959C.x,loc_C&3), 3); 169 | Gra_dot_XOR(MK_COORD(D_959C.y,3), MK_COORD(D_959C.x,loc_C&3), 3); 170 | } 171 | } 172 | u_kbread(); 173 | CurMode = loc_B; 174 | } 175 | #undef PT 176 | #undef MK_COORD 177 | 178 | C_C23B() 179 | { 180 | int loc_A, loc_B; 181 | register unsigned loc_C; 182 | int loc_D, loc_E, loc_F; 183 | 184 | loc_E = CurMode; CurMode = MOD_VISION; 185 | Gra_10(); 186 | txt_Y = 21; do { txt_X = 21; do { 187 | D_8F54[txt_Y][txt_X] = 0; 188 | } while(--txt_X >= 0); } while(--txt_Y >= 0); 189 | 190 | loc_C = 0; 191 | D_8CFC[loc_C++] = txt_Y = 11; 192 | D_8CFC[loc_C++] = txt_X = 11; 193 | D_8CFC[loc_C++] = Party._y; 194 | D_8CFC[loc_C++] = Party._x; 195 | D_8F54[10][10] = 1; 196 | Gra_putchar(0x01); 197 | /*C_C2B5*/ 198 | do { 199 | loc_F = D_8CFC[--loc_C]; 200 | loc_A = D_8CFC[--loc_C]; 201 | txt_X = D_8CFC[--loc_C] - 1; 202 | txt_Y = D_8CFC[--loc_C] - 1; 203 | for(loc_B = -1; loc_B < 2; txt_X ++, txt_Y -= 3, loc_B++) { 204 | /*C_C2E0*/ 205 | for(loc_D = -1; loc_D < 2; txt_Y ++, loc_D++) { 206 | if((loc_B | loc_D)) { 207 | int bp_0e, bp_10; 208 | bp_0e = (loc_B + loc_F) & 7; 209 | bp_10 = (loc_D + loc_A) & 7; 210 | if( 211 | txt_Y < 1 || txt_Y > 22 || 212 | txt_X < 1 || txt_X > 22 || 213 | D_8F54[txt_Y-1][txt_X-1] 214 | ) continue; 215 | /*C_C347*/ 216 | Gra_putchar(D_2FF2[D_8742._map.x8x8x8[Party._z][bp_10][bp_0e] >> 4]); 217 | if((D_8742._map.x8x8x8[Party._z][bp_10][bp_0e] & 0xf0) != 0xf0) { 218 | D_8CFC[loc_C++] = txt_Y; 219 | D_8CFC[loc_C++] = txt_X; 220 | D_8CFC[loc_C++] = bp_10; 221 | D_8CFC[loc_C++] = bp_0e; 222 | if(loc_C >= 600) 223 | loc_C = 0; 224 | D_8F54[txt_Y-1][txt_X-1] = 1; 225 | } 226 | } 227 | /*C_C33E*/ 228 | } 229 | } 230 | } while(loc_C); 231 | txt_Y = 23; 232 | txt_X = 24; 233 | u_kbflush(); 234 | u_kbread(); 235 | CurMode = loc_E; 236 | D_9446 = 1; 237 | } 238 | 239 | C_C403() 240 | { 241 | if(Party._loc >= 0x11) { 242 | C_C23B(); 243 | } else { 244 | C_B9EF(1); 245 | } 246 | } 247 | 248 | /*C_C41D*/CMD_Peer() 249 | { 250 | u4_puts(/*D_3012*/"Peer at "); 251 | if(Party._gems == 0) { 252 | w_What(); 253 | return; 254 | } 255 | u4_puts(/*D_301B*/"a Gem!\n"); 256 | Party._gems --; 257 | C_C403(); 258 | } 259 | -------------------------------------------------------------------------------- /SRC-TITLE/INFLATE.ASM: -------------------------------------------------------------------------------- 1 | EXTRN _open:NEAR 2 | EXTRN _close:NEAR 3 | EXTRN _read:NEAR 4 | EXTRN _lseek:NEAR 5 | EXTRN _malloc:NEAR 6 | EXTRN _free:NEAR 7 | 8 | DGROUP GROUP _BSS 9 | 10 | _BSS SEGMENT PUBLIC WORD 'BSS' 11 | ASSUME DS:DGROUP 12 | 13 | D_3B20 dw ? ;deflated file size 14 | D_3B22 dw ? ;deflated file buffer(pointer) 15 | D_3B24 db ? ;12 bits flag 16 | D_3B25 db ? ;temporary stores 4 bits 17 | D_3B26 dw 0f00h dup(?) 18 | D_5926 db 0f00h dup(?) 19 | D_6826 db 100h dup(?) 20 | 21 | _BSS ENDS 22 | 23 | 24 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 25 | ASSUME CS:_TEXT 26 | 27 | C_21E5 PROC NEAR 28 | PUSH BP 29 | MOV BP,SP 30 | ;-- AX := (bp06 << 4) ^ bp04 31 | MOV CL,4 32 | MOV AX,[BP+06] 33 | SHL AX,CL 34 | XOR AX,[BP+04] 35 | AND AH,0Fh 36 | ;-- 37 | TEST AH,0FFh 38 | JZ C_221C 39 | MOV BX,AX 40 | SHL BX,1 41 | MOV CX,D_3B26[BX - 2*100h] 42 | TEST CX,0FFFFh 43 | JZ C_224B 44 | AND CX,NOT 2000h 45 | CMP CX,[BP+04] 46 | JNZ C_221C 47 | MOV BX,AX 48 | MOV CL,D_5926[BX - 100h] 49 | CMP CL,[BP+06] 50 | JZ C_228E 51 | C_221C: 52 | MOV AX,[BP+06] 53 | SUB AH,AH 54 | SHL AX,1 55 | ADD AX,[BP+04] 56 | OR AX,800h 57 | MUL AX 58 | RCL AX,1 59 | RCL DX,1 60 | RCL AX,1 61 | RCL DX,1 62 | MOV AL,AH 63 | MOV AH,DL 64 | AND AH,0Fh 65 | TEST AH,0FFh 66 | JZ C_2261 67 | MOV BX,AX 68 | SHL BX,1 69 | MOV CX,D_3B26[BX - 2*100h] 70 | TEST CX,0FFFFh 71 | C_224B: 72 | JZ C_228E 73 | AND CX,NOT 2000h 74 | CMP CX,[BP+04] 75 | JNZ C_2261 76 | MOV BX,AX 77 | MOV CL,D_5926[BX - 100h] 78 | CMP CL,[BP+06] 79 | JZ C_228E 80 | C_2261: 81 | ADD AX,1FDh 82 | AND AX,0FFFh 83 | TEST AH,0FFh 84 | JZ C_2261 85 | MOV BX,AX 86 | SHL BX,1 87 | MOV CX,D_3B26[BX - 2*100h] 88 | TEST CX,0FFFFh 89 | JZ C_228E 90 | AND CX,NOT 2000h 91 | CMP CX,[BP+04] 92 | JNZ C_2261 93 | MOV BX,AX 94 | MOV CL,D_5926[BX - 100h] 95 | CMP CL,[BP+06] 96 | JNZ C_2261 97 | C_228E: ;-- 98 | POP BP 99 | RET 100 | C_21E5 ENDP 101 | 102 | ;AX := read 12 bits? 103 | C_2290 PROC NEAR 104 | MOV BX,D_3B22 105 | ;-- AL := read one byte 106 | SUB D_3B20,1 107 | JB C_22C8 ;end of buffer? 108 | MOV AL,[BX] 109 | INC BX 110 | ;-- 111 | TEST D_3B24,0FFh 112 | JNZ C_22BF 113 | ;======================== 114 | ;== read a second byte == 115 | ;== stores 12 bits in == 116 | ;== AX and the remai- == 117 | ;== ning 4 in D_3B25 == 118 | ;======================== 119 | ;-- DL := read one byte 120 | SUB D_3B20,1 121 | JB C_22C8 ;end of buffer? 122 | MOV DL,[BX] 123 | INC BX 124 | ;-- 125 | MOV D_3B25,DL 126 | MOV CL,4 127 | MOV AH,0 128 | SHL AX,CL 129 | SHR DL,CL 130 | OR AL,DL 131 | ;-- 132 | JMP SHORT C_22CB 133 | ;======================== 134 | C_22BF: ;== read only one byte == 135 | ;== use remaining 4 == 136 | ;== bits from D_3B25 == 137 | ;======================== 138 | MOV AH,D_3B25 139 | AND AH,0Fh 140 | ;-- 141 | JMP SHORT C_22CB 142 | ;=================== 143 | C_22C8: ;== end of buffer == 144 | ;=================== 145 | MOV AX,0FFFFh 146 | ;======= 147 | C_22CB: ;== == 148 | ;======= 149 | XOR D_3B24,1 150 | MOV D_3B22,BX 151 | ;-- 152 | RET 153 | C_2290 ENDP 154 | 155 | ;LZW inflate? 156 | ;[Lempel-Ziv-Welch] 157 | C_22D5 PROC NEAR 158 | PUSH BP 159 | MOV BP,SP 160 | SUB SP,8 161 | PUSH SI 162 | PUSH DI 163 | PUSH ES 164 | ;-- 165 | MOV WORD PTR [BP-04],0 166 | MOV D_3B24,0 167 | MOV AX,DS 168 | MOV ES,AX 169 | ;-- 170 | SUB AX,AX 171 | LEA DI,D_3B26 172 | MOV CX,0F00h 173 | REPZ STOSW 174 | ;-- 175 | CALL C_2290 ;AX := read 12 bits? 176 | MOV [BP-06],AX 177 | MOV [BP-08],AX 178 | ;-- 179 | CALL [BP+04] ;callback(AL) 180 | ;*************** 181 | C_2303: ;** main loop ** 182 | ;*************** 183 | CALL C_2290 ;AX := read 12 bits? 184 | MOV [BP-02],AX 185 | ;%% 186 | CMP AX,0FFFFh 187 | JNZ C_2311 188 | JMP C_23BC ;finished! 189 | C_2311: ;-- 190 | TEST AH,0FFh 191 | JZ C_235C 192 | ;======= 193 | ;== == 194 | ;======= 195 | LEA SI,D_6826 196 | MOV BX,AX 197 | SHL BX,1 198 | TEST D_3B26[BX - 2*100h],0FFFFh 199 | JNZ C_232F 200 | MOV AX,[BP-08] 201 | MOV [SI],AL 202 | INC SI 203 | MOV AX,[BP-06] 204 | C_232F: 205 | MOV BX,AX 206 | TEST AH,0FFh 207 | JZ C_2348 208 | MOV AL,D_5926[BX - 100h] 209 | MOV [SI],AL 210 | INC SI 211 | SHL BX,1 212 | MOV AX,D_3B26[BX - 2*100h] 213 | AND AX,NOT 2000h 214 | JMP C_232F 215 | C_2348: ;-- 216 | MOV [BP-08],AX 217 | CALL [BP+04] ;callback(AL) 218 | C_234E: ;-- 219 | DEC SI 220 | MOV AL,[SI] 221 | CALL [BP+04] ;callback(AL) 222 | ;-- 223 | CMP SI,OFFSET DGROUP:D_6826 224 | JNZ C_234E 225 | ;-- 226 | JMP SHORT C_2362 227 | ;======= 228 | C_235C: ;== == 229 | ;======= 230 | CALL [BP+04] ;callback(AL) 231 | MOV [BP-08],AL 232 | ;======= 233 | C_2362: ;== == 234 | ;======= 235 | PUSH [BP-08] 236 | PUSH [BP-06] 237 | CALL C_21E5 238 | ADD SP,4 239 | MOV BX,AX 240 | ;-- 241 | MOV AX,[BP-08] 242 | MOV D_5926[BX - 100h],AL 243 | SHL BX,1 244 | MOV AX,[BP-06] 245 | OR AX,2000h 246 | MOV D_3B26[BX - 2*100h],AX 247 | INC WORD PTR [BP-04] 248 | MOV AX,[BP-04] 249 | CMP AX,0CCCh 250 | JBE C_23B3 251 | MOV AX,DS 252 | MOV ES,AX 253 | MOV WORD PTR [BP-04],0 254 | ;-- 255 | SUB AX,AX 256 | LEA DI,D_3B26 257 | MOV CX,0F00h 258 | REPZ STOSW 259 | ;-- 260 | CALL C_2290 ;AX := read 12 bits? 261 | MOV [BP-02],AX 262 | MOV [BP-08],AX 263 | CMP AX,0FFFFh 264 | JZ C_23BC ;finished! 265 | ;-- 266 | CALL [BP+04] ;callback(AL) 267 | C_23B3: ;-- 268 | MOV AX,[BP-02] 269 | MOV [BP-06],AX 270 | ;-- 271 | JMP C_2303 ;main loop! 272 | C_23BC: ;-- 273 | POP ES 274 | POP DI 275 | POP SI 276 | MOV SP,BP 277 | POP BP 278 | RET 279 | C_22D5 ENDP 280 | 281 | ;load file + inflate(callback)? 282 | ;[bp+04] file name 283 | ;[bp+06] callback(AL) 284 | PUBLIC _C_23C3 285 | _C_23C3 PROC NEAR 286 | PUSH BP 287 | MOV BP,SP 288 | SUB SP,4 289 | ;-- 290 | MOV AX,8000h ;O_BINARY|O_RDONLY 291 | PUSH AX 292 | PUSH [BP+04] 293 | CALL _open 294 | ADD SP,4 295 | ;%% 296 | MOV [BP-02],AX 297 | CMP AX,-1 298 | JZ C_243A ;error 299 | ;** compute file size ** 300 | MOV BX,2 ;SEEK_END 301 | PUSH BX 302 | MOV BX,0 303 | PUSH BX 304 | PUSH BX 305 | PUSH AX ;file handle 306 | CALL _lseek 307 | ADD SP,8 308 | MOV D_3B20,AX 309 | ;** ** 310 | PUSH AX ;file size 311 | CALL _malloc 312 | ADD SP,2 313 | MOV D_3B22,AX 314 | MOV [BP-04],AX 315 | TEST AX,0FFFFh 316 | JZ C_243A ;error 317 | ;-- 318 | MOV AX,0 319 | PUSH AX 320 | PUSH AX 321 | PUSH AX 322 | PUSH [BP-02] 323 | CALL _lseek 324 | ADD SP,8 325 | ;-- 326 | PUSH D_3B20 327 | PUSH D_3B22 328 | PUSH [BP-02] 329 | CALL _read 330 | ADD SP,6 331 | ;-- 332 | PUSH [BP-02] 333 | CALL _close 334 | ADD SP,2 335 | ;-- 336 | PUSH [BP+06] ;callback 337 | CALL C_22D5 ;inflate? 338 | ADD SP,2 339 | ;-- 340 | MOV AX,0 341 | JMP SHORT C_243F ;sould be return but? 342 | C_243A: ;-- error -- 343 | MOV AX,-1 344 | JMP SHORT C_243F ;sould be return but? 345 | C_243F: ;** ** 346 | PUSH [BP-04] 347 | CALL _free 348 | ADD SP,2 349 | ;** ** 350 | MOV SP,BP 351 | POP BP 352 | RET 353 | _C_23C3 ENDP 354 | 355 | _TEXT ENDS 356 | 357 | END 358 | -------------------------------------------------------------------------------- /SRC/U4_SRCH.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | /*Thanks to Fenyx4 for the 8 | comment on the rune names*/ 9 | 10 | #include "u4.h" 11 | 12 | #include 13 | 14 | char D_27A6[] = "Nothing Here!\n"; 15 | 16 | /*"You find..." & karma+=5*/ 17 | C_8D4B() 18 | { 19 | u4_puts(/*D_2798*/"You find...\n"); 20 | karma_inc(&(Party._honor), 5); 21 | Party.f_1e8 = Party._moves & 0xf0; 22 | } 23 | 24 | /*get random amount of reagent (max 99)*/ 25 | C_8D6D(bp04) 26 | int bp04; 27 | { 28 | Party._reagents[bp04] += U4_RND1(7) + 2; 29 | if(Party._reagents[bp04] > 99) { 30 | Party._reagents[bp04] = 99; 31 | u4_puts(/*D_27B5*/"Dropped some!\n"); 32 | sound(1); 33 | } 34 | } 35 | 36 | C_8DAA() 37 | { 38 | if((Party._trammel | Party._felucca) || (Party._moves & 0xf0) == Party.f_1e8) { 39 | u4_puts(D_27A6); 40 | return; 41 | } 42 | C_8D4B(); 43 | u4_puts(/*D_27C4*/"Mandrake Root!\n"); 44 | C_8D6D(7); 45 | } 46 | 47 | C_8DE0() 48 | { 49 | if((Party._trammel | Party._felucca) || (Party._moves & 0xf0) == Party.f_1e8) { 50 | u4_puts(D_27A6); 51 | return; 52 | } 53 | C_8D4B(); 54 | u4_puts(/*D_27D4*/"Nightshade!\n"); 55 | C_8D6D(6); 56 | } 57 | 58 | C_8E16() 59 | { 60 | if(TST_MSK(Party.mItems, ST_BELL)) { 61 | u4_puts(D_27A6); 62 | return; 63 | } 64 | SET_MSK(Party.mItems, ST_BELL); 65 | C_8D4B(); 66 | u4_puts(/*D_27E1*/"The Bell of Courage!\n"); 67 | XP_inc(0, 400); 68 | } 69 | 70 | C_8E46() 71 | { 72 | if(TST_MSK(Party.mItems, ST_HORN)) { 73 | u4_puts(D_27A6); 74 | return; 75 | } 76 | SET_MSK(Party.mItems, ST_HORN); 77 | C_8D4B(); 78 | u4_puts(/*D_27F7*/"A Silver Horn!\n"); 79 | XP_inc(0, 400); 80 | } 81 | 82 | C_8E77() 83 | { 84 | if(TST_MSK(Party.mItems, ST_WHEEL)) { 85 | u4_puts(D_27A6); 86 | return; 87 | } 88 | SET_MSK(Party.mItems, ST_WHEEL); 89 | C_8D4B(); 90 | u4_puts(/*D_2807*/"The Wheel from the H.M.S. Cape!\n"); 91 | XP_inc(0, 400); 92 | } 93 | 94 | C_8EA8() 95 | { 96 | if( 97 | TST_MSK(Party.mItems, ST_SKULL) || 98 | (Party._trammel | Party._felucca) || 99 | TST_MSK(Party.mItems, ST_CAST_SKULL) 100 | ) { 101 | u4_puts(D_27A6); 102 | return; 103 | } 104 | SET_MSK(Party.mItems, ST_SKULL); 105 | C_8D4B(); 106 | u4_puts(/*D_2828*/"The Skull of Mondain the Wizard!\n"); 107 | XP_inc(0, 400); 108 | } 109 | 110 | C_8EE8() 111 | { 112 | if( 113 | TST_MSK(Party.mStones, 7) || 114 | (Party._trammel | Party._felucca) 115 | ) { 116 | u4_puts(D_27A6); 117 | return; 118 | } 119 | SET_MSK(Party.mStones, 7); 120 | C_8D4B(); 121 | u4_puts(/*D_284A*/"The Black Stone!\n"); 122 | XP_inc(0, 200); 123 | } 124 | 125 | C_8F21() 126 | { 127 | if(TST_MSK(Party.mStones, 6)) { 128 | u4_puts(D_27A6); 129 | return; 130 | } 131 | SET_MSK(Party.mStones, 6); 132 | C_8D4B(); 133 | u4_puts(/*D_285C*/"The White Stone!\n"); 134 | XP_inc(0, 200); 135 | } 136 | 137 | C_8F51() 138 | { 139 | if(TST_MSK(Party.mItems, ST_BOOK)) { 140 | u4_puts(D_27A6); 141 | return; 142 | } 143 | SET_MSK(Party.mItems, ST_BOOK); 144 | C_8D4B(); 145 | u4_puts(/*D_286E*/"The Book of Truth!\n"); 146 | XP_inc(0, 400); 147 | } 148 | 149 | C_8F81() 150 | { 151 | if(TST_MSK(Party.mItems, ST_CANDLE)) { 152 | u4_puts(D_27A6); 153 | return; 154 | } 155 | SET_MSK(Party.mItems, ST_CANDLE); 156 | C_8D4B(); 157 | u4_puts(/*D_2882*/"The Candle of Love!\n"); 158 | XP_inc(0, 400); 159 | } 160 | 161 | /*use telescope*/ 162 | C_8FB1() 163 | { 164 | int bp_02; 165 | 166 | u4_puts(/*D_2897*/"You see a knob on the Telescope marked A-P\n"); 167 | if((bp_02 = AskLetter(/*D_28C3*/"You Select:\x12\x12\b", 'A', 'P')) < 0) 168 | return; 169 | bp_02 -= 'A'; 170 | if(Load(D_0824[bp_02], sizeof(tMap32x32), &(D_8742._map)) == -1) 171 | exit(3); 172 | C_B9EF(0); 173 | if(Load(D_0824[Party._loc - 1], sizeof(tMap32x32), &(D_8742._map)) == -1) 174 | exit(3); 175 | } 176 | 177 | C_9027() 178 | { 179 | if( 180 | Party._armors[7] | 181 | Party._hones | Party._compa | 182 | Party._valor | Party._justi | 183 | Party._sacri | Party._honor | 184 | Party._spiri | Party._humil 185 | ) { 186 | u4_puts(D_27A6); 187 | return; 188 | } 189 | Party._armors[7] = 8; 190 | C_8D4B(); 191 | u4_puts(/*D_28D2*/"Mystic Armour!\n"); 192 | XP_inc(0, 400); 193 | } 194 | 195 | C_9076() 196 | { 197 | if( 198 | Party._weapons[15] | 199 | Party._hones | Party._compa | 200 | Party._valor | Party._justi | 201 | Party._sacri | Party._honor | 202 | Party._spiri | Party._humil 203 | ) { 204 | u4_puts(D_27A6); 205 | return; 206 | } 207 | Party._weapons[15] = 8; 208 | C_8D4B(); 209 | u4_puts(/*D_28E2*/"Mystic Weapons!\n"); 210 | XP_inc(0, 400); 211 | } 212 | 213 | unsigned char D_2904[][2] = { 214 | {0x05,0x01}, 215 | {0x06,0x02}, 216 | {0x07,0x04}, 217 | {0x08,0x08}, 218 | {0x09,0x10}, 219 | {0x0A,0x20}, 220 | {0x01,0x40}, 221 | {0x0D,0x80} 222 | }; 223 | 224 | C_90C5() 225 | { 226 | register int si; 227 | 228 | for(si = 7; si >= 0; si --) 229 | if(D_2904[si][0] == Party._loc) 230 | break; 231 | if(D_2904[si][1] & Party.mRunes) { 232 | u4_puts(D_27A6); 233 | return; 234 | } 235 | Party.mRunes |= D_2904[si][1]; 236 | C_8D4B(); 237 | u4_puts(/*D_28F3*/"The rune of "); 238 | u4_puts(D_1E98[151 + si]); 239 | u4_puts(/*D_2900*/"!\n"); 240 | XP_inc(0, 100); 241 | } 242 | 243 | typedef s_handler(); 244 | typedef s_handler *pS_handler; 245 | 246 | struct t_05_local { 247 | unsigned char _00, _01, _02; 248 | pS_handler _03; 249 | } D_2920[] = { 250 | {0x00,0xB6,0x36,C_8DAA},/*Mandrake root*/ 251 | {0x00,0x64,0xA5,C_8DAA},/*Mandrake root*/ 252 | {0x00,0x2E,0x95,C_8DE0},/*Nightshade*/ 253 | {0x00,0xCD,0x2C,C_8DE0},/*Nightshade*/ 254 | {0x00,0xB0,0xD0,C_8E16},/*The Bell of Courage!*/ 255 | {0x00,0x2D,0xAD,C_8E46},/*'A Silver Horn!'*/ 256 | {0x00,0x60,0xD7,C_8E77},/*The Wheel from the H.M.S. Cape!*/ 257 | {0x00,0xC5,0xF5,C_8EA8},/*The Skull of Mondain the Wizard!*/ 258 | {0x00,0xE0,0x85,C_8EE8},/*The Black Stone!*/ 259 | {0x00,0x40,0x50,C_8F21},/*The White Stone!*/ 260 | {0x02,0x06,0x06,C_8F51},/*The Book of Truth!*/ 261 | {0x10,0x16,0x01,C_8F81},/*The Candle of Love!*/ 262 | {0x02,0x16,0x03,C_8FB1},/*use Telescope*/ 263 | {0x03,0x16,0x04,C_9027},/*Mystic Armour!*/ 264 | {0x04,0x08,0x0F,C_9076},/*Mystic Weapons!*/ 265 | {0x05,0x08,0x06,C_90C5},/*rune of Honesty*/ 266 | {0x06,0x19,0x01,C_90C5},/*rune of Compassion*/ 267 | {0x07,0x1E,0x1E,C_90C5},/*rune of Valor*/ 268 | {0x08,0x0D,0x06,C_90C5},/*rune of Justice*/ 269 | {0x09,0x1C,0x1E,C_90C5},/*rune of Sacrifice*/ 270 | {0x0A,0x02,0x1D,C_90C5},/*rune of Honor*/ 271 | {0x01,0x11,0x08,C_90C5},/*rune of Spirituality*/ 272 | {0x0D,0x1D,0x1D,C_90C5},/*rune of Humility*/ 273 | {0x00,0x00,0x00,0} 274 | }; 275 | 276 | /*C_913A*/CMD_Search() 277 | { 278 | register struct t_05_local *si; 279 | 280 | u4_puts(/*D_2914*/"Search...\n"); 281 | if(CurMode <= MOD_BUILDING && Party.f_1dc != 0) { 282 | w_DriftOnly(); 283 | return; 284 | } 285 | for(si = D_2920; si->_03; si ++) { 286 | if(si->_00 == Party._loc && si->_01 == Party._x && si->_02 == Party._y) 287 | break; 288 | } 289 | if(si->_03 == 0) { 290 | u4_puts(D_27A6); 291 | } else { 292 | (*si->_03)(); 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /forVS/UN_U4.DSP: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="UN_U4" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 5.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=UN_U4 - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "UN_U4.MAK". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "UN_U4.MAK" CFG="UN_U4 - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "UN_U4 - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "UN_U4 - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP Scc_ProjName "" 26 | # PROP Scc_LocalPath "" 27 | CPP=cl.exe 28 | RSC=rc.exe 29 | 30 | !IF "$(CFG)" == "UN_U4 - Win32 Release" 31 | 32 | # PROP BASE Use_MFC 0 33 | # PROP BASE Use_Debug_Libraries 0 34 | # PROP BASE Output_Dir "Release" 35 | # PROP BASE Intermediate_Dir "Release" 36 | # PROP BASE Target_Dir "" 37 | # PROP Use_MFC 0 38 | # PROP Use_Debug_Libraries 0 39 | # PROP Output_Dir "Release" 40 | # PROP Intermediate_Dir "Release" 41 | # PROP Target_Dir "" 42 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 43 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 44 | # ADD BASE RSC /l 0x411 /d "NDEBUG" 45 | # ADD RSC /l 0x411 /d "NDEBUG" 46 | BSC32=bscmake.exe 47 | # ADD BASE BSC32 /nologo 48 | # ADD BSC32 /nologo 49 | LINK32=link.exe 50 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 51 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 52 | 53 | !ELSEIF "$(CFG)" == "UN_U4 - Win32 Debug" 54 | 55 | # PROP BASE Use_MFC 0 56 | # PROP BASE Use_Debug_Libraries 1 57 | # PROP BASE Output_Dir "Debug" 58 | # PROP BASE Intermediate_Dir "Debug" 59 | # PROP BASE Target_Dir "" 60 | # PROP Use_MFC 0 61 | # PROP Use_Debug_Libraries 1 62 | # PROP Output_Dir "Debug" 63 | # PROP Intermediate_Dir "Debug" 64 | # PROP Ignore_Export_Lib 0 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 67 | # ADD CPP /nologo /Gz /W3 /GX /Zi /Od /I "..\SRC" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c 68 | # ADD BASE RSC /l 0x411 /d "_DEBUG" 69 | # ADD RSC /l 0x411 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LINK32=link.exe 74 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 75 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 76 | # SUBTRACT LINK32 /profile 77 | 78 | !ENDIF 79 | 80 | # Begin Target 81 | 82 | # Name "UN_U4 - Win32 Release" 83 | # Name "UN_U4 - Win32 Debug" 84 | # Begin Group "U4" 85 | 86 | # PROP Default_Filter "" 87 | # Begin Source File 88 | 89 | SOURCE=..\SRC\U4_3D.C 90 | # End Source File 91 | # Begin Source File 92 | 93 | SOURCE=..\SRC\U4_AI.C 94 | # End Source File 95 | # Begin Source File 96 | 97 | SOURCE=..\SRC\U4_ANIM.C 98 | # End Source File 99 | # Begin Source File 100 | 101 | SOURCE=..\SRC\U4_COMBA.C 102 | # End Source File 103 | # Begin Source File 104 | 105 | SOURCE=..\SRC\U4_COMBB.C 106 | # End Source File 107 | # Begin Source File 108 | 109 | SOURCE=..\SRC\U4_COMBC.C 110 | # End Source File 111 | # Begin Source File 112 | 113 | SOURCE=..\SRC\U4_CSTES.C 114 | # End Source File 115 | # Begin Source File 116 | 117 | SOURCE=..\SRC\U4_DNG.C 118 | # End Source File 119 | # Begin Source File 120 | 121 | SOURCE=..\SRC\U4_END.C 122 | # End Source File 123 | # Begin Source File 124 | 125 | SOURCE=..\SRC\U4_EVT.C 126 | # End Source File 127 | # Begin Source File 128 | 129 | SOURCE=..\SRC\U4_EXPLO.C 130 | # End Source File 131 | # Begin Source File 132 | 133 | SOURCE=..\SRC\U4_FILE.C 134 | # End Source File 135 | # Begin Source File 136 | 137 | SOURCE=..\SRC\U4_GET.C 138 | # End Source File 139 | # Begin Source File 140 | 141 | SOURCE=..\SRC\U4_HOLE.C 142 | # End Source File 143 | # Begin Source File 144 | 145 | SOURCE=..\SRC\U4_INIT.C 146 | # End Source File 147 | # Begin Source File 148 | 149 | SOURCE=..\SRC\U4_LB.C 150 | # End Source File 151 | # Begin Source File 152 | 153 | SOURCE=..\SRC\U4_LOCAT.C 154 | # End Source File 155 | # Begin Source File 156 | 157 | SOURCE=..\SRC\U4_MAIN.C 158 | # End Source File 159 | # Begin Source File 160 | 161 | SOURCE=..\SRC\U4_MAIN2.C 162 | # End Source File 163 | # Begin Source File 164 | 165 | SOURCE=..\SRC\U4_MAP.C 166 | # End Source File 167 | # Begin Source File 168 | 169 | SOURCE=..\SRC\U4_MIX.C 170 | # End Source File 171 | # Begin Source File 172 | 173 | SOURCE=..\SRC\U4_NPC.C 174 | # End Source File 175 | # Begin Source File 176 | 177 | SOURCE=..\SRC\U4_PEER.C 178 | # End Source File 179 | # Begin Source File 180 | 181 | SOURCE=..\SRC\U4_Q_N_V.C 182 | # End Source File 183 | # Begin Source File 184 | 185 | SOURCE=..\SRC\U4_SHOPS.C 186 | # End Source File 187 | # Begin Source File 188 | 189 | SOURCE=..\SRC\U4_SHRIN.C 190 | # End Source File 191 | # Begin Source File 192 | 193 | SOURCE=..\SRC\U4_SPELL.C 194 | # End Source File 195 | # Begin Source File 196 | 197 | SOURCE=..\SRC\U4_SRCH.C 198 | # End Source File 199 | # Begin Source File 200 | 201 | SOURCE=..\SRC\U4_SRCH2.C 202 | # End Source File 203 | # Begin Source File 204 | 205 | SOURCE=..\SRC\U4_TALK.C 206 | # End Source File 207 | # Begin Source File 208 | 209 | SOURCE=..\SRC\U4_USE.C 210 | # End Source File 211 | # Begin Source File 212 | 213 | SOURCE=..\SRC\U4_UTIL.C 214 | # End Source File 215 | # Begin Source File 216 | 217 | SOURCE=..\SRC\U4_Z.C 218 | # End Source File 219 | # End Group 220 | # Begin Group "U4_h" 221 | 222 | # PROP Default_Filter "" 223 | # Begin Source File 224 | 225 | SOURCE=..\SRC\U4.H 226 | # End Source File 227 | # Begin Source File 228 | 229 | SOURCE=..\SRC\U4_DOS.H 230 | # End Source File 231 | # Begin Source File 232 | 233 | SOURCE=..\SRC\U4_FILE.H 234 | # End Source File 235 | # Begin Source File 236 | 237 | SOURCE=..\SRC\U4_GRAPH.H 238 | # End Source File 239 | # Begin Source File 240 | 241 | SOURCE=..\SRC\U4_SCAN.H 242 | # End Source File 243 | # Begin Source File 244 | 245 | SOURCE=..\SRC\U4_SHAPE.H 246 | # End Source File 247 | # End Group 248 | # Begin Source File 249 | 250 | SOURCE=.\common.c 251 | # End Source File 252 | # Begin Source File 253 | 254 | SOURCE=.\common.h 255 | # End Source File 256 | # Begin Source File 257 | 258 | SOURCE=.\u4_forWin.c 259 | # End Source File 260 | # Begin Source File 261 | 262 | SOURCE=.\U4_VAR.C 263 | # End Source File 264 | # End Target 265 | # End Project 266 | -------------------------------------------------------------------------------- /SRC-TITLE/DATA.ASM: -------------------------------------------------------------------------------- 1 | 2 | DGROUP GROUP CONST 3 | 4 | CONST SEGMENT PUBLIC WORD 'CONST' 5 | ASSUME DS:DGROUP 6 | 7 | ;====---- monster animation sequence ----==== 8 | PUBLIC D_3380 9 | D_3380 db 01h,01h,01h,00h,00h,01h,01h,01h,00h,00h,01h,01h,02h,02h,03h,03h 10 | db 04h,04h,01h,02h,03h,04h,01h,02h,05h,06h,07h,08h,05h,06h,07h,08h 11 | db 05h,06h,07h,08h,05h,06h,07h,08h,05h,06h,07h,08h,05h,06h,07h,08h 12 | db 09h,0Ah,09h,0Ah,09h,0Ah,0Bh,0Bh,0Bh,0Bh,0Ch,0Ch,0Dh,0Dh,0Ch,0Dh 13 | db 0Ch,0Dh,0Ch,0Bh,0Bh,0Bh,00h,00h,01h,02h,03h,04h,01h,02h,05h,06h 14 | db 07h,08h,05h,06h,07h,08h,09h,0Ah,0Bh,0Bh,0Bh,00h,00h,0Eh,0Eh,0Eh 15 | db 0Fh,10h,10h,10h,11h,11h,11h,10h,10h,10h,11h,11h,11h,10h,10h,10h 16 | db 0Fh,0Eh,0Eh,00h,00h,0Bh,0Bh,0Bh 17 | 18 | ;====---- monster animation sequence ----==== 19 | PUBLIC D_33F8 20 | D_33F8 db 01h,00h,01h,02h,03h,04h,03h,02h,01h,00h,01h,02h,03h,04h,05h,06h 21 | db 05h,06h,05h,06h,04h,07h,08h,09h,0Ah,09h,08h,07h,08h,09h,0Ah,0Bh 22 | db 0Ch,0Bh,0Ch,0Dh,0Bh,0Ch,0Dh,01h,0Dh,01h,0Eh,01h,0Fh,01h,0Eh,01h 23 | db 0Fh,0Ah,09h,08h,10h,11h,10h,11h,10h,11h,09h,08h,07h,04h,03h,02h 24 | 25 | ;====---- monsters anim src_y ----==== 26 | PUBLIC D_3438 27 | D_3438 db 00h,20h,40h,60h,80h,0A0h 28 | db 00h,20h,40h,60h,80h,0A0h 29 | db 00h,20h,40h,60h,80h,0A0h 30 | 31 | ;====---- monster #1 anim src_x ----==== 32 | PUBLIC D_344A 33 | D_344A db 00h,00h,00h,00h,00h,00h 34 | db 07h,07h,07h,07h,07h,07h 35 | db 0Eh,0Eh,0Eh,0Eh,0Eh,0Eh 36 | 37 | ;====---- monster #2 anim src_x ----==== 38 | PUBLIC D_345C 39 | D_345C db 22h,22h,22h,22h,22h,22h 40 | db 1Ch,1Ch,1Ch,1Ch,1Ch,1Ch 41 | db 16h,16h,16h,16h,16h,16h 42 | 43 | 44 | ;====---- handwriting data? ----==== 45 | PUBLIC D_346E 46 | D_346E db 054h,0BDh,055h,0BCh,057h,0BCh,059h,0BCh,05Bh,0BCh,05Ch,0BDh,05Ch,0BEh,05Bh,0BFh 47 | db 059h,0BFh,058h,0BEh,058h,0BDh,057h,0BBh,056h,0BAh,056h,0B9h,055h,0B8h,055h,0B7h 48 | db 054h,0B6h,054h,0B5h,053h,0B4h,053h,0B3h,052h,0B2h,052h,0B1h,051h,0B0h,04Fh,0B0h 49 | db 04Eh,0B0h,04Dh,0B1h,04Dh,0B2h,04Eh,0B3h,050h,0B3h,051h,0B2h,054h,0B2h,055h,0B1h 50 | db 056h,0B1h,057h,0B0h,059h,0B0h,05Bh,0B0h,05Dh,0B0h,05Fh,0B0h,061h,0B0h,063h,0B0h 51 | db 065h,0B0h,067h,0B0h,069h,0B0h,06Bh,0B0h,06Dh,0B0h,06Fh,0B0h,071h,0B0h,073h,0B0h 52 | db 075h,0B0h,077h,0B0h,079h,0B0h,07Bh,0B0h,07Dh,0B0h,07Fh,0B0h,081h,0B0h,083h,0B0h 53 | db 085h,0B0h,087h,0B0h,089h,0B0h,08Bh,0B0h,08Dh,0B0h,08Fh,0B0h,091h,0B0h,093h,0B0h 54 | db 095h,0B0h,097h,0B0h,099h,0B0h,09Bh,0B0h,09Dh,0B0h,09Fh,0B0h,0A1h,0B0h,0A3h,0B0h 55 | db 0A5h,0B0h,0A7h,0B0h,0A9h,0B0h,0ABh,0B0h,0ADh,0B0h,0AFh,0B0h,0B1h,0B0h,0B3h,0B0h 56 | db 0B5h,0B0h,0B7h,0B0h,0B9h,0B0h,0BBh,0B0h,0BDh,0B0h,0BFh,0B0h,0C1h,0B0h,0C3h,0B0h 57 | db 0C5h,0B0h,0C7h,0B0h,0C9h,0B0h,0CAh,0B0h,0CBh,0B1h,0CCh,0B1h,0CDh,0B2h,05Eh,0B8h 58 | db 05Eh,0B7h,05Dh,0B6h,05Dh,0B5h,05Ch,0B4h,05Ch,0B3h,05Dh,0B2h,05Fh,0B2h,060h,0B2h 59 | db 061h,0B3h,061h,0B4h,062h,0B5h,062h,0B6h,063h,0B7h,063h,0B8h,062h,0B9h,060h,0B9h 60 | db 05Fh,0B9h,069h,0B9h,06Ah,0B8h,06Ah,0B7h,069h,0B6h,069h,0B5h,068h,0B4h,068h,0B3h 61 | db 067h,0B2h,06Bh,0B8h,06Ch,0B9h,06Eh,0B9h,077h,0B9h,075h,0B9h,074h,0B9h,073h,0B8h 62 | db 073h,0B7h,072h,0B6h,072h,0B5h,071h,0B4h,071h,0B3h,072h,0B2h,074h,0B2h,075h,0B3h 63 | db 076h,0B4h,077h,0B5h,077h,0B6h,078h,0B7h,078h,0B8h,079h,0B9h,079h,0BAh,07Ah,0BBh 64 | db 07Ah,0BCh,07Bh,0BDh,07Bh,0BEh,076h,0B3h,077h,0B2h,08Bh,0BEh,08Bh,0BDh,08Ah,0BCh 65 | db 08Ah,0BBh,089h,0BAh,089h,0B9h,088h,0B8h,088h,0B7h,087h,0B6h,087h,0B5h,086h,0B4h 66 | db 086h,0B3h,085h,0B2h,08Ch,0BFh,08Eh,0BFh,08Fh,0BFh,090h,0BEh,090h,0BDh,08Fh,0BCh 67 | db 08Fh,0BBh,08Eh,0BAh,08Eh,0B9h,08Ch,0B9h,08Fh,0B8h,08Fh,0B7h,08Eh,0B6h,08Eh,0B5h 68 | db 08Dh,0B4h,08Dh,0B3h,08Ch,0B2h,08Ah,0B2h,088h,0B2h,087h,0B3h,096h,0B9h,097h,0B8h 69 | db 097h,0B7h,096h,0B6h,096h,0B5h,095h,0B4h,095h,0B3h,094h,0B2h,098h,0B8h,099h,0B9h 70 | db 09Bh,0B9h,0A1h,0B9h,0A0h,0B8h,0A0h,0B7h,09Fh,0B6h,09Fh,0B5h,09Eh,0B4h,09Eh,0B3h 71 | db 09Dh,0B2h,0A2h,0BCh,0A2h,0BBh,0A9h,0BCh,0A9h,0BBh,0A8h,0BAh,0A8h,0B9h,0A7h,0B8h 72 | db 0A7h,0B7h,0A6h,0B6h,0A6h,0B5h,0A5h,0B4h,0A5h,0B3h,0A6h,0B2h,0A8h,0B2h,0A9h,0B2h 73 | db 0AAh,0B3h,0A5h,0B9h,0A6h,0B9h,0AAh,0B9h,0B2h,0B9h,0B1h,0B8h,0B1h,0B7h,0B0h,0B6h 74 | db 0B0h,0B5h,0AFh,0B4h,0AFh,0B3h,0AEh,0B2h,0B3h,0BCh,0B3h,0BBh,0BBh,0B8h,0BAh,0B9h 75 | db 0B8h,0B9h,0B7h,0B9h,0B6h,0B8h,0B6h,0B7h,0B7h,0B6h,0B8h,0B5h,0B9h,0B4h,0B9h,0B3h 76 | db 0B8h,0B2h,0B6h,0B2h,0B5h,0B2h,0B4h,0B3h,0C5h,0BEh,0C5h,0BDh,0C4h,0BCh,0C4h,0BBh 77 | db 0C3h,0BAh,0C3h,0B9h,0C2h,0B8h,0C2h,0B7h,0C1h,0B6h,0C1h,0B5h,0C0h,0B4h,0C0h,0B3h 78 | db 0BFh,0B2h,0C5h,0B9h,0C6h,0B9h,0C7h,0B8h,0C7h,0B7h,0C6h,0B6h,0C6h,0B5h,0C5h,0B4h 79 | db 0C5h,0B3h,0C6h,0B2h 80 | db 0 81 | 82 | ;====---- tile map data? ----==== 83 | PUBLIC D_3683 84 | D_3683 db 06h,06h,06h,04h,04h,04h,01h,01h,00h,00h,00h,00h,01h,04h,04h,0Dh,0Eh,0Fh,04h 85 | db 06h,06h,04h,04h,04h,01h,01h,01h,01h,00h,00h,01h,01h,04h,04h,04h,04h,04h,04h 86 | db 06h,04h,04h,01h,01h,01h,02h,02h,01h,01h,01h,01h,01h,01h,0Ah,04h,04h,04h,06h 87 | db 06h,04h,04h,01h,01h,02h,02h,01h,01h,09h,08h,01h,01h,01h,01h,04h,06h,06h,06h 88 | db 04h,04h,04h,04h,01h,01h,01h,01h,04h,04h,08h,08h,01h,01h,01h,01h,01h,06h,06h 89 | 90 | PUBLIC D_36E2 91 | D_36E2 db 88h,20h,11h,80h,20h,31h,80h,20h,51h,80h,20h,71h,88h,27h 92 | db 11h,84h,27h,10h,84h,17h,10h,84h,07h,10h,84h,77h,88h,20h,51h,80h 93 | db 20h,31h,80h,20h,11h,80h,70h,88h,01h,66h,84h,11h,66h,84h,07h,10h 94 | db 84h,17h,10h,82h,11h,46h,82h,17h,0Fh,82h,11h,47h,82h,17h,0Eh,82h 95 | db 11h,48h,27h,0Eh,84h,11h,49h,77h,84h,11h,4Ah,88h,27h,0Eh,84h,17h 96 | db 0Eh,84h,17h,0Dh,84h,28h,0Eh,84h,18h,0Eh,84h,11h,2Ah,80h,1Ch,0Bh 97 | db 80h,1Ch,0Ch,80h,7Ch,1Dh,0Dh,81h,7Dh,84h,1Eh,0Dh,80h,1Eh,0Ch,80h 98 | db 1Eh,0Bh,80h,1Eh,0Ah,81h,7Eh,84h,11h,4Ah,84h,11h,4Bh,07h,0Dh,84h 99 | db 11h,4Ch,07h,0Eh,84h,15h,0Ch,84h,15h,0Dh,84h,05h,0Dh,16h,0Ch,84h 100 | db 16h,0Dh,84h,0Dh,0Eh,81h,7Dh,84h,1Dh,0Eh,81h,7Dh,84h,0Dh,0Dh,81h 101 | db 7Dh,84h,1Ch,0Dh,81h,7Ch,84h,0Dh,0Eh,81h,7Dh,84h,1Dh,0Eh,81h,7Dh 102 | db 84h,0Dh,0Dh,81h,7Dh,75h,03h,0Dh,84h,1Dh,0Dh,81h,7Dh,84h,1Ch,0Eh 103 | db 81h,7Ch,84h,1Dh,0Dh,81h,7Dh,76h,14h,0Dh,88h,18h,0Dh,84h,18h,0Ch 104 | db 17h,0Eh,84h,78h,17h,0Dh,84h,17h,0Ch,84h,77h,88h,71h,12h,4Ch,84h 105 | db 12h,6Ch,84h,12h,0Ch,84h,4Bh,00h,73h,82h,3Bh,01h,82h,2Bh,02h,12h 106 | db 0Bh,82h,2Bh,03h,82h,12h,0Ah,1Bh,04h,74h,82h,1Bh,05h,82h,1Bh,06h 107 | db 12h,6Ah,82h,1Bh,07h,82h,1Ch,09h,80h,1Ch,08h,80h,7Ch,1Dh,07h,81h 108 | db 7Dh,88h,1Bh,08h,82h,1Ch,09h,80h,7Ch,1Dh,08h,81h,7Dh,7Bh,84h,3Ah 109 | db 09h,84h,4Ah,09h,84h,4Ah,08h,12h,0Ah,84h,12h,09h,84h,12h,08h,84h 110 | db 2Ch,08h,80h,3Ch,08h,80h,7Ch,4Dh,08h,81h,7Dh,7Ah,88h,12h,68h,84h 111 | db 22h,68h,84h,32h,68h,84h,32h,08h,84h,32h,07h,84h,32h,67h,84h,42h 112 | db 67h,88h,47h,07h,84h,47h,08h,84h,47h,09h,48h,07h,84h,37h,09h,48h 113 | db 08h,84h,77h,48h,09h,84h,38h,09h,84h,78h,88h,37h,09h,84h,47h,09h 114 | db 84h,47h,08h,38h,09h,84h,47h,07h,48h,09h,84h,77h,48h,08h,84h,48h 115 | db 07h,84h,78h,88h,42h,07h,84h,42h,06h,84h,42h,05h,84h,42h,04h,84h 116 | db 42h,24h,84h,32h,24h,84h,32h,04h,84h,32h,03h,88h,37h,03h,84h,37h 117 | db 02h,84h,37h,01h,38h,03h,84h,47h,01h,38h,02h,82h,09h,09h,82h,47h 118 | db 00h,48h,02h,19h,08h,82h,29h,07h,82h,47h,01h,39h,06h,82h,3Eh,05h 119 | db 80h,3Eh,04h,80h,3Eh,03h,81h,7Eh,72h,82h,39h,05h,82h,39h,04h,48h 120 | db 03h,37h,01h,82h,39h,03h,82h,3Eh,03h,37h,02h,81h,7Eh,83h,4Dh,03h 121 | db 81h,7Dh,78h,44h,03h,84h,3Dh,03h,81h,7Dh,82h,3Dh,02h,81h,7Dh,82h 122 | db 3Dh,03h,81h,7Dh,79h,88h,47h,02h,84h,47h,03h,74h,88h,20h,01h,80h 123 | db 20h,21h,80h,20h,41h,80h,20h,61h,85h,47h,02h,84h,37h,02h,84h,27h 124 | db 02h,84h,27h,01h,84h,77h,88h,20h,61h,80h,20h,41h,80h,20h,21h,80h 125 | db 20h,01h,80h,70h,88h 126 | db 0FFh 127 | 128 | 129 | CONST ENDS 130 | END 131 | -------------------------------------------------------------------------------- /SRC/U4_END.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | 11 | char *D_0BDA[] = { 12 | /*D_09BE*/"What dost thou possess if all may rely upon your every word?", 13 | /*D_09FB*/"What quality compels one to share in the journeys of others?", 14 | /*D_0A38*/"What answers when great deeds are called for?", 15 | /*D_0A66*/"What should be the same for Lord and Serf alike?", 16 | /*D_0A97*/"What is loath to place the self above aught else?", 17 | /*D_0AC9*/"What shirks no duty?", 18 | /*D_0ADE*/"What, in knowing the true self, knows all?", 19 | /*D_0B09*/"What is that which Serfs are born with but Nobles must strive to obtain?", 20 | /*D_0B52*/"If all else is imaginary, this is real...", 21 | /*D_0B7C*/"What plunges to the depths, while soaring on the heights?", 22 | /*D_0BB6*/"What turns not away from any peril?" 23 | }; 24 | 25 | C_2F7E() 26 | { 27 | u_delay(15, 1); 28 | if(u_kbhit()) 29 | u_kbread(); 30 | } 31 | 32 | unsigned char D_0BF0[] = {0xE7,0x53,0x23,0x3B,0x9E,0x69,0x17,0xBA,0xD8,0x1D,0x91,0x59,0xE9}; 33 | unsigned char D_0BFE[] = {0x88,0x69,0xDD,0x2C,0x15,0xB7,0x81,0xAC,0x6A,0x30,0xF3,0x6A,0xE9}; 34 | 35 | static unsigned D_8CCA; 36 | 37 | /*return to surface*/ 38 | C_2F9D(bp04) 39 | unsigned bp04; 40 | { 41 | u_delay(5, 0); 42 | Gra_CR(); 43 | Party._x = D_0BF0[bp04]; 44 | Party._y = D_0BFE[bp04]; 45 | Party.f_1d8 = D_8CCA; 46 | Party._loc = 0; 47 | CurMode = MOD_OUTDOORS; 48 | spell_cnt = 0; 49 | hit_tile = 0; 50 | spell_sta = 7; 51 | D_9440 = 1; 52 | D_95C6 = 0; 53 | Party.f_1dc = 0; 54 | C_26B6(); 55 | dspl_Stats(); 56 | u_kbflush(); 57 | longjmp(D_9458, -1); 58 | } 59 | 60 | /*passage is not granted*/ 61 | C_3010() 62 | { 63 | u4_puts(/*D_0C0B*/"\nPassage is not granted.\n"); 64 | C_2F9D(12); 65 | } 66 | 67 | /*Victory !*/ 68 | C_3025() 69 | { 70 | u_delay(2, 0); 71 | shakefx(); 72 | shakefx(); 73 | shakefx(); 74 | shakefx(); 75 | u_delay(3, 0); 76 | dfree(pShapes); 77 | Gra_17();/*infinity symbol*/ 78 | u_delay(3, 0); 79 | u4_puts(/*D_0C25*/"\n\nThe boundless knowledge of the Codex of Ultimate Wisdom is revealed unto thee."); 80 | C_2F7E(); 81 | u4_puts(/*D_0C76*/"\n\nThe voice says: Thou hast proven thyself to be truly good in nature."); 82 | C_2F7E(); 83 | u4_puts(/*D_0CBD*/"\n\nThou must know that thy quest to become an Avatar is the endless quest of a lifetime."); 84 | C_2F7E(); 85 | u4_puts(/*D_0D15*/"\n\nAvatarhood is a living gift. It must always and forever be nurtured to flourish."); 86 | C_2F7E(); 87 | u4_puts(/*D_0D69*/"\n\nFor if thou dost stray from the paths of virtue, thy way may be lost forever."); 88 | C_2F7E(); 89 | u4_puts(/*D_0DB9*/"\n\nReturn now unto thine own world. Live there as an example to thy people, as our memory of thy gallant deeds serves us."); 90 | C_2F7E(); 91 | Gra_10(); 92 | u4_puts(/*D_0E32*/"\n\nAs the sound of the voice trails off, darkness seems to rise around you. There is a moment of intense, wrenching vertigo."); 93 | C_2F7E(); 94 | Gra_16((D_943A == 1)?/*D_0EAE*/"stoncrcl.pic":/*D_0EBB*/"stoncrcl.ega", 0, 0); 95 | u4_puts(/*D_0EC8*/"\n\nYou open your eyes to a familiar circle of stones. You wonder of your recent adventures."); 96 | C_2F7E(); 97 | u4_puts(/*D_0F24*/"\n\nIt seems a time and place very distant. You wonder if it really happened. Then you realize that in your hand you hold The Ankh."); 98 | C_2F7E(); 99 | u4_puts(/*D_0FA7*/"\n\nYou walk away from the circle, knowing that you can always return from whence you came, since you now know the secret of the gates."); 100 | C_2F7E(); 101 | u4_puts(/*D_102D*/"\n\nCONGRATULATIONS!\n Thou hast\n completed\n ULTIMA IV\n Quest of the\n AVATAR\n in "); 102 | u4_putl(Party._moves, 0, '0'); 103 | u4_puts(/*D_1087*/"\n turns! Report\n thy feat unto\nLord British at\nOrigin Systems!"); 104 | while(1); 105 | } 106 | 107 | C_310F(bp06, bp04) 108 | char *bp06; 109 | char *bp04; 110 | { 111 | char bp_10[16]; 112 | 113 | u4_puts(bp06); 114 | Gra_CR(); 115 | Gra_CR(); 116 | u4_gets(bp_10, 15); 117 | Gra_CR(); 118 | if(strnicmp(bp_10, bp04, 15) != 0) { 119 | u_delay(1, 0); 120 | u4_puts(/*D_10C6*/"\nThy thoughts are not pure.\nI ask again.\n"); 121 | u_delay(2, 0); 122 | 123 | u4_puts(bp06); 124 | Gra_CR(); 125 | Gra_CR(); 126 | u4_gets(bp_10, 15); 127 | Gra_CR(); 128 | if(strnicmp(bp_10, bp04, 15) != 0) { 129 | u_delay(1, 0); 130 | u4_puts(/*D_10F0*/"\nThy thoughts are not pure.\nI ask again.\n"); 131 | u_delay(2, 0); 132 | 133 | u4_puts(bp06); 134 | Gra_CR(); 135 | Gra_CR(); 136 | u4_gets(bp_10, 15); 137 | Gra_CR(); 138 | if(strnicmp(bp_10, bp04, 15) != 0) 139 | return 0; 140 | } 141 | } 142 | return 1; 143 | } 144 | 145 | char *D_161A[] = { 146 | /*D_111A*/"truth", 147 | /*D_1120*/"love", 148 | /*D_1125*/"courage" 149 | }; 150 | 151 | char *D_1620[] = { 152 | /*D_112D*/"honesty", 153 | /*D_1135*/"compassn", 154 | /*D_113E*/"valor", 155 | /*D_1144*/"justice", 156 | /*D_114C*/"sacrific", 157 | /*D_1155*/"honor", 158 | /*D_115B*/"spirit", 159 | /*D_1162*/"humility" 160 | }; 161 | 162 | /*last phase of game ?*/ 163 | C_31F4() 164 | { 165 | int bp_02; 166 | char bp_12[16]; 167 | 168 | D_8CCA = Party.f_1d8; 169 | Party.f_1d8 = 1; 170 | CurMode = MOD_VISION; 171 | Gra_13(); 172 | dspl_Stats(); 173 | Gra_10(); 174 | u4_puts(/*D_116B*/"\n\n\nThere is a sudden darkness, and you find yourself alone in an empty chamber.\n"); 175 | u_delay(4, 0); 176 | Gra_16((D_943A == 1)?/*D_11BC*/"key7.pic":/*D_11C5*/"key7.ega", 0, 0); 177 | if( 178 | !TST_MSK(Party.mItems, ST_KEY_C) | 179 | !TST_MSK(Party.mItems, ST_KEY_T) | 180 | !TST_MSK(Party.mItems, ST_KEY_L) 181 | ) { 182 | u4_puts(/*D_11CE*/"\nThou dost not have the Key of Three Parts.\n"); 183 | C_2F9D(12); 184 | } 185 | u4_puts(/*D_11FB*/"\nYou use your Key of Three Parts.\n"); 186 | u_delay(3, 0); 187 | u4_puts(/*D_121E*/"\nA voice rings out:\n"); 188 | if(!C_310F(/*D_123D*/"\"What is the Word of Passage?\"", /*D_1233*/"veramocor")) 189 | C_3010(); 190 | if(D_8CCA != 8) { 191 | u4_puts(/*D_125C*/"\nThou hast not proved thy leadership in all eight virtues.\n"); 192 | u_delay(8, 0); 193 | C_3010(); 194 | } 195 | for(bp_02 = 7; bp_02 >= 0; bp_02 --) { 196 | if(*(pKarmas[bp_02])) { 197 | u4_puts(/*D_1298*/"\nThou art not ready.\n"); 198 | C_3010(); 199 | } 200 | } 201 | u4_puts(/*D_12AE*/"\nPassage is granted.\n"); 202 | u_delay(5, 0); 203 | Gra_10(); 204 | for(bp_02 = 0; bp_02 < 11; bp_02 ++) { 205 | char bp_26[20]; 206 | 207 | u_delay(2, 0); 208 | u4_puts(/*D_12C4*/"\n\nThe voice asks:\n\n"); 209 | u_delay(2, 0); 210 | if(!C_310F(D_0BDA[bp_02], (bp_02<=7)?D_1E98[151 + bp_02]:D_161A[bp_02-8])) { 211 | u_delay(1, 0); 212 | u4_puts(/*D_12D8*/"\nThy quest is not yet complete.\n"); 213 | C_2F9D(bp_02); 214 | } 215 | strcpy(bp_26, (bp_02 >= 8)?D_161A[bp_02-8]:D_1620[bp_02]); 216 | strcat(bp_26, (D_943A == 1)?/*D_12F9*/".pic":/*D_12FE*/".ega"); 217 | Gra_16(bp_26, 0, 0); 218 | if(bp_02 == 7) { 219 | u_delay(3, 0); 220 | u4_puts(/*D_1303*/"\nThou art well versed in the virtues of the Avatar.\n"); 221 | u_delay(5, 0); 222 | } 223 | } 224 | u4_puts(/*D_1338*/"\n\nThe floor rumbles beneath your feet.\n"); 225 | shakefx(); 226 | shakefx(); 227 | u_delay(5, 0); 228 | u4_puts(/*D_1360*/"\nAbove the din, the voice asks:\n\nIf all eight virtues of the Avatar combine into and are derived from the Three Principles of Truth, Love and Courage..."); 229 | C_2F7E(); 230 | u4_puts(/*D_13F9*/"\n\nThen what is the one thing which encompasses and is the whole of all undeniable Truth, unending Love, and unyielding Courage?\n\n"); 231 | u4_gets(bp_12, 15); 232 | Gra_CR(); 233 | if(strnicmp(bp_12, /*D_147B*/"infinity", 16) != 0) { 234 | u4_puts(/*D_1484*/"\nThy thoughts are not pure.\nI ask again.\n"); 235 | u_delay(3, 0); 236 | u4_puts(/*D_14AE*/"\n\nWhat is the one thing which encompasses and is the whole of all undeniable Truth, unending Love, and unyielding Courage?\n\n"); 237 | u4_gets(bp_12, 15); 238 | Gra_CR(); 239 | if(strnicmp(bp_12, /*D_152B*/"infinity", 16) != 0) { 240 | u4_puts(/*D_1534*/"\nThy thoughts are not pure.\nI ask again.\n"); 241 | u_delay(3, 0); 242 | u4_puts(/*D_155E*/"\n\nWhat is the one thing which encompasses and is the whole of all undeniable Truth, unending Love, and unyielding Courage?\n\n"); 243 | u4_gets(bp_12, 15); 244 | Gra_CR(); 245 | if(strnicmp(bp_12, /*D_15DB*/"infinity", 16) != 0) { 246 | u_delay(1, 0); 247 | u4_puts(/*D_15E4*/"\nThou dost not know the true nature of the Universe.\n"); 248 | C_2F9D(11); 249 | } 250 | } 251 | } 252 | C_3025(); 253 | } 254 | -------------------------------------------------------------------------------- /SRC/U4_USE.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | 11 | char D_00EE[] = "Hmm...No effect!\n"; 12 | char D_0100[] = "None owned!\n"; 13 | char D_010E[] = {/*colors masks*/ 14 | (1<<6)|(1<<5)|(1<<3)|(1<<0),/*truth*/ 15 | (1<<6)|(1<<4)|(1<<3)|(1<<1),/*love*/ 16 | (1<<6)|(1<<5)|(1<<4)|(1<<2) /*courage*/ 17 | }; 18 | 19 | void C_01E1() 20 | { 21 | int bp_10, bp_02; 22 | char bp_12[12]; 23 | char bp_04; 24 | 25 | if(Combat._charaX[activeChara] != 5 || Combat._charaY[activeChara] != 5 || D_943E == -1) { 26 | u4_puts(D_00EE); 27 | return; 28 | } 29 | u4_puts(/*D_0080*/"\nThere are holes for 4 stones. What colors:\n"); 30 | bp_04 = 0; 31 | for(bp_02 = 1; bp_02 <= 4; bp_02++) { 32 | u4_putc(bp_02 + 'A' - 1); u4_putc(':'); 33 | u4_gets(bp_12, 11); 34 | Gra_CR(); 35 | for(bp_10 = 7; bp_10 >= 0; bp_10--) { 36 | if(strnicmp(D_0884[bp_10], bp_12, 12) == 0) 37 | break; 38 | } 39 | if(bp_10 == -1 || !TST_MSK(Party.mStones, bp_10)) { 40 | if(*bp_12 != '\0') 41 | u4_puts(D_0100); 42 | return; 43 | } 44 | if((1 << bp_10) & bp_04) { 45 | u4_puts(/*D_00AD*/"Already used!\n"); 46 | return; 47 | } 48 | bp_04 |= (1 << bp_10); 49 | } 50 | if(D_010E[D_943E] != bp_04) { 51 | u4_puts(D_00EE); 52 | return; 53 | } 54 | switch(D_943E) { 55 | case 0: 56 | if(TST_MSK(Party.mItems, ST_KEY_T)) { 57 | u4_puts(D_00EE); 58 | return; 59 | } 60 | SET_MSK(Party.mItems, ST_KEY_T); 61 | break; 62 | case 1: 63 | if(TST_MSK(Party.mItems, ST_KEY_L)) { 64 | u4_puts(D_00EE); 65 | return; 66 | } 67 | SET_MSK(Party.mItems, ST_KEY_L); 68 | break; 69 | case 2: 70 | if(TST_MSK(Party.mItems, ST_KEY_C)) { 71 | u4_puts(D_00EE); 72 | return; 73 | } 74 | SET_MSK(Party.mItems, ST_KEY_C); 75 | break; 76 | } 77 | u4_puts(/*D_00BC*/"Thou doth find one third of the Three Part Key!\n"); 78 | } 79 | 80 | char *D_0284[] = { 81 | /*D_0111*/"Truth", 82 | /*D_0117*/"Love", 83 | /*D_011C*/"Courage", 84 | /*D_0124*/"Truth and Love", 85 | /*D_0133*/"Love and Courage", 86 | /*D_0144*/"Courage and Truth", 87 | /*D_0156*/"Truth, Love and Courage", 88 | /*D_016E*/"\nA voice rings out: What Virtue exists independently of Truth, Love and Courage" 89 | }; 90 | 91 | /*use stone(s)*/ 92 | C_0311() { 93 | int bp_02; 94 | 95 | if(Party.mStones) { 96 | char bp_10[14]; 97 | if(CurMode != MOD_COM_ROOM && CurMode != MOD_DUNGEON) 98 | u4_puts(/*D_01BF*/"No place to Use them!\n"); 99 | if(CurMode == MOD_DUNGEON) { 100 | if(tile_cur != 0xb0 || Party._loc != 0x18) { 101 | u4_puts(D_00EE); 102 | return; 103 | } 104 | if(Party._z != 7) 105 | u4_puts(/*D_01D6*/"\nAs thou doth approach, a voice rings out: What virtue dost stem from "); 106 | u4_puts(D_0284[Party._z]); 107 | u4_puts(/*D_021D*/"?\n\n"); 108 | u4_gets(bp_10, 13); 109 | Gra_CR(); 110 | if(strnicmp(bp_10, D_1E98[151 + Party._z], 14)) { 111 | C_03A1: 112 | if(bp_10[0]) 113 | u4_puts(D_00EE); 114 | return; 115 | } 116 | u4_puts(/*D_0221*/"\nThe Voice says: Use thy Stone.\n\nColor:\n"); 117 | u4_gets(bp_10, 11); 118 | Gra_CR(); 119 | bp_02 = 7; 120 | while( 121 | strnicmp(bp_10, D_0884[bp_02], 12) && 122 | --bp_02 >= 0 123 | ); 124 | if(bp_02 == -1) 125 | goto C_03A1; 126 | if(!TST_MSK(Party.mStones, bp_02)) { 127 | u4_puts(/*D_024A*/"\nYou have none!\n\n"); 128 | return; 129 | } 130 | if(Party._z != bp_02) { 131 | u4_puts(D_00EE); 132 | return; 133 | } 134 | if(Party._z == 7) { 135 | C_31F4();/*last phase of game*/ 136 | return; 137 | } 138 | D_8742._map.x8x8x8[Party._z][Party._y][Party._x] = 0x20; 139 | u4_puts(/*D_025C*/"\nThe altar changes before thyne eyes!\n"); 140 | } else { 141 | C_01E1(); 142 | } 143 | } else { 144 | u4_puts(D_0100); 145 | } 146 | } 147 | 148 | /*use key(s)*/ 149 | C_044C() { 150 | if( 151 | ((Party.mItems >> ST_KEY_T) & 1) | 152 | ((Party.mItems >> ST_KEY_L) & 1) | 153 | ((Party.mItems >> ST_KEY_C) & 1) 154 | ) 155 | u4_puts("No place to Use them!\n"); 156 | else 157 | u4_puts(D_0100); 158 | } 159 | 160 | /*use bell*/ 161 | C_0487() { 162 | if(!TST_MSK(Party.mItems, ST_BELL)) { 163 | u4_puts(D_0100); 164 | return; 165 | } 166 | if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9) { 167 | u4_puts(D_00EE); 168 | return; 169 | } 170 | SET_MSK(Party.mItems, ST_USE_BELL); 171 | u4_puts("The Bell rings on and on!\n"); 172 | } 173 | 174 | /*use book*/ 175 | C_04C0() { 176 | if(!TST_MSK(Party.mItems, ST_BOOK)) { 177 | u4_puts(D_0100); 178 | return; 179 | } 180 | if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9 || 181 | !TST_MSK(Party.mItems, ST_USE_BELL) 182 | ) { 183 | u4_puts(D_00EE); 184 | return; 185 | } 186 | SET_MSK(Party.mItems, ST_USE_BOOK); 187 | u4_puts("The words resonate with the ringing!\n"); 188 | } 189 | 190 | /*use candle*/ 191 | C_0501() { 192 | if(!TST_MSK(Party.mItems, ST_CANDLE)) { 193 | u4_puts(D_0100); 194 | return; 195 | } 196 | if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9 || 197 | !TST_MSK(Party.mItems, ST_USE_BOOK) 198 | ) { 199 | u4_puts(D_00EE); 200 | return; 201 | } 202 | SET_MSK(Party.mItems, ST_USE_CANDLE); 203 | u4_puts("As you light the Candle the Earth Trembles!\n"); 204 | sound(6); 205 | shakefx(); 206 | } 207 | 208 | /*use horn*/ 209 | C_0553() { 210 | if(!TST_MSK(Party.mItems, ST_HORN)) { 211 | u4_puts(D_0100); 212 | return; 213 | } 214 | if(Party._loc != 0) { 215 | u4_puts(D_00EE); 216 | return; 217 | } 218 | u4_puts("The Horn sounds an eerie tone!\n"); 219 | spell_sta = 1; 220 | spell_cnt = 10; 221 | dspl_Stats(); 222 | } 223 | 224 | /*use wheel*/ 225 | C_058C() { 226 | if(!TST_MSK(Party.mItems, ST_WHEEL)) { 227 | u4_puts(D_0100); 228 | return; 229 | } 230 | if(Party._loc != 0 || Party._tile > TIL_13 || Party._ship != 50) { 231 | u4_puts(D_00EE); 232 | return; 233 | } 234 | u4_puts("Once mounted, the Wheel glows with a blue light!\n"); 235 | Party._ship = 99; 236 | dspl_Stats(); 237 | } 238 | 239 | /*use skull*/ 240 | C_05CE() { 241 | int bp_02; 242 | 243 | if(!TST_MSK(Party.mItems, ST_SKULL)) { 244 | u4_puts(D_0100); 245 | return; 246 | } 247 | if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9) { 248 | u4_puts("\nYou hold the evil Skull of Mondain the Wizard aloft....\n"); 249 | sound(6); shakefx(); 250 | Gra_09(); 251 | sound(6); shakefx(); 252 | Gra_09(); 253 | sound(6); shakefx(); 254 | if(CurMode >= MOD_COMBAT) { 255 | for(bp_02 = 31; bp_02 >= 0; bp_02 --) { 256 | if(D_8742._npc._tile[bp_02] != TIL_5E) 257 | D_8742._npc._tile[bp_02] = D_8742._npc._gtile[bp_02] = 0; 258 | } 259 | for(bp_02 = 15; bp_02 >= 0; bp_02 --) { 260 | if(Fighters._tile[bp_02] != TIL_5E) 261 | Fighters._tile[bp_02] = Fighters._gtile[bp_02] = 0; 262 | } 263 | } else { 264 | for(bp_02 = (Party._loc == 0)?7:31; bp_02 >= 0; bp_02 --) { 265 | if(D_8742._npc._tile[bp_02] != TIL_5E) 266 | D_8742._npc._tile[bp_02] = D_8742._npc._gtile[bp_02] = 0; 267 | } 268 | } 269 | /*C_06B2:*/ 270 | t_callback(); 271 | karma_dec((char *)&(Party._hones), 5); 272 | karma_dec((char *)&(Party._compa), 5); 273 | karma_dec((char *)&(Party._valor), 5); 274 | karma_dec((char *)&(Party._justi), 5); 275 | karma_dec((char *)&(Party._sacri), 5); 276 | karma_dec((char *)&(Party._honor), 5); 277 | karma_dec((char *)&(Party._spiri), 5); 278 | karma_dec((char *)&(Party._humil), 5); 279 | dspl_Stats(); 280 | } else { 281 | u4_puts("\nYou cast the Skull of Mondain into the Abyss!\n"); 282 | SET_MSK(Party.mItems, ST_CAST_SKULL); 283 | karma_inc((char *)&(Party._hones), 10); 284 | karma_inc((char *)&(Party._compa), 10); 285 | karma_inc((char *)&(Party._valor), 10); 286 | karma_inc((char *)&(Party._justi), 10); 287 | karma_inc((char *)&(Party._sacri), 10); 288 | karma_inc((char *)&(Party._honor), 10); 289 | karma_inc((char *)&(Party._spiri), 10); 290 | karma_inc((char *)&(Party._humil), 10); 291 | sound(6); shakefx(); 292 | Gra_09(); 293 | sound(6); shakefx(); 294 | Gra_09(); 295 | sound(6); shakefx(); 296 | } 297 | RST_MSK(Party.mItems, ST_SKULL); 298 | } 299 | 300 | struct { 301 | char *_00; 302 | void (*_02)(); 303 | } D_0434[] = { 304 | {/*D_03D5*/"stone", C_0311}, 305 | {/*D_03DB*/"stones", C_0311}, 306 | {/*D_03E2*/"bell", C_0487}, 307 | {/*D_03E7*/"book", C_04C0}, 308 | {/*D_03EC*/"candle", C_0501}, 309 | {/*D_03F3*/"key", C_044C}, 310 | {/*D_03F7*/"keys", C_044C}, 311 | {/*D_03FC*/"horn", C_0553}, 312 | {/*D_0401*/"wheel", C_058C}, 313 | {/*D_0407*/"skull", C_05CE}, 314 | {/*D_040D*/"", 0} 315 | }; 316 | 317 | /*C_07AE*/CMD_Use() { 318 | register int si; 319 | char bp_0e[12]; 320 | 321 | u4_puts("Use which item:\n"); 322 | u4_gets(bp_0e, 11); 323 | Gra_CR(); 324 | for(si = 0; D_0434[si]._00[0]; si++) { 325 | if(strnicmp(D_0434[si]._00, bp_0e, 12) == 0) { 326 | (*(D_0434[si]._02))(); 327 | return; 328 | } 329 | } 330 | u4_puts("Not a Usable item!\n"); 331 | } 332 | -------------------------------------------------------------------------------- /SRC/U4_Z.C: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultima IV - Quest Of The Avatar 3 | * (c) Copyright 1987 Lord British 4 | * reverse-coded by Ergonomy Joe in 2012 5 | */ 6 | 7 | #include "u4.h" 8 | 9 | #include 10 | 11 | C_45B5() 12 | { 13 | for( ;txt_Y <= 8; txt_Y ++) { 14 | txt_X = 24; 15 | u4_puts(/*D_18C6*/" "); 16 | } 17 | } 18 | 19 | /*display centered string*/ 20 | C_45D6(si/*bp06*/, bp04) 21 | register char *si; 22 | unsigned bp04; 23 | { 24 | register int di; 25 | 26 | di = strlen(si); 27 | if(di > 12) 28 | di = 12; 29 | di -= (di & 1); 30 | 31 | txt_X = (di>=8) + ((12 - di) / 2) + bp04 + 25; 32 | if(txt_Y == 0) { 33 | txt_X --; 34 | u4_putc(0x10); 35 | } 36 | u4_puts(si); 37 | if(txt_Y == 0) 38 | u4_putc(0x11); 39 | } 40 | 41 | C_4649() 42 | { 43 | unsigned bp_02, bp_04; 44 | 45 | bp_02 = txt_Y; 46 | bp_04 = txt_X; 47 | txt_Y = 0; 48 | txt_X = 24; 49 | do 50 | Gra_putchar('\r'); 51 | while(++txt_X < 39); 52 | txt_Y = bp_02; 53 | txt_X = bp_04; 54 | } 55 | 56 | C_4689(bp04) 57 | int bp04; 58 | { 59 | register struct tChara *si; 60 | 61 | si = &(Party.chara[bp04]); 62 | txt_Y = 0; C_45D6(si->_name, 0); 63 | txt_X = 24; 64 | txt_Y = 1; u4_putc(si->p_24); 65 | txt_Y = 1; C_45D6(D_1E98[77 + si->_class], 0); 66 | txt_X = 38; u4_putc(si->_stat); 67 | txt_X = 25; 68 | txt_Y = 3; u4_puts(/*D_18D6*/"MP:"); u4_putl(si->_MP, 2, '0'); 69 | txt_X = 32; u4_puts(/*D_18DA*/"LV:"); u4_putc((si->_HP[1]/100)+'0'); 70 | txt_X = 24; 71 | txt_Y = 4; u4_puts(/*D_18DE*/"STR:"); u4_putl(si->_str, 2, '0'); 72 | txt_X = 32; u4_puts(/*D_18E3*/"HP:"); u4_putl(si->_HP[0], 4, '0'); 73 | txt_X = 24; 74 | txt_Y = 5; u4_puts(/*D_18E7*/"DEX:"); u4_putl(si->_dex, 2, '0'); 75 | txt_X = 32; u4_puts(/*D_18EC*/"HM:"); u4_putl(si->_HP[1], 4, '0'); 76 | txt_X = 24; 77 | txt_Y = 6; u4_puts(/*D_18F0*/"INT:"); u4_putl(si->_int, 2, '0'); 78 | txt_X = 32; u4_puts(/*D_18F5*/"EX:"); u4_putl(si->_XP, 4, '0'); 79 | txt_Y = 7; 80 | txt_X = 24; u4_puts(/*D_18F9*/"W:"); u4_puts(D_1E98[37 + si->_weapon]); 81 | txt_Y = 8; 82 | txt_X = 24; u4_puts(/*D_18FC*/"A:"); u4_puts(D_1E98[53 + si->_armor]); 83 | } 84 | 85 | C_4832() 86 | { 87 | register int si; 88 | 89 | txt_Y = 0; 90 | C_45D6(/*D_18FF*/"Weapons", 0); 91 | txt_Y = 1; 92 | txt_X = 24; 93 | u4_puts(/*D_1907*/"A-Hands"); 94 | txt_Y = 2; 95 | txt_X = 24; 96 | si = 1; 97 | do { 98 | if(Party._weapons[si]) { 99 | u4_putc(si+'A'); 100 | u4_putl(Party._weapons[si], 2, '-'); 101 | u4_putc('-'); 102 | u4_puts(D_1E98[61 + si]); 103 | txt_X = (txt_X - 1) & ~7; 104 | if(++txt_Y == 9) { 105 | txt_Y = 1; 106 | txt_X += 8; 107 | } 108 | } 109 | } while(++si < 0x10); 110 | while(txt_X < 40) { 111 | u4_puts(/*D_190F*/" "); 112 | txt_X = (txt_X - 1) & ~7; 113 | if(++txt_Y == 9) { 114 | txt_Y = 1; 115 | txt_X += 8; 116 | } 117 | } 118 | } 119 | 120 | C_48F8() 121 | { 122 | register int si; 123 | 124 | txt_Y = 0; 125 | C_45D6(/*D_1917*/"Armour", 0); 126 | txt_Y = 1; 127 | txt_X = 24; 128 | u4_puts(/*D_191E*/"A -No Armour"); 129 | txt_Y = 2; 130 | for(si = 1; si < 8; si ++) { 131 | if(Party._armors[si]) { 132 | txt_X = 24; 133 | u4_putc(si + 'A'); 134 | u4_putl(Party._armors[si], 2, '-'); 135 | u4_putc('-'); 136 | u4_puts(D_1E98[53 + si]); 137 | while(txt_X != 39) 138 | u4_putc(' '); 139 | txt_Y ++; 140 | } 141 | } 142 | C_45B5(); 143 | } 144 | 145 | C_4987() 146 | { 147 | txt_Y = 0; 148 | C_45D6(/*D_192C*/"Equipment", -1); 149 | 150 | txt_X = 24; txt_Y = 1; 151 | u4_putl(Party._torches, 2, ' '); u4_puts(/*D_1936*/" Torches"); 152 | 153 | txt_X = 24; txt_Y ++; 154 | u4_putl(Party._gems, 2, ' '); u4_puts(/*D_193F*/" Gems"); 155 | 156 | txt_X = 24; txt_Y ++; 157 | u4_putl(Party._keys, 2, ' '); u4_puts(/*D_1945*/" Keys"); 158 | 159 | if(Party._sextants) { 160 | txt_X = 24; txt_Y = 4; 161 | u4_putl(Party._sextants, 2, ' '); u4_puts(/*D_194B*/" Sextants"); 162 | } 163 | txt_Y ++; 164 | C_45B5(); 165 | } 166 | 167 | char D_199A[] = "BYRGOPWB"; 168 | char D_19A4[] = "HCVJSHSH"; 169 | 170 | C_4A3D() 171 | { 172 | register int si; 173 | 174 | txt_Y = 0; 175 | C_45D6(/*D_1955*/"Items", 0); 176 | txt_Y = 1; 177 | if(Party.mStones) { 178 | txt_X = 24; 179 | u4_puts(/*D_195B*/"Stones:"); 180 | si = 0; 181 | do { 182 | if(TST_MSK(Party.mStones, si)) 183 | u4_putc(D_199A[si]); 184 | } while(++si < 8); 185 | txt_Y ++; 186 | } 187 | if(Party.mRunes) { 188 | txt_X = 24; 189 | u4_puts(/*D_1963*/"Runes:"); 190 | si = 0; 191 | do { 192 | if(TST_MSK(Party.mRunes, si)) 193 | u4_putc(D_19A4[si]); 194 | } while(++si < 8); 195 | txt_Y ++; 196 | } 197 | if(TST_MSK(Party.mItems, ST_BELL) || TST_MSK(Party.mItems, ST_BOOK) || TST_MSK(Party.mItems, ST_CANDLE)) { 198 | txt_X = 24; 199 | if(TST_MSK(Party.mItems, ST_BELL)) 200 | u4_puts(/*D_196A*/"Bell "); 201 | if(TST_MSK(Party.mItems, ST_BOOK)) 202 | u4_puts(/*D_1970*/"Book "); 203 | if(TST_MSK(Party.mItems, ST_CANDLE)) { 204 | u4_puts(/*D_1976*/"Candl"); 205 | if(!TST_MSK(Party.mItems, ST_BOOK) || !TST_MSK(Party.mItems, ST_BELL)) 206 | u4_putc('e'); 207 | } 208 | txt_Y ++; 209 | } 210 | if(TST_MSK(Party.mItems, ST_KEY_C) || TST_MSK(Party.mItems, ST_KEY_L) || TST_MSK(Party.mItems, ST_KEY_T)) { 211 | txt_X = 24; 212 | u4_puts(/*D_197C*/"3 Part Key:"); 213 | if(TST_MSK(Party.mItems, ST_KEY_T)) 214 | u4_putc('T'); 215 | if(TST_MSK(Party.mItems, ST_KEY_L)) 216 | u4_putc('L'); 217 | if(TST_MSK(Party.mItems, ST_KEY_C)) 218 | u4_putc('C'); 219 | txt_Y ++; 220 | } 221 | if(TST_MSK(Party.mItems, ST_HORN)) { 222 | txt_X = 24; 223 | u4_puts(/*D_1988*/"Horn"); 224 | txt_Y ++; 225 | } 226 | if(TST_MSK(Party.mItems, ST_WHEEL)) { 227 | txt_X = 24; 228 | u4_puts(/*D_198D*/"Wheel"); 229 | txt_Y ++; 230 | } 231 | if(TST_MSK(Party.mItems, ST_SKULL)) { 232 | txt_X = 24; 233 | u4_puts(/*D_1993*/"Skull"); 234 | } 235 | } 236 | 237 | C_4BC7() 238 | { 239 | register int si; 240 | 241 | txt_Y = 0; 242 | C_45D6(/*D_19AD*/"Reagents", 0); 243 | txt_Y = 1; 244 | si = 0; 245 | do { 246 | if(Party._reagents[si]) { 247 | txt_X = 24; 248 | u4_putc(si+'A'); 249 | u4_putl(Party._reagents[si], 2, '-'); 250 | u4_putc('-'); 251 | u4_puts(D_1E98[93 + si]); 252 | while(txt_X != 39) 253 | u4_putc(' '); 254 | txt_Y ++; 255 | } 256 | } while(++si < 8); 257 | C_45B5(); 258 | } 259 | 260 | C_4C42() 261 | { 262 | register int si; 263 | 264 | txt_Y = 0; 265 | C_45D6(/*D_19B6*/"Mixtures", 0); 266 | txt_Y = 1; 267 | txt_X = 24; 268 | si = 0; 269 | do { 270 | if(Party._mixtures[si]) { 271 | u4_putc(si+'A'); 272 | u4_putc('-'); 273 | u4_putl(Party._mixtures[si], 2, '0'); 274 | txt_X -= 4; 275 | txt_Y ++; 276 | if(txt_Y == 9) { 277 | txt_Y = 1; 278 | txt_X += 5; 279 | if(txt_X >= 39) 280 | return; 281 | } 282 | } 283 | } while(++si < 26); 284 | } 285 | 286 | typedef z_handler(int); 287 | typedef z_handler *pZ_handler; 288 | 289 | pZ_handler D_19C0[] = { 290 | C_4689,C_4689,C_4689,C_4689, 291 | C_4689,C_4689,C_4689,C_4689, 292 | C_4832, 293 | C_48F8, 294 | C_4987, 295 | C_4A3D, 296 | C_4BC7, 297 | C_4C42 298 | }; 299 | 300 | C_4CC1(bp04) 301 | int bp04; 302 | { 303 | unsigned bp_02, bp_04; 304 | 305 | bp_02 = txt_Y; 306 | bp_04 = txt_X; 307 | do { 308 | register int si; 309 | 310 | Gra_13(); 311 | C_4649(); 312 | (*D_19C0[bp04])(bp04); 313 | while(!u_kbhit()); 314 | switch(si = u_kbread()) { 315 | case KBD_1: 316 | case KBD_2: 317 | case KBD_3: 318 | case KBD_4: 319 | case KBD_5: 320 | case KBD_6: 321 | case KBD_7: 322 | case KBD_8: 323 | if((si&0xf) <= Party.f_1d8) 324 | bp04 = (si&0xf) - 1; 325 | else 326 | sound(1); 327 | break; 328 | case KBD_RIGHT: case KBD_DOWN: 329 | bp04 = (bp04 + 1) % 14; 330 | if(bp04 == Party.f_1d8) 331 | bp04 = 8; 332 | break; 333 | case KBD_UP: case KBD_LEFT: 334 | if(bp04 == 8) 335 | bp04 = Party.f_1d8 - 1; 336 | else 337 | bp04 = (bp04 + 13) % 14; 338 | break; 339 | case KBD_PGUP: 340 | if(bp04 >= 1 && bp04 <= 8) 341 | bp04 = 0; 342 | else if(bp04 > 8 && bp04 <= 13) 343 | bp04 = 8; 344 | else bp04 = 13; 345 | break; 346 | case KBD_HOME: 347 | bp04 = 0; 348 | break; 349 | case KBD_0: 350 | bp04 = 8; 351 | break; 352 | case KBD_PGDN: 353 | if(bp04 >= 0 && bp04 <= 7) 354 | bp04 = 8; 355 | else if(bp04 >= 8 && bp04 <= 12) 356 | bp04 = 13; 357 | else 358 | bp04 = 0; 359 | break; 360 | case KBD_END: 361 | bp04 = 13; 362 | break; 363 | default: 364 | bp04 = -1; 365 | } 366 | } while(bp04 != -1); 367 | C_4649(); 368 | Gra_13(); 369 | dspl_Stats(); 370 | txt_Y = bp_02; 371 | txt_X = bp_04; 372 | } 373 | 374 | /*C_4E45*/CMD_Ztats() 375 | { 376 | if(CurMode >= MOD_COMBAT) { 377 | u4_puts(/*D_19DC*/"Ztats\n"); 378 | Gra_11(activeChara); 379 | C_4CC1(activeChara); 380 | Gra_11(activeChara); 381 | } else { 382 | int bp_02; 383 | 384 | bp_02 = AskChara(/*D_19E3*/"Ztats for:\x12\x12\b"); 385 | if(bp_02 != -1) 386 | C_4CC1((bp_02 == -2)?8:bp_02); 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /SRC/UTIL2.ASM: -------------------------------------------------------------------------------- 1 | EXTRN u4_puts:NEAR 2 | EXTRN u4_putc:NEAR 3 | EXTRN Gra_putchar:NEAR 4 | EXTRN t_callback:NEAR 5 | 6 | EXTRN MSG_DSKERR:BYTE 7 | EXTRN MSG_SYSERR:BYTE 8 | 9 | EXTRN speed_info:WORD 10 | 11 | EXTRN Party:BYTE 12 | 13 | EXTRN txt_X:WORD 14 | EXTRN txt_Y:WORD 15 | 16 | PUBLIC cursor_rate 17 | 18 | 19 | DGROUP GROUP _DATA,_BSS 20 | ;######################################## 21 | _DATA SEGMENT PUBLIC WORD 'DATA' 22 | ASSUME DS:DGROUP 23 | ;---------------------------------------- 24 | cursor_rate dw 0 ;D_0672 25 | D_0674 dw 0 26 | D_0676 dw 0FFFFh ;display cursor flag 27 | ;---------------------------------------- 28 | _DATA ENDS 29 | ;######################################## 30 | _BSS SEGMENT PUBLIC WORD 'BSS' 31 | ;---------------------------------------- 32 | ;random seeds 33 | PUBLIC seed_128 34 | seed_128 db 10h dup(?) ;D_8732 35 | ;-- struct t_500 -- 36 | PUBLIC D_8742 37 | D_8742 db 500h dup(?) 38 | ;-- 39 | D_8C42 db ? ;cursor state {0, 1, 2, 3} 40 | D_8C43 dw ? ;cursor update counter 41 | db ? ;padding? 42 | ;---------------------------------------- 43 | _BSS ENDS 44 | ;######################################## 45 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 46 | ASSUME CS:_TEXT 47 | ;----------------------------------------C_16CD 48 | ;[bp+04] wait delay in seconds 49 | ;[bp+06] allow interruption/prompt 50 | PUBLIC _u_delay 51 | _u_delay PROC NEAR 52 | PUSH BP 53 | MOV BP,SP 54 | PUSH SI 55 | ;-- 56 | MOV D_8C43,1 57 | ;-- 58 | MOV AX,cursor_rate 59 | MOV D_0674,AX 60 | ;-- 61 | MOV AH,2Ch ;get time 62 | INT 21h 63 | MOV DL,DH ;seconds 64 | MOV DH,0 65 | MOV SI,DX 66 | ADD SI,[BP+04] 67 | CMP SI,60 68 | JB C_1701 69 | ;-- -- 70 | SUB SI,60 71 | ;-- 72 | TEST WORD PTR [BP+06],0FFFFh 73 | JZ C_1710 ;cannot interrupt 74 | CALL _u_kbhit 75 | TEST AX,0FFFFh 76 | JNZ C_176C ;key has been pressed 77 | C_1701: ;-- 78 | TEST WORD PTR [BP+06],0FFFFh 79 | JZ C_1710 ;cannot interrupt 80 | CALL _u_kbhit 81 | TEST AX,0FFFFh 82 | JNZ C_175D ;key has been pressed 83 | C_1710: ;-- 84 | CALL t_callback 85 | ;============ 86 | ;== cursor == 87 | ;============ 88 | MOV AX,[BP+06] 89 | AND AX,D_0676 90 | JZ C_1751 91 | ;-- update shape 92 | MOV AX,D_0674 93 | CMP AX,cursor_rate 94 | JNZ C_173D 95 | DEC D_8C43 96 | JNZ C_1751 97 | DEC D_8C42 98 | AND D_8C42,3 99 | ;-- display 100 | MOV AL,D_8C42 101 | ADD AL,1Ch 102 | PUSH AX 103 | CALL Gra_putchar 104 | C_173D: ;-- reload cursor counter 105 | MOV AX,1 106 | ADD AX,cursor_rate 107 | MUL speed_info 108 | MOV D_8C43,AX 109 | ;-- 110 | MOV AX,cursor_rate 111 | MOV D_0674,AX 112 | ;======= 113 | C_1751: ;== == 114 | ;======= 115 | MOV AH,2Ch ;get time 116 | INT 21h 117 | MOV BL,DH ;seconds 118 | MOV BH,0 119 | CMP SI,BX 120 | JNZ C_1701 121 | C_175D: ;-- 122 | MOV AX,[BP+06] 123 | AND AX,D_0676 124 | JZ C_176C 125 | ;-- delete cursor -- 126 | MOV AL,' ' 127 | PUSH AX 128 | CALL Gra_putchar 129 | C_176C: ;-- 130 | POP SI 131 | MOV SP,BP 132 | POP BP 133 | RET 134 | _u_delay ENDP 135 | ;----------------------------------------C_1771 136 | PUBLIC u_rand_a 137 | u_rand_a PROC NEAR 138 | PUSHF 139 | PUSH CX 140 | PUSH DI 141 | PUSH ES 142 | ;-- 143 | MOV AX,DS 144 | MOV ES,AX 145 | STD 146 | ;-- 147 | MOV CX,0Eh 148 | MOV DI,OFFSET DGROUP:seed_128 + 0Eh 149 | CLC 150 | MOV AL,[DI+01] 151 | C_1784: ADC AL,[DI] 152 | STOSB 153 | LOOP C_1784 154 | ADC [DI],AL 155 | ;-- 156 | MOV CX,10h 157 | MOV DI,OFFSET DGROUP:seed_128 + 10h 158 | C_1791: DEC DI 159 | INC BYTE PTR [DI] 160 | LOOPZ C_1791 161 | ;-- 162 | POP ES 163 | POP DI 164 | POP CX 165 | POPF 166 | ;-- 167 | MOV AL,seed_128[0] 168 | MOV AH,0 169 | TEST AL,0FFh 170 | ;-- 171 | RET 172 | u_rand_a ENDP 173 | ;----------------------------------------C_17A2 174 | PUBLIC u_rand_b 175 | u_rand_b PROC NEAR 176 | MOV AL,seed_128[3] 177 | ADC AL,seed_128[2] 178 | MOV seed_128[2],AL 179 | XOR seed_128[1],AL 180 | MOV AL,seed_128[1] 181 | ADC AL,seed_128[0] 182 | ROR AL,1 183 | MOV seed_128[0],AL 184 | MOV seed_128[3],AL 185 | MOV AH,0 186 | TEST AX,0FFFFh 187 | RET 188 | u_rand_b ENDP 189 | ;----------------------------------------C_17C5 190 | ;increment Party.f_000 191 | ;returns: 192 | ; 1 if key is pressed 193 | ; 0 if not 194 | PUBLIC _u_kbhit 195 | _u_kbhit PROC NEAR 196 | CALL u_rand_a 197 | ;-- increment (unsigned long)Party.f_000 198 | INC WORD PTR Party 199 | JNZ C_17D2 200 | INC WORD PTR Party+2 201 | C_17D2: ;-- 202 | MOV AH,1 ;get keyboard status 203 | INT 16h 204 | JZ C_17EB ;-- no key pressed 205 | CMP AX,2E03h ; key code ? 206 | JZ C_17E7 ;remove 207 | TEST AX,0FFFFh 208 | JZ C_17E7 ;remove 209 | ;-- returns 1 210 | MOV AX,1 211 | JMP SHORT C_17F1 212 | C_17E7: ;-- remove 213 | MOV AH,0 ;wait for keypress and read character 214 | INT 16h 215 | C_17EB: ;-- 216 | CALL t_callback 217 | ;-- returns 0 218 | MOV AX,0 219 | C_17F1: ;-- -- 220 | OR AX,AX 221 | ;-- 222 | RET 223 | _u_kbhit ENDP 224 | ;----------------------------------------C_17F4 225 | ;get keyboard scancode 226 | ;wait if necessary 227 | PUBLIC _u_kbread 228 | _u_kbread PROC NEAR 229 | ;-- wait a very long time, 230 | ;-- and allow key interrupt 231 | MOV AX,8081h 232 | PUSH AX 233 | PUSH AX 234 | CALL _u_delay 235 | ADD SP,4 236 | ;-- 237 | MOV AH,0 238 | INT 16h 239 | ;-- 240 | RET 241 | _u_kbread ENDP 242 | ;----------------------------------------C_1804 243 | ;wait while key pressed 244 | PUBLIC _u_kbflush 245 | _u_kbflush PROC NEAR 246 | ;-- allow interrupts 247 | STI 248 | NOP 249 | NOP 250 | NOP 251 | CLI 252 | ;-- 253 | CALL _u_kbhit 254 | JZ C_1813 255 | CALL _u_kbread 256 | JMP _u_kbflush 257 | C_1813: ;-- 258 | RET 259 | _u_kbflush ENDP 260 | ;---------------------------------------- 261 | ;get current default drive 262 | PUBLIC C_1814 263 | C_1814 PROC NEAR 264 | MOV AH,19h ;get current default drive 265 | INT 21h 266 | INC AL 267 | MOV AH,0 268 | ;-- 269 | RET 270 | C_1814 ENDP 271 | ;---------------------------------------- 272 | ;select disk 273 | PUBLIC C_181D 274 | C_181D PROC NEAR 275 | PUSH BP 276 | MOV BP,SP 277 | ;-- 278 | MOV DL,[BP+04] 279 | DEC DL 280 | MOV AH,0Eh ;select disk 281 | INT 21h 282 | MOV AH,0 283 | ;-- 284 | POP BP 285 | RET 2 286 | C_181D ENDP 287 | ;---------------------------------------- 288 | ;test file 289 | PUBLIC C_182F 290 | C_182F PROC NEAR 291 | PUSH BP 292 | MOV BP,SP 293 | ;-- 294 | MOV DX,[BP+04] 295 | MOV AL,0 296 | MOV AH,3Dh ;open file 297 | INT 21h 298 | JNB C_1842 299 | ;-- 300 | MOV AX,0 301 | JMP SHORT C_184B 302 | C_1842: ;-- 303 | MOV BX,AX 304 | MOV AH,3Eh ;close file 305 | INT 21h 306 | ;-- 307 | MOV AX,1 308 | C_184B: ;-- 309 | POP BP 310 | RET 2 311 | C_182F ENDP 312 | ;---------------------------------------- 313 | ;piracy check function ? 314 | ;succes => 0 315 | ;failure => -1 316 | PUBLIC C_184F 317 | C_184F PROC NEAR 318 | PUSHF 319 | PUSH BX 320 | PUSH AX 321 | PUSH CX 322 | PUSH DX 323 | PUSH DS 324 | PUSH ES 325 | ;-- 326 | PUSH BP 327 | MOV BP,SP 328 | PUSH DI 329 | PUSH SI 330 | ;-- set drive 331 | MOV AH,19h ;get current default drive 332 | INT 21h 333 | CMP AL,1 334 | JBE C_1865 335 | MOV AL,0 336 | C_1865: MOV DL,AL ;drive 337 | ;-- 338 | MOV SI,4 ;4 tries 339 | MOV CL,10h ;from sector 10h 340 | nextSector: ;-- read one sector to c000:0000 341 | MOV AX,(2 SHL 8) OR 1 ;read 1 sector 342 | MOV DH,0 ;head 0 343 | MOV CH,9 ;track 9 344 | MOV BX,0C000h 345 | MOV ES,BX 346 | XOR BX,BX ;to c000:0000 347 | INT 13h 348 | JB C_1887 349 | ;-- one track success 350 | DEC CL 351 | JZ C_1890 ;finished 352 | MOV SI,4 ;4 tries 353 | JMP nextSector 354 | C_1887: ;-- failed this sector 355 | DEC SI 356 | JNZ nextSector 357 | ;-- failure 358 | MOV BX,0FFFFh 359 | JMP C_1893 ;(+nop) 360 | C_1890: ;-- success 361 | MOV BX,0 362 | C_1893: ;-- 363 | POP SI 364 | POP DI 365 | MOV SP,BP 366 | POP BP 367 | ;-- 368 | POP ES 369 | POP DS 370 | POP DX 371 | POP CX 372 | POP AX 373 | MOV AL,BL 374 | POP BX 375 | POPF 376 | RET 377 | C_184F ENDP 378 | ;---------------------------------------- 379 | ;set critical error handler 380 | PUBLIC C_18A2 381 | C_18A2 PROC NEAR 382 | PUSH DS 383 | ;-- 384 | LEA DX,INT_18B3 385 | MOV AX,CS 386 | MOV DS,AX 387 | MOV AH,25h ;set new interrupt vector 388 | MOV AL,24h ;Critical Error 389 | INT 21h 390 | ;-- 391 | POP DS 392 | RET 393 | C_18A2 ENDP 394 | ;---- 395 | INT_18B3: 396 | PUSH BP 397 | MOV BP,SP 398 | PUSH BX 399 | PUSH CX 400 | PUSH DX 401 | PUSH SI 402 | PUSH DS 403 | PUSH ES 404 | ;-- 405 | MOV BX,SS 406 | MOV DS,BX 407 | MOV ES,BX 408 | TEST AH,80h 409 | JNZ C_190C 410 | ;-- display disk error -- 411 | PUSH txt_Y 412 | PUSH txt_X 413 | MOV txt_Y,24 ;18h 414 | MOV txt_X,0 415 | ;-- 416 | LEA AX,MSG_DSKERR 417 | PUSH AX 418 | CALL u4_puts 419 | ;-- 420 | MOV AH,0 ;wait for keypress and read character 421 | INT 16h 422 | ;-- 423 | MOV txt_X,0 424 | MOV SI,39 ;27h 425 | C_18F0: ;-- 426 | MOV AX,' ' 427 | PUSH AX 428 | CALL u4_putc 429 | ;-- 430 | DEC SI 431 | JNZ C_18F0 432 | ;-- 433 | POP txt_X 434 | POP txt_Y 435 | ;-- -- 436 | POP ES 437 | POP DS 438 | POP SI 439 | POP DX 440 | POP CX 441 | POP BX 442 | POP BP 443 | MOV AL,1 444 | IRET 445 | C_190C: ;-- display fatal error 446 | LEA AX,MSG_SYSERR 447 | PUSH AX 448 | CALL u4_puts 449 | ;-- -- 450 | POP ES 451 | POP DS 452 | POP SI 453 | POP DX 454 | POP CX 455 | POP BX 456 | POP BP 457 | MOV AL,2 458 | IRET 459 | ;---------------------------------------- 460 | _TEXT ENDS 461 | ;######################################## 462 | END 463 | -------------------------------------------------------------------------------- /SRC-TITLE/UTIL2.ASM: -------------------------------------------------------------------------------- 1 | EXTRN u4_puts:NEAR 2 | EXTRN u4_putc:NEAR 3 | EXTRN Gra_putchar:NEAR 4 | EXTRN t_callback:NEAR 5 | 6 | EXTRN MSG_DSKERR:BYTE 7 | EXTRN MSG_SYSERR:BYTE 8 | 9 | EXTRN speed_info:WORD 10 | 11 | EXTRN Party:BYTE 12 | 13 | EXTRN txt_X:WORD 14 | EXTRN txt_Y:WORD 15 | 16 | PUBLIC cursor_rate 17 | PUBLIC D_31C0 18 | 19 | DGROUP GROUP _DATA,_BSS 20 | ;######################################## 21 | _DATA SEGMENT PUBLIC WORD 'DATA' 22 | ASSUME DS:DGROUP 23 | ;---------------------------------------- 24 | cursor_rate dw 0 ;D_31BC 25 | D_31BE dw 0 26 | D_31C0 dw 0FFFFh ;display cursor flag 27 | ;---------------------------------------- 28 | _DATA ENDS 29 | ;######################################## 30 | _BSS SEGMENT PUBLIC WORD 'BSS' 31 | ;---------------------------------------- 32 | ;random seeds 33 | PUBLIC seed_128 34 | seed_128 db 10h dup(?) ;D_6966 35 | ;-- struct t_500 -- 36 | PUBLIC D_6976 37 | D_6976 db 500h dup(?) 38 | ;-- 39 | D_6E76 db ? ;cursor state {0, 1, 2, 3} 40 | D_6E77 dw ? ;cursor update counter 41 | db ? ;padding? 42 | ;---------------------------------------- 43 | _BSS ENDS 44 | ;######################################## 45 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 46 | ASSUME CS:_TEXT 47 | ;----------------------------------------C_3149 48 | ;[bp+04] wait delay in seconds 49 | ;[bp+06] allow interruption/prompt 50 | PUBLIC _u_delay 51 | _u_delay PROC NEAR 52 | PUSH BP 53 | MOV BP,SP 54 | PUSH SI 55 | ;-- 56 | MOV D_6E77,1 57 | ;-- 58 | MOV AX,cursor_rate 59 | MOV D_31BE,AX 60 | ;-- 61 | MOV AH,2Ch ;get time 62 | INT 21h 63 | MOV DL,DH ;seconds 64 | MOV DH,0 65 | MOV SI,DX 66 | ADD SI,[BP+04] 67 | CMP SI,60 68 | JB C_317D 69 | ;-- -- 70 | SUB SI,60 71 | ;-- 72 | TEST WORD PTR [BP+06],0FFFFh 73 | JZ C_318C ;cannot interrupt 74 | CALL u_kbhit 75 | TEST AX,0FFFFh 76 | JNZ C_31E8 77 | C_317D: ;-- 78 | TEST WORD PTR [BP+06],0FFFFh 79 | JZ C_318C ;cannot interrupt 80 | CALL u_kbhit 81 | TEST AX,0FFFFh 82 | JNZ C_31D9 83 | C_318C: ;-- 84 | CALL t_callback 85 | ;============ 86 | ;== cursor == 87 | ;============ 88 | MOV AX,[BP+06] 89 | AND AX,D_31C0 90 | JZ C_31CD 91 | ;-- update shape 92 | MOV AX,D_31BE 93 | CMP AX,cursor_rate 94 | JNZ C_31B9 95 | DEC D_6E77 96 | JNZ C_31CD 97 | DEC D_6E76 98 | AND D_6E76,3 99 | ;-- display 100 | MOV AL,D_6E76 101 | ADD AL,1Ch 102 | PUSH AX 103 | CALL Gra_putchar 104 | C_31B9: ;-- reload cursor counter 105 | MOV AX,1 106 | ADD AX,cursor_rate 107 | MUL speed_info 108 | MOV D_6E77,AX 109 | ;-- 110 | MOV AX,cursor_rate 111 | MOV D_31BE,AX 112 | ;======= 113 | C_31CD: ;== == 114 | ;======= 115 | MOV AH,2Ch ;get time 116 | INT 21h 117 | MOV BL,DH ;seconds 118 | MOV BH,0 119 | CMP SI,BX 120 | JNZ C_317D 121 | C_31D9: ;-- 122 | MOV AX,[BP+06] 123 | AND AX,D_31C0 124 | JZ C_31E8 125 | ;-- delete cursor -- 126 | MOV AL,' ' 127 | PUSH AX 128 | CALL Gra_putchar 129 | C_31E8: ;-- 130 | POP SI 131 | MOV SP,BP 132 | POP BP 133 | RET 134 | _u_delay ENDP 135 | ;----------------------------------------C_31ED 136 | PUBLIC u_rand_a 137 | u_rand_a PROC NEAR 138 | PUSHF 139 | PUSH CX 140 | PUSH DI 141 | PUSH ES 142 | ;-- 143 | MOV AX,DS 144 | MOV ES,AX 145 | STD 146 | ;-- 147 | MOV CX,0Eh 148 | MOV DI,OFFSET DGROUP:seed_128 + 0Eh 149 | CLC 150 | MOV AL,[DI+01] 151 | C_3200: ADC AL,[DI] 152 | STOSB 153 | LOOP C_3200 154 | ADC [DI],AL 155 | ;-- 156 | MOV CX,10h 157 | MOV DI,OFFSET DGROUP:seed_128 + 10h 158 | C_320D: DEC DI 159 | INC BYTE PTR [DI] 160 | LOOPZ C_320D 161 | ;-- 162 | POP ES 163 | POP DI 164 | POP CX 165 | POPF 166 | ;-- 167 | MOV AL,seed_128[0] 168 | MOV AH,0 169 | TEST AL,0FFh 170 | ;-- 171 | RET 172 | u_rand_a ENDP 173 | ;----------------------------------------C_321E 174 | PUBLIC u_rand_b 175 | u_rand_b PROC NEAR 176 | MOV AL,seed_128[3] 177 | ADC AL,seed_128[2] 178 | MOV seed_128[2],AL 179 | XOR seed_128[1],AL 180 | MOV AL,seed_128[1] 181 | ADC AL,seed_128[0] 182 | ROR AL,1 183 | MOV seed_128[0],AL 184 | MOV seed_128[3],AL 185 | MOV AH,0 186 | TEST AX,0FFFFh 187 | RET 188 | u_rand_b ENDP 189 | ;----------------------------------------C_3241 190 | ;increment Party.f_000 191 | ;returns: 192 | ; 1 if key is pressed 193 | ; 0 if not 194 | PUBLIC u_kbhit 195 | u_kbhit PROC NEAR 196 | CALL u_rand_a 197 | ;-- increment (unsigned long)Party.f_000 198 | INC WORD PTR Party 199 | JNZ C_324E 200 | INC WORD PTR Party+2 201 | C_324E: ;-- 202 | MOV AH,1 ;get keyboard status 203 | INT 16h 204 | JZ C_3267 ;-- no key pressed 205 | CMP AX,2E03h ; key code ? 206 | JZ C_3263 ;remove 207 | TEST AX,0FFFFh 208 | JZ C_3263 ;remove 209 | ;-- returns 1 210 | MOV AX,1 211 | JMP SHORT C_326D 212 | C_3263: ;-- remove 213 | MOV AH,0 ;wait for keypress and read character 214 | INT 16h 215 | C_3267: ;-- 216 | CALL t_callback 217 | ;-- returns 0 218 | MOV AX,0 219 | C_326D: ;-- -- 220 | OR AX,AX 221 | ;-- 222 | RET 223 | u_kbhit ENDP 224 | ;----------------------------------------C_3270 225 | ;get keyboard scancode 226 | ;wait if necessary 227 | PUBLIC u_kbread 228 | u_kbread PROC NEAR 229 | ;-- wait a very long time, 230 | ;-- and allow key interrupt 231 | MOV AX,8081h 232 | PUSH AX 233 | PUSH AX 234 | CALL _u_delay 235 | ADD SP,4 236 | ;-- 237 | MOV AH,0 ;wait for keypress and read character 238 | INT 16h 239 | ;-- 240 | RET 241 | u_kbread ENDP 242 | ;----------------------------------------C_3280 243 | ;wait while key pressed 244 | PUBLIC u_kbflush 245 | u_kbflush PROC NEAR 246 | ;-- allow interrupts 247 | STI 248 | NOP 249 | NOP 250 | NOP 251 | CLI 252 | ;-- 253 | CALL u_kbhit 254 | JZ C_328F 255 | CALL u_kbread 256 | JMP u_kbflush 257 | C_328F: ;-- 258 | RET 259 | u_kbflush ENDP 260 | ;---------------------------------------- 261 | ;get current default drive 262 | PUBLIC C_3290 263 | C_3290 PROC NEAR 264 | MOV AH,19h ;get current default drive 265 | INT 21h 266 | INC AL 267 | MOV AH,0 268 | ;-- 269 | RET 270 | C_3290 ENDP 271 | ;---------------------------------------- 272 | ;select disk 273 | PUBLIC C_3299 274 | C_3299 PROC NEAR 275 | PUSH BP 276 | MOV BP,SP 277 | ;-- 278 | MOV DL,[BP+04] 279 | DEC DL 280 | MOV AH,0Eh ;select disk 281 | INT 21h 282 | MOV AH,0 283 | ;-- 284 | POP BP 285 | RET 2 286 | C_3299 ENDP 287 | ;---------------------------------------- 288 | ;test file 289 | PUBLIC C_32AB 290 | C_32AB PROC NEAR 291 | PUSH BP 292 | MOV BP,SP 293 | ;-- 294 | MOV DX,[BP+04] 295 | MOV AL,0 296 | MOV AH,3Dh ;open file 297 | INT 21h 298 | JNB C_32BE 299 | ;-- 300 | MOV AX,0 301 | JMP SHORT C_32C7 302 | C_32BE: ;-- 303 | MOV BX,AX 304 | MOV AH,3Eh ;close file 305 | INT 21h 306 | ;-- 307 | MOV AX,1 308 | C_32C7: ;-- 309 | POP BP 310 | RET 2 311 | C_32AB ENDP 312 | ;---------------------------------------- 313 | ;piracy check function ?(not called) 314 | ;succes => 0 315 | ;failure => -1 316 | PUBLIC C_32CB 317 | C_32CB PROC NEAR 318 | PUSHF 319 | PUSH BX 320 | PUSH AX 321 | PUSH CX 322 | PUSH DX 323 | PUSH DS 324 | PUSH ES 325 | ;-- 326 | PUSH BP 327 | MOV BP,SP 328 | PUSH DI 329 | PUSH SI 330 | ;-- set drive 331 | MOV AH,19h ;get current default drive 332 | INT 21h 333 | CMP AL,1 334 | JBE C_32E1 335 | MOV AL,0 336 | C_32E1: MOV DL,AL ;drive 337 | ;-- 338 | MOV SI,4 ;4 tries 339 | MOV CL,10h ;from sector 10h 340 | nextSector: ;-- read one sector to c000:0000 341 | MOV AX,(2 SHL 8) OR 1 ;read 1 sector 342 | MOV DH,0 ;head 0 343 | MOV CH,9 ;track 9 344 | MOV BX,0C000h 345 | MOV ES,BX 346 | XOR BX,BX ;to c000:0000 347 | INT 13h 348 | JB C_3303 349 | ;-- one track success 350 | DEC CL 351 | JZ C_330C ;finished 352 | MOV SI,4 ;4 tries 353 | JMP nextSector 354 | C_3303: ;-- failed this sector 355 | DEC SI 356 | JNZ nextSector 357 | ;-- failure 358 | MOV BX,0FFFFh 359 | JMP C_330F ;(+nop) 360 | C_330C: ;-- success 361 | MOV BX,0 362 | C_330F: ;-- 363 | POP SI 364 | POP DI 365 | MOV SP,BP 366 | POP BP 367 | ;-- 368 | POP ES 369 | POP DS 370 | POP DX 371 | POP CX 372 | POP AX 373 | MOV AL,BL 374 | POP BX 375 | POPF 376 | RET 377 | C_32CB ENDP 378 | ;---------------------------------------- 379 | ;set critical error handler 380 | PUBLIC C_331E 381 | C_331E PROC NEAR 382 | PUSH DS 383 | ;-- 384 | LEA DX,INT_332F 385 | MOV AX,CS 386 | MOV DS,AX 387 | MOV AH,25h ;set new interrupt vector 388 | MOV AL,24h ;Critical Error 389 | INT 21h 390 | ;-- 391 | POP DS 392 | RET 393 | C_331E ENDP 394 | ;---- 395 | INT_332F: 396 | PUSH BP 397 | MOV BP,SP 398 | PUSH BX 399 | PUSH CX 400 | PUSH DX 401 | PUSH SI 402 | PUSH DS 403 | PUSH ES 404 | ;-- 405 | MOV BX,SS 406 | MOV DS,BX 407 | MOV ES,BX 408 | TEST AH,80h 409 | JNZ C_3388 410 | ;-- display disk error -- 411 | PUSH txt_Y 412 | PUSH txt_X 413 | MOV txt_Y,24 ;18h 414 | MOV txt_X,0 415 | ;-- 416 | LEA AX,MSG_DSKERR 417 | PUSH AX 418 | CALL u4_puts 419 | ;-- 420 | MOV AH,0 ;wait for keypress and read character 421 | INT 16h 422 | ;-- 423 | MOV txt_X,0 424 | MOV SI,39 ;27h 425 | C_336C: ;-- 426 | MOV AX,' ' 427 | PUSH AX 428 | CALL u4_putc 429 | ;-- 430 | DEC SI 431 | JNZ C_336C 432 | ;-- 433 | POP txt_X 434 | POP txt_Y 435 | ;-- -- 436 | POP ES 437 | POP DS 438 | POP SI 439 | POP DX 440 | POP CX 441 | POP BX 442 | POP BP 443 | MOV AL,1 444 | IRET 445 | C_3388: ;-- display fatal error 446 | LEA AX,MSG_SYSERR 447 | PUSH AX 448 | CALL u4_puts 449 | ;-- -- 450 | POP ES 451 | POP DS 452 | POP SI 453 | POP DX 454 | POP CX 455 | POP BX 456 | POP BP 457 | MOV AL,2 458 | IRET 459 | ;---------------------------------------- 460 | _TEXT ENDS 461 | ;######################################## 462 | END 463 | -------------------------------------------------------------------------------- /SRC/U4_SOUND.ASM: -------------------------------------------------------------------------------- 1 | PUBLIC _SoundFlag 2 | 3 | EXTRN u_rand_a:NEAR 4 | EXTRN speed_info:WORD 5 | 6 | DGROUP GROUP _DATA 7 | ;######################################## 8 | _DATA SEGMENT PUBLIC WORD 'DATA' 9 | ASSUME DS:DGROUP 10 | ;---------------------------------------- 11 | _SoundFlag db 1 ;D_06A6 12 | D_06A7 dw OFFSET _TEXT:C_1D69 13 | dw OFFSET _TEXT:sound_1 14 | dw OFFSET _TEXT:C_1DA8 15 | dw OFFSET _TEXT:C_1EB3 16 | dw OFFSET _TEXT:C_1EFD 17 | dw OFFSET _TEXT:C_1F4A 18 | dw OFFSET _TEXT:C_1E7F 19 | dw OFFSET _TEXT:C_1E53 20 | dw OFFSET _TEXT:C_1F22 21 | dw OFFSET _TEXT:C_1DCD 22 | dw OFFSET _TEXT:C_1F73 23 | dw OFFSET _TEXT:C_1FA3 24 | dw OFFSET _TEXT:C_1FCC 25 | db 0 ;padding ? 26 | ;---------------------------------------- 27 | _DATA ENDS 28 | ;######################################## 29 | _TEXT SEGMENT PUBLIC BYTE 'CODE' 30 | ASSUME CS:_TEXT 31 | ;----------------------------------------C_1D47 32 | PUBLIC _sound 33 | _sound PROC NEAR 34 | PUSH BP 35 | MOV BP,SP 36 | ;-- 37 | MOV BL,[BP+04] 38 | MOV CL,[BP+06] 39 | MOV CH,[BP+08] 40 | CMP _SoundFlag,0 41 | JZ C_1D67 42 | CMP BL,0Dh 43 | JNB C_1D67 44 | MOV BH,0 45 | SHL BX,1 46 | CALL D_06A7[BX] 47 | C_1D67: ;-- 48 | POP BP 49 | RET 50 | _sound ENDP 51 | ;---------------------------------------- 52 | C_1D69 PROC NEAR 53 | ;-- backup port 61h 54 | IN AL,61h 55 | MOV AH,AL 56 | ;-- 57 | AND AL,NOT 3 58 | XOR AL,2 59 | OUT 61h,AL 60 | MOV DI,32h 61 | C_1D76: 62 | DEC DI 63 | JNZ C_1D76 64 | XOR AL,2 65 | OUT 61h,AL 66 | ;-- restore port 61h 67 | MOV AL,AH 68 | OUT 61h,AL 69 | ;-- 70 | RET 71 | C_1D69 ENDP 72 | ;----------------------------------------C_1D82 73 | ;same as beep for title.exe 74 | sound_1 PROC NEAR 75 | MOV AX,0CAh 76 | MUL speed_info 77 | MOV DX,AX 78 | ;-- backup port 61h 79 | IN AL,61h 80 | MOV AH,AL 81 | ;-- 82 | AND AL,NOT 3 83 | MOV CX,10h 84 | C_1D94: 85 | OUT 61h,AL 86 | XOR AL,2 87 | MOV BX,DX 88 | C_1D9A: 89 | DEC BX 90 | PUSHF 91 | PUSH AX 92 | POP AX 93 | POPF 94 | JNZ C_1D9A 95 | LOOP C_1D94 96 | ;-- restore port 61h 97 | MOV AL,AH 98 | OUT 61h,AL 99 | ;-- 100 | RET 101 | sound_1 ENDP 102 | ;---------------------------------------- 103 | C_1DA8 PROC NEAR 104 | MOV AX,0E0h 105 | MUL speed_info 106 | MOV DX,AX 107 | ;-- backup port 61h 108 | IN AL,61h 109 | MOV AH,AL 110 | ;-- 111 | AND AL,NOT 3 112 | MOV CX,30h 113 | C_1DBA: 114 | OUT 61h,AL 115 | XOR AL,2 116 | MOV BX,DX 117 | C_1DC0: 118 | DEC BX 119 | JNZ C_1DC0 120 | LOOP C_1DBA 121 | ;-- restore port 61h 122 | MOV AL,AH 123 | OUT 61h,AL 124 | ;-- 125 | CALL sound_1 126 | ;-- 127 | RET 128 | C_1DA8 ENDP 129 | ;---------------------------------------- 130 | C_1DCD PROC NEAR 131 | PUSH BP 132 | MOV BP,SP 133 | SUB SP,4 134 | PUSH speed_info 135 | ;-- 136 | SHR speed_info,1 137 | ADC speed_info,0 138 | MOV AX,1Bh 139 | MUL speed_info 140 | MOV [BP-04],AX 141 | MOV AX,speed_info 142 | MUL CL 143 | MOV DX,AX 144 | MOV CX,speed_info 145 | ;-- backup port 61h 146 | IN AL,61h 147 | MOV [BP-02],AX 148 | ;-- 149 | AND AL,NOT 3 150 | C_1DFC: 151 | MOV AH,30h 152 | C_1DFE: 153 | MOV BX,DX 154 | C_1E00: 155 | DEC BX 156 | JNZ C_1E00 157 | OUT 61h,AL 158 | XOR AL,2 159 | MOV BX,CX 160 | C_1E09: 161 | DEC BX 162 | JNZ C_1E09 163 | OUT 61h,AL 164 | XOR AL,2 165 | DEC AH 166 | JNZ C_1DFE 167 | SUB DX,speed_info 168 | ADD CX,speed_info 169 | CMP CX,[BP-04] 170 | JNZ C_1DFC 171 | C_1E21: 172 | MOV AH,30h 173 | C_1E23: 174 | MOV BX,DX 175 | C_1E25: 176 | DEC BX 177 | JNZ C_1E25 178 | OUT 61h,AL 179 | XOR AL,2 180 | MOV BX,CX 181 | C_1E2E: 182 | DEC BX 183 | JNZ C_1E2E 184 | OUT 61h,AL 185 | XOR AL,2 186 | DEC AH 187 | JNZ C_1E23 188 | ADD DX,speed_info 189 | SUB CX,speed_info 190 | CMP CX,0 191 | JNZ C_1E21 192 | ;-- restore port 61h 193 | MOV AX,[BP-02] 194 | OUT 61h,AL 195 | ;-- 196 | POP speed_info 197 | MOV SP,BP 198 | POP BP 199 | RET 200 | C_1DCD ENDP 201 | ;---------------------------------------- 202 | C_1E53 PROC NEAR 203 | ;-- backup port 61h 204 | IN AL,61h 205 | PUSH AX 206 | ;-- 207 | AND AL,NOT 3 208 | MOV BH,0FFh 209 | C_1E5A: 210 | PUSH AX 211 | CALL u_rand_a 212 | AND AL,7Fh 213 | OR AL,40h 214 | MUL BYTE PTR speed_info 215 | MOV DX,AX 216 | SHR DX,1 217 | db 83h,0cah,1 ;OR DX,+01 218 | POP AX 219 | C_1E6E: 220 | NOP 221 | NOP 222 | DEC DX 223 | JNZ C_1E6E 224 | OUT 61h,AL 225 | XOR AL,2 226 | DEC BH 227 | JNZ C_1E5A 228 | ;-- restore port 61h 229 | POP AX 230 | OUT 61h,AL 231 | ;-- 232 | RET 233 | C_1E53 ENDP 234 | ;---------------------------------------- 235 | C_1E7F PROC NEAR 236 | ;-- backup port 61h 237 | IN AL,61h 238 | PUSH AX 239 | ;-- 240 | AND AL,NOT 3 241 | MOV BH,0FFh 242 | C_1E86: 243 | PUSH AX 244 | CALL u_rand_a 245 | AND AL,7Fh 246 | OR AL,1 247 | MOV AH,0 248 | MOV CX,AX 249 | SHL CX,1 250 | ADD CX,AX 251 | MOV AX,speed_info 252 | MUL CX 253 | MOV CX,AX 254 | SHR CX,1 255 | SHR CX,1 256 | db 83h,0c9h,1 ;OR CX,+01 257 | POP AX 258 | C_1EA5: 259 | LOOP C_1EA5 260 | OUT 61h,AL 261 | XOR AL,2 262 | DEC BH 263 | JNZ C_1E86 264 | ;-- restore port 61h 265 | POP AX 266 | OUT 61h,AL 267 | ;-- 268 | RET 269 | C_1E7F ENDP 270 | ;---------------------------------------- 271 | C_1EB3 PROC NEAR 272 | ;-- backup port 61h 273 | IN AL,61h 274 | PUSH AX 275 | ;-- 276 | AND AL,NOT 3 277 | MOV BL,5 278 | C_1EBA: 279 | OUT 61h,AL 280 | XOR AL,2 281 | MOV CL,BL 282 | PUSH AX 283 | MOV AX,speed_info 284 | MUL CL 285 | MOV CX,AX 286 | SHR CX,1 287 | POP AX 288 | C_1ECB: 289 | DEC CX 290 | NOP 291 | NOP 292 | JNZ C_1ECB 293 | INC BL 294 | JNZ C_1EBA 295 | ;-- restore port 61h 296 | POP AX 297 | OUT 61h,AL 298 | ;-- 299 | RET 300 | C_1EB3 ENDP 301 | ;---------------------------------------- 302 | ; uncalled ? 303 | C_1ED8 PROC NEAR 304 | MOV AX,0A0h 305 | MUL speed_info 306 | MOV BX,AX 307 | ;-- backup port 61h 308 | IN AL,61h 309 | MOV AH,AL 310 | ;-- 311 | AND AL,NOT 3 312 | MOV CH,0 313 | C_1EE9: 314 | MOV CX,BX 315 | C_1EEB: 316 | DEC CX 317 | JNZ C_1EEB 318 | OUT 61h,AL 319 | XOR AL,2 320 | SUB BX,speed_info 321 | JNZ C_1EE9 322 | ;-- restore port 61h 323 | MOV AL,AH 324 | OUT 61h,AL 325 | ;-- 326 | RET 327 | C_1ED8 ENDP 328 | ;---------------------------------------- 329 | C_1EFD PROC NEAR 330 | ;-- backup port 61h 331 | IN AL,61h 332 | PUSH AX 333 | ;-- 334 | AND AL,NOT 3 335 | MOV BL,0 336 | C_1F04: 337 | OUT 61h,AL 338 | XOR AL,02 339 | MOV CL,BL 340 | PUSH AX 341 | MOV AX,speed_info 342 | MUL CL 343 | MOV CX,AX 344 | SHR CX,1 345 | POP AX 346 | C_1F15: 347 | DEC CX 348 | NOP 349 | NOP 350 | JNZ C_1F15 351 | DEC BL 352 | JS C_1F04 353 | ;-- restore port 61h 354 | POP AX 355 | OUT 61h,AL 356 | ;-- 357 | RET 358 | C_1EFD ENDP 359 | ;---------------------------------------- 360 | C_1F22 PROC NEAR 361 | ;-- backup port 61h 362 | IN AL,61h 363 | PUSH AX 364 | ;-- 365 | AND AL,NOT 3 366 | MOV BL,80h 367 | C_1F29: 368 | OUT 61h,AL 369 | XOR AL,02 370 | MOV CL,BL 371 | PUSH AX 372 | MOV AX,speed_info 373 | MUL CL 374 | SHR AX,1 375 | ADC AX,0 376 | MOV CX,AX 377 | POP AX 378 | C_1F3D: 379 | DEC CX 380 | NOP 381 | NOP 382 | JNZ C_1F3D 383 | DEC BL 384 | JNZ C_1F29 385 | ;-- restore port 61h 386 | POP AX 387 | OUT 61h,AL 388 | ;-- 389 | RET 390 | C_1F22 ENDP 391 | ;---------------------------------------- 392 | C_1F4A PROC NEAR 393 | ;-- backup port 61h 394 | IN AL,61h 395 | MOV AH,AL 396 | ;-- 397 | AND AL,NOT 3 398 | MOV BL,80h 399 | C_1F52: 400 | OUT 61h,AL 401 | XOR AL,02 402 | MOV CL,BL 403 | PUSH AX 404 | MOV AX,speed_info 405 | MUL CL 406 | SHR AX,1 407 | MOV CX,AX 408 | POP AX 409 | C_1F63: 410 | DEC CX 411 | NOP 412 | NOP 413 | NOP 414 | NOP 415 | JNZ C_1F63 416 | INC BL 417 | JNZ C_1F52 418 | ;-- restore port 61h 419 | MOV AL,AH 420 | OUT 61h,AL 421 | ;-- 422 | RET 423 | C_1F4A ENDP 424 | ;---------------------------------------- 425 | C_1F73 PROC NEAR 426 | ;-- backup port 61h 427 | IN AL,61h 428 | PUSH AX 429 | ;-- 430 | AND AL,NOT 3 431 | C_1F78: 432 | PUSH AX 433 | CALL u_rand_a 434 | AND AL,3Fh 435 | ADD AL,40h 436 | MOV DL,AL 437 | MOV AX,speed_info 438 | MUL DL 439 | SHL AX,1 440 | MOV DX,AX 441 | POP AX 442 | MOV CH,28h 443 | C_1F8E: 444 | MOV BX,DX 445 | C_1F90: 446 | DEC BX 447 | JNZ C_1F90 448 | OUT 61h,AL 449 | XOR AL,2 450 | DEC CH 451 | JNZ C_1F8E 452 | DEC CL 453 | JNZ C_1F78 454 | ;-- restore port 61h 455 | POP AX 456 | OUT 61h,AL 457 | ;-- 458 | RET 459 | C_1F73 ENDP 460 | ;---------------------------------------- 461 | C_1FA3 PROC NEAR 462 | ;-- backup port 61h 463 | IN AL,61h 464 | PUSH AX 465 | ;-- 466 | AND AL,NOT 3 467 | MOV CX,40h 468 | C_1FAB: 469 | MOV AH,14h 470 | C_1FAD: 471 | MOV BX,CX 472 | XCHG BX,AX 473 | MUL speed_info 474 | XCHG BX,AX 475 | C_1FB5: 476 | NOP 477 | DEC BX 478 | JNZ C_1FB5 479 | OUT 61h,AL 480 | XOR AL,2 481 | DEC AH 482 | JNZ C_1FAD 483 | INC CX 484 | CMP CX,0C0h 485 | JB C_1FAB 486 | ;-- restore port 61h 487 | POP AX 488 | OUT 61h,AL 489 | ;-- 490 | RET 491 | C_1FA3 ENDP 492 | ;---------------------------------------- 493 | C_1FCC PROC NEAR 494 | ;-- backup port 61h 495 | IN AL,61h 496 | PUSH AX 497 | ;-- 498 | AND AL,NOT 3 499 | MOV CX,0C0h 500 | C_1FD4: 501 | MOV AH,14h 502 | C_1FD6: 503 | MOV BX,CX 504 | XCHG BX,AX 505 | MUL speed_info 506 | XCHG BX,AX 507 | C_1FDE: 508 | NOP 509 | DEC BX 510 | JNZ C_1FDE 511 | OUT 61h,AL 512 | XOR AL,2 513 | DEC AH 514 | JNZ C_1FD6 515 | DEC CX 516 | CMP CX,40h 517 | JA C_1FD4 518 | ;-- restore port 61h 519 | POP AX 520 | OUT 61h,AL 521 | ;-- 522 | RET 523 | C_1FCC ENDP 524 | ;---------------------------------------- 525 | _TEXT ENDS 526 | ;######################################## 527 | END 528 | --------------------------------------------------------------------------------