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 >
C/C++ Source or Header  |  1993-02-13  |  11KB  |  446 lines

  1. // UW2E23 Basic character editor for Ultima Underworld II
  2. // Author: Terry Orr Compuserv 71140,633
  3. // Programmed in Borland C++ version 3.1
  4. //
  5. // REVISION HISTORY:
  6. // UW2E23 Feb 13, 1993 version 2.3
  7. // Identifies the Rune bytes. Changes prompt color. And indicates CTRL C
  8. // for quit without save.
  9. // UW2E22 Feb 10, 1993 version 2.2
  10. // Corrects the problem with sometimes garbles save file after running UW2E21
  11. // UW2E21 Feb 9, 1993 version 2.1:
  12. // Corrects the problem with lockup if entering other than numerics.
  13. // UW2E20 Feb 8, 1993 version 2.0:
  14. // More advanced providing editing of all first 80 bytes in player.dat
  15. // including unknown bytes. Except name bytes which re-encryption needs
  16. // left alone.
  17. // UW2E11 Feb 8, 1993 version 1.1:
  18. // Cleaned up the editor section a little bit. Nothing major
  19. // UW2E1 Feb 7, 1993 beta version 1.0:
  20. // Fixed problem with missing Track edit, and everything after Search field
  21. // was off by one and swimming edit was missed.
  22. // UW2E0 Feb 7, 1993 beta version 0:
  23. // Original beta version.
  24.  
  25. #include <stdio.h>
  26. #include <conio.h>
  27. #include <stdlib.h>
  28. #include <io.h>
  29. #include <ctype.h>
  30.  
  31. #define FILENAME "player.dat"
  32. #define VERSION "2.3"
  33.  
  34. main()
  35. {
  36.     int i, n, x, y;   // General purpose variables
  37.     int handle;    // Disk file handle
  38.     int ax,cx,al,bp_06;    // Simulate disassembly code cpu registers
  39.     long flen;     // holds the file length value
  40.  
  41. // Declare the Buffers and alocate memory
  42.  
  43.     int *pdat;              // Buffer for player.dat
  44.     pdat = new int[3072];
  45.    int *cypher;            // Cyper table buffer
  46.     cypher = new int[200];
  47.    int *stat;              // Decrypted player.dat buffer
  48.     stat = new int[200];
  49.  
  50.     FILE *fp;  // For disk i/o
  51.  
  52.     clrscr();  // Clear the screen
  53.  
  54. // Read file from disk to pdat[] buffer
  55.  
  56.     if ((fp=fopen(FILENAME,"rb"))==NULL){ //Error message if cant open file
  57.         printf("UW2EDIT Error(1): cannot open/find %s\n",FILENAME);
  58.         exit(1);
  59.     }
  60.     handle = fileno(fp);
  61.     flen = filelength(handle);
  62.     for(i=0; i<flen; i++)
  63.         pdat[i] = getc(fp);
  64.     fclose(fp);
  65.  
  66. // Generate the decryption table cypher[]
  67. // This section is not commented because it is to confusing even when
  68. // commented. It was designed based on the assembly code in UW2.EXE
  69.  
  70.     bp_06 = pdat[0] - 0xaa + 0x1b;  // T = 6f
  71.     cx = 0x3c;
  72.     while(cx < 0x50){
  73.         al = cx & 0x00ff;
  74.         al = al + bp_06 & 0x00ff;
  75.         al = al + 2 & 0x00ff;
  76.         bp_06 = al;
  77.         cx = cx + 1;
  78.     }
  79.     cx = 0;
  80.     while(cx < 0x50){
  81.         bp_06 = bp_06 + 6 & 0x00ff;
  82.         cypher[cx] = bp_06;
  83.         cx = cx + 1;
  84.     }
  85.     cx = 0;
  86.     i = 0;
  87.     while(cx < 0x10){
  88.         bp_06  = bp_06 + 7 & 0x00ff;
  89.         cypher[i] = bp_06;
  90.         i = i + 5;
  91.         cx = cx + 1;
  92.     }
  93.     cx = 0;
  94.     i = 0;
  95.     while(cx < 0x04){
  96.         bp_06 = bp_06 + 0x29 & 0x00ff;
  97.         cypher[i] = bp_06;
  98.         i = i + 0x0c;
  99.         cx = cx + 1;
  100.     }
  101.     cx = 0;
  102.     i = 0;
  103.     while(cx < 0x0b){
  104.         bp_06 = bp_06 + 0x49 & 0x00ff;
  105.         cypher[i] = bp_06;
  106.         i = i + 0x07;
  107.         cx = cx + 1;
  108.     }
  109.  
  110. // Now decrypt player.dat ie pdat[] using cypher[] into stat[]
  111. // stat[] will hold the decrypted character statistics.
  112.  
  113.     cx = 1;
  114.     al = (pdat[1] ^ cypher[0]) & 0x00ff;
  115.     stat[0] = al;
  116.     while(cx < 0x50){
  117.         al = cypher[cx];
  118.         al = (al + stat[cx-1]) & 0x00ff;
  119.         al = (al + pdat[cx]) & 0x00ff;
  120.         bp_06 = pdat[cx+1];
  121.         stat[cx] = (al ^ bp_06) & 0x00ff;
  122.         cx = cx + 1;
  123.     }
  124.  
  125. // ** THE EDITOR GOES GO HERE **
  126.  
  127.     int choice = 0;
  128.     int newval;
  129.    char string[3];
  130.     char name[19];
  131.  
  132.     textcolor(YELLOW);
  133.    textbackground(BLUE);
  134.     gotoxy(4,1);
  135.     cprintf(" Ultima Underworld II Character Editor Version %s Written by Terry Orr ",VERSION);
  136.  
  137.    textbackground(BLACK);
  138.  
  139. // Draw top horizontal line
  140.  
  141.     n=196;
  142.     textcolor(GREEN);
  143.     gotoxy(1,2);
  144.     for (i=1; i < 78; i++)
  145.         cprintf("%c",n);
  146.  
  147. // Draw top left corner
  148.  
  149.     n=218;
  150.     gotoxy(1,2);
  151.     cprintf("%c",n);
  152.  
  153. // Draw top right corner
  154.  
  155.     n=191;
  156.     gotoxy(77,2);
  157.     cprintf("%c",n);
  158.  
  159. // Draw left vertical line
  160.  
  161.     n=179;
  162.     for (i=3; i < 23; i++){
  163.         gotoxy(1,i);
  164.         cprintf("%c",n);
  165.     }
  166.  
  167. // Draw second vertical line
  168.  
  169.     n=179;
  170.     for (i=3; i < 23; i++){
  171.         gotoxy(20,i);
  172.         cprintf("%c",n);
  173.     }
  174.  
  175. // Draw third vertical line
  176.  
  177.     n=179;
  178.     for (i=3; i < 23; i++){
  179.         gotoxy(39,i);
  180.         cprintf("%c",n);
  181.     }
  182.  
  183. // Draw forth vertical line
  184.  
  185.     n=179;
  186.     for (i=3; i < 23; i++){
  187.         gotoxy(58,i);
  188.         cprintf("%c",n);
  189.     }
  190.  
  191. // Draw right vertical line
  192.  
  193.     n=179;
  194.     for (i=3; i < 23; i++){
  195.         gotoxy(77,i);
  196.         cprintf("%c",n);
  197.     }
  198.  
  199. // Draw botom horizontal line
  200.  
  201.     n=196;
  202.     textcolor(GREEN);
  203.     gotoxy(1,23);
  204.     for (i=1; i < 78; i++)
  205.         cprintf("%c",n);
  206.  
  207. // Draw bottom left corner
  208.  
  209.     n=192;
  210.     gotoxy(1,23);
  211.     cprintf("%c",n);
  212.  
  213. // Draw bottom right corner
  214.  
  215.     n=217;
  216.     gotoxy(77,23);
  217.     cprintf("%c",n);
  218.  
  219. // Now fill the screen. LIGHTGRAY = cant edit. WHITE = known parameter
  220. // LIGHTRED = unknown parameter. Displays player.dat bytes 0 thru 79.
  221.  
  222.     while(choice != 80){
  223.         textcolor(LIGHTGRAY);
  224.         gotoxy(2,3);
  225.         cprintf("0...Name1    [%02c]",stat[0]);
  226.         gotoxy(2,4);
  227.         cprintf("1...Name2    [%02c]",stat[1]);
  228.         gotoxy(2,5);
  229.         cprintf("2...Name3    [%02c]",stat[2]);
  230.         gotoxy(2,6);
  231.         cprintf("3...Name4    [%02c]",stat[3]);
  232.         gotoxy(2,7);
  233.         cprintf("4...Name5    [%02c]",stat[4]);
  234.         gotoxy(2,8);
  235.         cprintf("5...Name6    [%02c]",stat[5]);
  236.         gotoxy(2,9);
  237.         cprintf("6...Name7    [%02c]",stat[6]);
  238.         gotoxy(2,10);
  239.         cprintf("7...Name8    [%02c]",stat[7]);
  240.         gotoxy(2,11);
  241.         cprintf("8...Name9    [%02c]",stat[8]);
  242.         gotoxy(2,12);
  243.         cprintf("9...Name10   [%02c]",stat[9]);
  244.         gotoxy(2,13);
  245.         cprintf("10..Name11   [%02c]",stat[10]);
  246.         gotoxy(2,14);
  247.         cprintf("11..Name12   [%02c]",stat[11]);
  248.         gotoxy(2,15);
  249.         cprintf("12..Name13   [%02c]",stat[12]);
  250.         gotoxy(2,16);
  251.         cprintf("13..Name14   [%02c]",stat[13]);
  252.         gotoxy(2,17);
  253.         cprintf("14..Name15   [%02c]",stat[14]);
  254.         gotoxy(2,18);
  255.         cprintf("15..Name16   [%02c]",stat[15]);
  256.         gotoxy(2,19);
  257.         cprintf("16..Name17   [%02c]",stat[16]);
  258.         gotoxy(2,20);
  259.         cprintf("17..Name18   [%02c]",stat[17]);
  260.         gotoxy(2,21);
  261.         cprintf("18..Name19   [%02c]",stat[18]);
  262.         textcolor(LIGHTRED);
  263.         gotoxy(2,22);
  264.         cprintf("19..Unknown  [%02d]",stat[19]);
  265.  
  266.         gotoxy(21,3);
  267.         cprintf("20..Unknown  [%02d]",stat[20]);
  268.         gotoxy(21,4);
  269.         cprintf("21..Unknown  [%02d]",stat[21]);
  270.         gotoxy(21,5);
  271.         cprintf("22..Unknown  [%02d]",stat[22]);
  272.         gotoxy(21,6);
  273.         cprintf("23..Unknown  [%02d]",stat[23]);
  274.         gotoxy(21,7);
  275.         cprintf("24..Unknown  [%02d]",stat[24]);
  276.         gotoxy(21,8);
  277.         cprintf("25..Unknown  [%02d]",stat[25]);
  278.         gotoxy(21,9);
  279.         cprintf("26..Unknown  [%02d]",stat[26]);
  280.         gotoxy(21,10);
  281.         cprintf("27..Unknown  [%02d]",stat[27]);
  282.         gotoxy(21,11);
  283.         cprintf("28..Unknown  [%02d]",stat[28]);
  284.         gotoxy(21,12);
  285.         cprintf("29..Unknown  [%02d]",stat[29]);
  286.         gotoxy(21,13);
  287.         textcolor(WHITE);
  288.         cprintf("30..Strength [%02d]",stat[30]);
  289.         gotoxy(21,14);
  290.         cprintf("31..Dexterity[%02d]",stat[31]);
  291.         gotoxy(21,15);
  292.         cprintf("32..Vitality [%02d]",stat[32]);
  293.         gotoxy(21,16);
  294.         cprintf("33..Attack   [%02d]",stat[33]);
  295.         gotoxy(21,17);
  296.         cprintf("34..Defense  [%02d]",stat[34]);
  297.         gotoxy(21,18);
  298.         cprintf("35..Barehand [%02d]",stat[35]);
  299.         gotoxy(21,19);
  300.         cprintf("36..Sword    [%02d]",stat[36]);
  301.         gotoxy(21,20);
  302.         cprintf("37..Axe      [%02d]",stat[37]);
  303.         gotoxy(21,21);
  304.         cprintf("38..Mace     [%02d]",stat[38]);
  305.         gotoxy(21,22);
  306.         cprintf("39..Missile  [%02d]",stat[39]);
  307.  
  308.         gotoxy(40,3);
  309.         cprintf("40..Mana     [%02d]",stat[40]);
  310.         gotoxy(40,4);
  311.         cprintf("41..Lore     [%02d]",stat[41]);
  312.         gotoxy(40,5);
  313.         cprintf("42..Casting  [%02d]",stat[42]);
  314.         gotoxy(40,6);
  315.         cprintf("43..Traps    [%02d]",stat[43]);
  316.         gotoxy(40,7);
  317.         cprintf("44..Search   [%02d]",stat[44]);
  318.         gotoxy(40,8);
  319.         cprintf("45..Track    [%02d]",stat[45]);
  320.         gotoxy(40,9);
  321.         cprintf("46..Stealth  [%02d]",stat[46]);
  322.         gotoxy(40,10);
  323.         cprintf("47..Repair   [%02d]",stat[47]);
  324.         gotoxy(40,11);
  325.         cprintf("48..Charisma [%02d]",stat[48]);
  326.         gotoxy(40,12);
  327.         cprintf("49..Picklock [%02d]",stat[49]);
  328.         gotoxy(40,13);
  329.         cprintf("50..Acrobat  [%02d]",stat[50]);
  330.         gotoxy(40,14);
  331.         cprintf("51..Appraise [%02d]",stat[51]);
  332.         gotoxy(40,15);
  333.         cprintf("52..Swimming [%02d]",stat[52]);
  334.         gotoxy(40,16);
  335.         textcolor(WHITE);
  336.         cprintf("53..Vitality [%02d]",stat[53]);
  337.         gotoxy(40,17);
  338.         cprintf("54..Vitality [%02d]",stat[54]);
  339.         gotoxy(40,18);
  340.         cprintf("55..Mana     [%02d]",stat[55]);
  341.         gotoxy(40,19);
  342.         cprintf("56..Mana     [%02d]",stat[56]);
  343.         gotoxy(40,20);
  344.         textcolor(LIGHTRED);
  345.         cprintf("57..Unknown  [%02d]",stat[57]);
  346.         gotoxy(40,21);
  347.         cprintf("58..Unknown  [%02d]",stat[58]);
  348.         gotoxy(40,22);
  349.         cprintf("59..Unknown  [%02d]",stat[59]);
  350.  
  351.         gotoxy(59,3);
  352.         cprintf("60..Unknown  [%02d]",stat[60]);
  353.         gotoxy(59,4);
  354.         textcolor(WHITE);
  355.         cprintf("61..Level    [%02d]",stat[61]);
  356.         gotoxy(59,5);
  357.         textcolor(LIGHTRED);
  358.         cprintf("62..Unknown  [%02d]",stat[62]);
  359.         gotoxy(59,6);
  360.         cprintf("63..Unknown  [%02d]",stat[63]);
  361.         gotoxy(59,7);
  362.         cprintf("64..Unknown  [%02d]",stat[64]);
  363.         gotoxy(59,8);
  364.         cprintf("65..Unknown  [%02d]",stat[65]);
  365.         gotoxy(59,9);
  366.         cprintf("66..Unknown  [%02d]",stat[66]);
  367.         gotoxy(59,10);
  368.         cprintf("67..Unknown  [%02d]",stat[67]);
  369.         gotoxy(59,11);
  370.         textcolor(WHITE);
  371.         cprintf("68..Rune A-H [%02d]",stat[68]);
  372.         gotoxy(59,12);
  373.         cprintf("69..Rune I-P [%02d]",stat[69]);
  374.         gotoxy(59,13);
  375.         cprintf("70..Rune Q-Y [%02d]",stat[70]);
  376.         gotoxy(59,14);
  377.         textcolor(LIGHTRED);
  378.         cprintf("71..Unknown  [%02d]",stat[71]);
  379.         gotoxy(59,15);
  380.         cprintf("72..Unknown  [%02d]",stat[72]);
  381.         gotoxy(59,16);
  382.         cprintf("73..Unknown  [%02d]",stat[73]);
  383.         gotoxy(59,17);
  384.         cprintf("74..Unknown  [%02d]",stat[74]);
  385.         gotoxy(59,18);
  386.         cprintf("75..Unknown  [%02d]",stat[75]);
  387.         gotoxy(59,19);
  388.         cprintf("76..Unknown  [%02d]",stat[76]);
  389.         gotoxy(59,20);
  390.         cprintf("77..Unknown  [%02d]",stat[77]);
  391.         gotoxy(59,21);
  392.         cprintf("78..Unknown  [%02d]",stat[78]);
  393.         gotoxy(59,22);
  394.         cprintf("79..Unknown  [%02d]",stat[79]);
  395.  
  396. // Scan for user input
  397.  
  398.         textcolor(CYAN);
  399.         gotoxy(8,24);
  400.         clreol();
  401.         gotoxy(8,24);
  402.         cprintf("Select a number (19 - 79) or 80 to Save & Quit (CTRL C to Quit) ");
  403.       gets(string);
  404.       choice = atoi(string);
  405.         gotoxy(8,24);
  406.         clreol();
  407.  
  408.         if(choice > 18 && choice < 80){
  409.             gotoxy(28,24);
  410.             cprintf("Enter the new value (0 - 255) ");
  411.          gets(string);
  412.          newval = atoi(string);
  413.             gotoxy(28,24);
  414.             clreol();
  415.             if(newval < 256) stat[choice] = newval;
  416.         }
  417.     }
  418.  
  419. //  The user selected "Save and Quit", so reverse the decryption process
  420. //  and save to pdat[]
  421.  
  422. //    pdat[0] = stat[0] + 0xaa & 0x00ff;
  423.     pdat[1] = stat[0] ^ cypher[0];
  424.     cx = 0;
  425.     while(cx < 0x4f){
  426.         al = (stat[cx] + cypher[cx+1]) & 0x00ff;
  427.         al = (al + pdat[cx +1]) & 0x00ff;
  428.         pdat[cx+2] = (stat[cx+1] ^ al) & 0x00ff;
  429.         cx = cx +1;
  430.     }
  431.  
  432. // Now save pdat[] to disk (player.dat)
  433.  
  434.     fp = fopen("player.dat","wb");
  435.     for(i=0; i<flen; i++)
  436.         putc(pdat[i],fp);
  437.     fclose(fp);
  438.  
  439.     textcolor(WHITE);
  440.     lowvideo();
  441.     clrscr();
  442.  
  443.     return(0);
  444.  
  445. }
  446.