home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
u
/
uw2e23.zip
/
UW2E23.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-13
|
11KB
|
446 lines
// UW2E23 Basic character editor for Ultima Underworld II
// Author: Terry Orr Compuserv 71140,633
// Programmed in Borland C++ version 3.1
//
// REVISION HISTORY:
// UW2E23 Feb 13, 1993 version 2.3
// Identifies the Rune bytes. Changes prompt color. And indicates CTRL C
// for quit without save.
// UW2E22 Feb 10, 1993 version 2.2
// Corrects the problem with sometimes garbles save file after running UW2E21
// UW2E21 Feb 9, 1993 version 2.1:
// Corrects the problem with lockup if entering other than numerics.
// UW2E20 Feb 8, 1993 version 2.0:
// More advanced providing editing of all first 80 bytes in player.dat
// including unknown bytes. Except name bytes which re-encryption needs
// left alone.
// UW2E11 Feb 8, 1993 version 1.1:
// Cleaned up the editor section a little bit. Nothing major
// UW2E1 Feb 7, 1993 beta version 1.0:
// Fixed problem with missing Track edit, and everything after Search field
// was off by one and swimming edit was missed.
// UW2E0 Feb 7, 1993 beta version 0:
// Original beta version.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <io.h>
#include <ctype.h>
#define FILENAME "player.dat"
#define VERSION "2.3"
main()
{
int i, n, x, y; // General purpose variables
int handle; // Disk file handle
int ax,cx,al,bp_06; // Simulate disassembly code cpu registers
long flen; // holds the file length value
// Declare the Buffers and alocate memory
int *pdat; // Buffer for player.dat
pdat = new int[3072];
int *cypher; // Cyper table buffer
cypher = new int[200];
int *stat; // Decrypted player.dat buffer
stat = new int[200];
FILE *fp; // For disk i/o
clrscr(); // Clear the screen
// Read file from disk to pdat[] buffer
if ((fp=fopen(FILENAME,"rb"))==NULL){ //Error message if cant open file
printf("UW2EDIT Error(1): cannot open/find %s\n",FILENAME);
exit(1);
}
handle = fileno(fp);
flen = filelength(handle);
for(i=0; i<flen; i++)
pdat[i] = getc(fp);
fclose(fp);
// Generate the decryption table cypher[]
// This section is not commented because it is to confusing even when
// commented. It was designed based on the assembly code in UW2.EXE
bp_06 = pdat[0] - 0xaa + 0x1b; // T = 6f
cx = 0x3c;
while(cx < 0x50){
al = cx & 0x00ff;
al = al + bp_06 & 0x00ff;
al = al + 2 & 0x00ff;
bp_06 = al;
cx = cx + 1;
}
cx = 0;
while(cx < 0x50){
bp_06 = bp_06 + 6 & 0x00ff;
cypher[cx] = bp_06;
cx = cx + 1;
}
cx = 0;
i = 0;
while(cx < 0x10){
bp_06 = bp_06 + 7 & 0x00ff;
cypher[i] = bp_06;
i = i + 5;
cx = cx + 1;
}
cx = 0;
i = 0;
while(cx < 0x04){
bp_06 = bp_06 + 0x29 & 0x00ff;
cypher[i] = bp_06;
i = i + 0x0c;
cx = cx + 1;
}
cx = 0;
i = 0;
while(cx < 0x0b){
bp_06 = bp_06 + 0x49 & 0x00ff;
cypher[i] = bp_06;
i = i + 0x07;
cx = cx + 1;
}
// Now decrypt player.dat ie pdat[] using cypher[] into stat[]
// stat[] will hold the decrypted character statistics.
cx = 1;
al = (pdat[1] ^ cypher[0]) & 0x00ff;
stat[0] = al;
while(cx < 0x50){
al = cypher[cx];
al = (al + stat[cx-1]) & 0x00ff;
al = (al + pdat[cx]) & 0x00ff;
bp_06 = pdat[cx+1];
stat[cx] = (al ^ bp_06) & 0x00ff;
cx = cx + 1;
}
// ** THE EDITOR GOES GO HERE **
int choice = 0;
int newval;
char string[3];
char name[19];
textcolor(YELLOW);
textbackground(BLUE);
gotoxy(4,1);
cprintf(" Ultima Underworld II Character Editor Version %s Written by Terry Orr ",VERSION);
textbackground(BLACK);
// Draw top horizontal line
n=196;
textcolor(GREEN);
gotoxy(1,2);
for (i=1; i < 78; i++)
cprintf("%c",n);
// Draw top left corner
n=218;
gotoxy(1,2);
cprintf("%c",n);
// Draw top right corner
n=191;
gotoxy(77,2);
cprintf("%c",n);
// Draw left vertical line
n=179;
for (i=3; i < 23; i++){
gotoxy(1,i);
cprintf("%c",n);
}
// Draw second vertical line
n=179;
for (i=3; i < 23; i++){
gotoxy(20,i);
cprintf("%c",n);
}
// Draw third vertical line
n=179;
for (i=3; i < 23; i++){
gotoxy(39,i);
cprintf("%c",n);
}
// Draw forth vertical line
n=179;
for (i=3; i < 23; i++){
gotoxy(58,i);
cprintf("%c",n);
}
// Draw right vertical line
n=179;
for (i=3; i < 23; i++){
gotoxy(77,i);
cprintf("%c",n);
}
// Draw botom horizontal line
n=196;
textcolor(GREEN);
gotoxy(1,23);
for (i=1; i < 78; i++)
cprintf("%c",n);
// Draw bottom left corner
n=192;
gotoxy(1,23);
cprintf("%c",n);
// Draw bottom right corner
n=217;
gotoxy(77,23);
cprintf("%c",n);
// Now fill the screen. LIGHTGRAY = cant edit. WHITE = known parameter
// LIGHTRED = unknown parameter. Displays player.dat bytes 0 thru 79.
while(choice != 80){
textcolor(LIGHTGRAY);
gotoxy(2,3);
cprintf("0...Name1 [%02c]",stat[0]);
gotoxy(2,4);
cprintf("1...Name2 [%02c]",stat[1]);
gotoxy(2,5);
cprintf("2...Name3 [%02c]",stat[2]);
gotoxy(2,6);
cprintf("3...Name4 [%02c]",stat[3]);
gotoxy(2,7);
cprintf("4...Name5 [%02c]",stat[4]);
gotoxy(2,8);
cprintf("5...Name6 [%02c]",stat[5]);
gotoxy(2,9);
cprintf("6...Name7 [%02c]",stat[6]);
gotoxy(2,10);
cprintf("7...Name8 [%02c]",stat[7]);
gotoxy(2,11);
cprintf("8...Name9 [%02c]",stat[8]);
gotoxy(2,12);
cprintf("9...Name10 [%02c]",stat[9]);
gotoxy(2,13);
cprintf("10..Name11 [%02c]",stat[10]);
gotoxy(2,14);
cprintf("11..Name12 [%02c]",stat[11]);
gotoxy(2,15);
cprintf("12..Name13 [%02c]",stat[12]);
gotoxy(2,16);
cprintf("13..Name14 [%02c]",stat[13]);
gotoxy(2,17);
cprintf("14..Name15 [%02c]",stat[14]);
gotoxy(2,18);
cprintf("15..Name16 [%02c]",stat[15]);
gotoxy(2,19);
cprintf("16..Name17 [%02c]",stat[16]);
gotoxy(2,20);
cprintf("17..Name18 [%02c]",stat[17]);
gotoxy(2,21);
cprintf("18..Name19 [%02c]",stat[18]);
textcolor(LIGHTRED);
gotoxy(2,22);
cprintf("19..Unknown [%02d]",stat[19]);
gotoxy(21,3);
cprintf("20..Unknown [%02d]",stat[20]);
gotoxy(21,4);
cprintf("21..Unknown [%02d]",stat[21]);
gotoxy(21,5);
cprintf("22..Unknown [%02d]",stat[22]);
gotoxy(21,6);
cprintf("23..Unknown [%02d]",stat[23]);
gotoxy(21,7);
cprintf("24..Unknown [%02d]",stat[24]);
gotoxy(21,8);
cprintf("25..Unknown [%02d]",stat[25]);
gotoxy(21,9);
cprintf("26..Unknown [%02d]",stat[26]);
gotoxy(21,10);
cprintf("27..Unknown [%02d]",stat[27]);
gotoxy(21,11);
cprintf("28..Unknown [%02d]",stat[28]);
gotoxy(21,12);
cprintf("29..Unknown [%02d]",stat[29]);
gotoxy(21,13);
textcolor(WHITE);
cprintf("30..Strength [%02d]",stat[30]);
gotoxy(21,14);
cprintf("31..Dexterity[%02d]",stat[31]);
gotoxy(21,15);
cprintf("32..Vitality [%02d]",stat[32]);
gotoxy(21,16);
cprintf("33..Attack [%02d]",stat[33]);
gotoxy(21,17);
cprintf("34..Defense [%02d]",stat[34]);
gotoxy(21,18);
cprintf("35..Barehand [%02d]",stat[35]);
gotoxy(21,19);
cprintf("36..Sword [%02d]",stat[36]);
gotoxy(21,20);
cprintf("37..Axe [%02d]",stat[37]);
gotoxy(21,21);
cprintf("38..Mace [%02d]",stat[38]);
gotoxy(21,22);
cprintf("39..Missile [%02d]",stat[39]);
gotoxy(40,3);
cprintf("40..Mana [%02d]",stat[40]);
gotoxy(40,4);
cprintf("41..Lore [%02d]",stat[41]);
gotoxy(40,5);
cprintf("42..Casting [%02d]",stat[42]);
gotoxy(40,6);
cprintf("43..Traps [%02d]",stat[43]);
gotoxy(40,7);
cprintf("44..Search [%02d]",stat[44]);
gotoxy(40,8);
cprintf("45..Track [%02d]",stat[45]);
gotoxy(40,9);
cprintf("46..Stealth [%02d]",stat[46]);
gotoxy(40,10);
cprintf("47..Repair [%02d]",stat[47]);
gotoxy(40,11);
cprintf("48..Charisma [%02d]",stat[48]);
gotoxy(40,12);
cprintf("49..Picklock [%02d]",stat[49]);
gotoxy(40,13);
cprintf("50..Acrobat [%02d]",stat[50]);
gotoxy(40,14);
cprintf("51..Appraise [%02d]",stat[51]);
gotoxy(40,15);
cprintf("52..Swimming [%02d]",stat[52]);
gotoxy(40,16);
textcolor(WHITE);
cprintf("53..Vitality [%02d]",stat[53]);
gotoxy(40,17);
cprintf("54..Vitality [%02d]",stat[54]);
gotoxy(40,18);
cprintf("55..Mana [%02d]",stat[55]);
gotoxy(40,19);
cprintf("56..Mana [%02d]",stat[56]);
gotoxy(40,20);
textcolor(LIGHTRED);
cprintf("57..Unknown [%02d]",stat[57]);
gotoxy(40,21);
cprintf("58..Unknown [%02d]",stat[58]);
gotoxy(40,22);
cprintf("59..Unknown [%02d]",stat[59]);
gotoxy(59,3);
cprintf("60..Unknown [%02d]",stat[60]);
gotoxy(59,4);
textcolor(WHITE);
cprintf("61..Level [%02d]",stat[61]);
gotoxy(59,5);
textcolor(LIGHTRED);
cprintf("62..Unknown [%02d]",stat[62]);
gotoxy(59,6);
cprintf("63..Unknown [%02d]",stat[63]);
gotoxy(59,7);
cprintf("64..Unknown [%02d]",stat[64]);
gotoxy(59,8);
cprintf("65..Unknown [%02d]",stat[65]);
gotoxy(59,9);
cprintf("66..Unknown [%02d]",stat[66]);
gotoxy(59,10);
cprintf("67..Unknown [%02d]",stat[67]);
gotoxy(59,11);
textcolor(WHITE);
cprintf("68..Rune A-H [%02d]",stat[68]);
gotoxy(59,12);
cprintf("69..Rune I-P [%02d]",stat[69]);
gotoxy(59,13);
cprintf("70..Rune Q-Y [%02d]",stat[70]);
gotoxy(59,14);
textcolor(LIGHTRED);
cprintf("71..Unknown [%02d]",stat[71]);
gotoxy(59,15);
cprintf("72..Unknown [%02d]",stat[72]);
gotoxy(59,16);
cprintf("73..Unknown [%02d]",stat[73]);
gotoxy(59,17);
cprintf("74..Unknown [%02d]",stat[74]);
gotoxy(59,18);
cprintf("75..Unknown [%02d]",stat[75]);
gotoxy(59,19);
cprintf("76..Unknown [%02d]",stat[76]);
gotoxy(59,20);
cprintf("77..Unknown [%02d]",stat[77]);
gotoxy(59,21);
cprintf("78..Unknown [%02d]",stat[78]);
gotoxy(59,22);
cprintf("79..Unknown [%02d]",stat[79]);
// Scan for user input
textcolor(CYAN);
gotoxy(8,24);
clreol();
gotoxy(8,24);
cprintf("Select a number (19 - 79) or 80 to Save & Quit (CTRL C to Quit) ");
gets(string);
choice = atoi(string);
gotoxy(8,24);
clreol();
if(choice > 18 && choice < 80){
gotoxy(28,24);
cprintf("Enter the new value (0 - 255) ");
gets(string);
newval = atoi(string);
gotoxy(28,24);
clreol();
if(newval < 256) stat[choice] = newval;
}
}
// The user selected "Save and Quit", so reverse the decryption process
// and save to pdat[]
// pdat[0] = stat[0] + 0xaa & 0x00ff;
pdat[1] = stat[0] ^ cypher[0];
cx = 0;
while(cx < 0x4f){
al = (stat[cx] + cypher[cx+1]) & 0x00ff;
al = (al + pdat[cx +1]) & 0x00ff;
pdat[cx+2] = (stat[cx+1] ^ al) & 0x00ff;
cx = cx +1;
}
// Now save pdat[] to disk (player.dat)
fp = fopen("player.dat","wb");
for(i=0; i<flen; i++)
putc(pdat[i],fp);
fclose(fp);
textcolor(WHITE);
lowvideo();
clrscr();
return(0);
}