Author [EN] [PL] [ES] [PT] [IT] [DE] [FR] [NL] [TR] [SR] [AR] [RU] [ID] Topic: Castlevania 3: Dracula's Curse Password Generator  (Read 13823 times)

0 Members and 1 Guest are viewing this topic.

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1860
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Castlevania 3: Dracula's Curse Password Generator
« on: March 11, 2012, 12:45:30 PM »
+1
To open this thread, I first want to share a quote I saw on Wikipedia from Ken Arnold, one of the creators of the classic PC game "Rogue":
Quote
"Every program has at least one bug and can be shortened by at least one instruction — from which, by induction, it is evident that every program can be reduced to one instruction that does not work."



With that now out of the way, I present to you my Castlevania III Password Generator. Simply run the executable, input any name you want (up to 8 letters, of course), select the starting stage, choose your partner (or play alone as Trevor), and choose your difficulty. The program will then generate a password for you to use in Dracula's Curse. The controls are as follows:

CTRL key: Advances the title screen; Sets name (same as END option); Restarts the program
C key: Advances the screens; Makes selections
Z key: Deletes a letter in the name; Moves backwards through the stage/ally/difficulty screens

Castlevania III/Akumajou Densetsu Password Generator v1.0
« Last Edit: March 12, 2012, 01:41:45 AM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1860
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Re: Best Dracula's Curse Passwords Ever
« Reply #1 on: March 11, 2012, 09:01:13 PM »
0
What the hell? I'm baffled here.

So I debugged my script using the name "ABCDEFGH" with Trevor solo on Stage 1 (Clock Tower Ascending... don't argue, I know what I'm talking about) on normal difficulty. I ran my script and checked the output one line at a time. Everything matched up just fine (I had a couple typos here and there but nothing major), so I fixed up the script that draws the password and ended up with something that I knew worked because I used it in the game before.

Then I tried generating a password for a different stage.

So yeah, the interesting thing here is that I can generate password for stages 0 (Wallachia Village), 1 (the clock tower going up), and 5 (the ghost ship) on HARD MODE for any of the characters, and only stages 1 and 5 on normal mode for Trevor solo (can't generate normal mode for any of the other characters). All other stage-character-difficulty combinations result in failed passwords. I mean, what the hell?! Why only those three?

Can't release my password generator until I get this bug figured out.  :-[
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1860
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Re: Castlevania 3: Dracula's Curse Password Generator
« Reply #2 on: March 12, 2012, 01:44:56 AM »
0
http://www.mediafire.com/?5im4cq9zrcym156

More info in the first post, which I modified so the title also shows the proper title.

I worked on this all weekend. Surprisingly the file is over 2 megs, even though it's a tiny little thing. The source code will be available once I crack the decompiler script for use in my engine. For now, if you have a copy of Castlevania 3, you can play around with this little prog and let me know if you find any errors.

If you'll excuse me now, I have 2 hours and 30 minutes left to nap before a 10 hour shift.
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline Corpsecrank

  • XXX
  • Vampire Hunter
  • ***
  • Posts: 339
  • Gender: Male
  • Still uttering the same nonsense.
    • Awards
  • Favorite Game: Castlevania: Symphony of the Night (PS1/SS)
  • Likes:
Re: Castlevania 3: Dracula's Curse Password Generator
« Reply #3 on: March 12, 2012, 05:33:36 AM »
0
Finally got this out eh.
You can find all my projects here: https://thetilepile.blogspot.com/

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1860
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
Re: Castlevania 3: Dracula's Curse Password Generator
« Reply #4 on: March 12, 2012, 07:41:42 AM »
0
Well the script I did start off debugging did have bugs in it, but the heart of all my bugs was in other scripts. Like, my bitwise operation scripts would cause errors when argument1=0, which I realized happened quite often, so I had to fix those scripts. The database of constants typically went up to 8 or 9 constants per argument0, but when I debugged, I found out one of the argument0 cases needed 20 constants, so I had to go back and fetch those. The script which translated the password into the icons was looping back on itself, so in only 1 out of 400 cases it would give a working password. And the other reason it took me so long to release is because I had no flippin' idea prior to setting out to accomplish this how to read Assembly or work in binary.

If you can't think of anything better to do, you can always compile all the possible passwords. It's quite doable:

17 x
There are 17 stages in Dracula's Curse; the Clock Tower and the Forest take up two stages each.
4 x
There are 4 possible partnership options; you can solo as Trevor or partner with Sypha, Grant, or Alucard.
2 x
There are two difficulties, normal or hard.
8 x
There are actually only 8 name combinations. The way the name is handled is it modifies each letter by a constant, adds them together, then reudces it to the modulo of 8, so the name is really any value from 0 to 7; this is why TREVOR has the same password set as MICHAEL and ABCDEFGH.
2 to 4
This part is negligible, but since it's in the code, I included it. Konami was trying to be evil, I think. Each password is modified pseudo-randomly. There is a byte that increments each step, so it basically randomizes the passwords. I can't remember the code off the top of my head (I'm at work right now), so it will produce anywhere from 2 to 4 variants of each password (I want to say there's a modulo of 4 involved). The variation is small and neglecting this byte should have no significant effect on the password generation.

So there's only 17x4x2x8(x [2:4])=1088 (or [2176:4352]) possible passwords. I think. ... I have a nagging hunch there may be less, but that's my answer.
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Offline Inccubus

  • Wannabe Great Old One
  • Master Hunter
  • *****
  • Posts: 3265
  • Gender: Male
  • Warrior
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. SuperOld Dungeonite: Members who have been around since the oldOLD days. Permanent Resident: Seems to always be around to post/reply.
    • Awards
  • Favorite Game: Vampire Killer (MSX)
  • Likes:
Re: Castlevania 3: Dracula's Curse Password Generator
« Reply #5 on: March 12, 2012, 10:43:36 AM »
0
Bravo!
"Stuff and things."

Offline TheouAegis

  • Amateur Auteur of GMvania
  • Master Hunter
  • *****
  • Posts: 1860
  • Gender: Male
  • Awards The Retro Gamer: Has a heated passion for the oldschool VG Titles. The Great Defender will always defend the object of his or her fandom. Hack Master makes creations out of CV parts. (S)he makes Dr. Frankenstein proud.
    • GMvania Developer's Blog
    • Awards
  • Likes:
CV3 Password Generator Code finally released
« Reply #6 on: April 14, 2012, 08:36:13 PM »
+1
The original version used in the initial release relied heavily on ds_list structuring for holding variable data. While this made it easier to pass variables between scripts and across objects (if ever that should be desired), it was a huge waste of resources (if you think about how many bytes one list index takes up, then multiply that by 30... Yeah, not very efficient). 

So I rewrote the script to use variables. Since most of the variables are object-local, care needs to be taken to make it difficult for people to hack the script if its used in a fan game. A few variables have been edited to be script-local to make it a tad harder to hack, but it's still a lot easier to hack than before, especially since all the variables will be located in the RAM pretty close to each other rather than spread out as they were with the ds_list method.

The various subscripts have been minimalized as well. This was another crack-stopper method I was considering -- jump between so many subscripts that any possible rookie hackers would become befuddled from the chaos. The latest version only retains those functions which alter or read the Status Byte's carry bit, effectively reducing the script count by half.

So if I am so worried about people cracking the script, why release it? Because my concern isn't people cracking the original script, it's people cracking your variations on the script. And since the base code is now out, it's up to anyone who wants to use it for their fan game to take great pains in modifying it to be crack-resistant. Sorry, that's just how it is.

I'll release the Password Decryptor whenever I get around to actually working on it. It's three times as long.

Code: [Select]
////VARIABLES TO BE SET IN THE CREATE EVENT////
cbit=0;
byte_a=0;
byte_y=0;
byte_0=0;
byte_1=0;
byte_3=0;
byte_4=0;
for (byte_x=5;byte_x<14;byte_x+=1)
{
    execute_string("byte_"+string(byte_x)+"=0;");
}


////NAME SET SCRIPT////
/*
Modifies the values saved in the name[v] array. Initially the values are
set to the corresponding image_index in the sprite cv_font; to work with
the password generator, the values need to match the original in CV3.
*/

//Set values to be encrypted
if argument0
{
    for (name_slot=0;name_slot<8;name_slot+=1)
        if name[name_slot]>0
            name[name_slot]+=$2F;
}
//Set values to be drawn
else
    for (name_slot=0;name_slot<8;name_slot+=1)
        if name[name_slot]>0
            name[name_slot]-=$2F;


////THE HEXED SCRIPT////
switch argument1
{
case 0:
    var dec,hex,h,byte,hi,lo;
    dec = argument0;
    if (dec) hex = ""; else hex="00";
    h = "0123456789ABCDEF";
    while (dec) {
        byte = dec & 255;
        hi = string_char_at(h,byte div 16 + 1);
        lo = string_char_at(h,byte mod 16 + 1);
        hex = hi + lo + hex;
        dec = dec >> 8;
    }
    return hex;
    break;

case 1:
    var hex,dec,h,p;
    hex = string_upper(argument0);
    dec = 0;
    h = "0123456789ABCDEF";
    for (p=1;p<=string_length(hex);p+=1) {
        dec = dec << 4 | (string_pos(string_char_at(hex,p),h)-1);
    }
    return dec;
    break;
}


////ADC SCRIPT////
variable_local_set(argument0,variable_local_get(argument0)+argument1+cbit);
//Since 6502 processed single bytes, only the lowest byte is saved
if variable_local_get(argument0)>$FF
    cbit=1;
variable_local_set(argument0,variable_local_get(argument0)&$FF);
return variable_local_get(argument0);


////CMP SCRIPT////
if !argument2
{
    if argument0 >= argument1
        cbit=1;
    else  cbit=0;
}
if argument0 > argument1
    return 1;
else
if argument0 < argument1
    return -1;
else
    return 0;


////ROL SCRIPT////
var C;
C = cbit;
cbit=variable_local_get(argument0)>>7;
variable_local_set(argument0,((variable_local_get(argument0) << 1) & (1 << 8)-1) | C);


////ASL SCRIPT////
cbit=variable_local_get(argument0) >> 7;
variable_local_set(argument0,(variable_local_get(argument0) << 1) & $FF);
return variable_local_get(argument0);


////LSR SCRIPT////
cbit=variable_local_get(argument0) & 1;
variable_local_set(argument0,(variable_local_get(argument0) >> 1) & $FF);
return variable_local_get(argument0);


////THE CODE ITSELF////
var byte_r, byte_2, pw3, pwt;
//This counted steps in the game; it's just a random value here.
byte_r=irandom($FF);
//This is actually performed later in the script, but was moved up here.
if ally&$FF=$FF ally=0
//Clear the carry bit
cbit=0;
name_set(1);
//This subscript encrypts the player name and sums up the letters.
//Yes, it takes this many steps to sum 3 variables.
for (byte_x=0;byte_x<$8;byte_x+=1)
{
    byte_a=name[byte_x];
    adc("byte_a",cryptos(0,byte_x));
    cbit=0;
    adc("byte_a",byte_0);
    cbit=0;
    byte_0=byte_a;
}
byte_0&=$7;
byte_a=stage;

//Change $11 to the highest resumable stage value
cmp(byte_a,$11);
if cbit stage=$11;

lsr("byte_a");
rol("byte_0");
byte_a=byte_r;
lsr("byte_a");
repeat(3) rol("byte_0");
byte_a=ally|byte_0;
asl("byte_a");
byte_13=byte_a|quest;
byte_a=byte_r;
lsr("byte_a");
byte_4=$50+($50*cbit);
byte_a=byte_13;
repeat(4) asl("byte_a");
byte_3=byte_a;
cbit=0;
byte_1=adc("byte_a",byte_13&$F0);
byte_0=byte_4^(byte_13&$F0);
byte_a=byte_4^byte_3;
cbit=0;
adc("byte_a",byte_0);
repeat(4) lsr("byte_a");
byte_a|=byte_1;
cbit=0;
byte_1=adc("byte_a",stage);
byte_0=byte_13;
byte_13=$0;
for(byte_x=$0;byte_x<$8;byte_x+=1)
{
    temp=string(5+byte_x);
    lsr("byte_0");
    rol("byte_"+temp);
    lsr("byte_1");
    rol("byte_"+temp);
}
byte_a=stage;
byte_y=lsr("byte_a");
for(byte_x=$2;byte_x>=$0;byte_x-=1)
{
    byte_0=cryptos(1,byte_y)&$C;
    repeat(2) lsr("byte_0");
    byte_a=(cryptos(1,byte_y)&$30)|byte_0;
    if cmp(byte_a,cryptos(2,byte_x))==0 break;
}
byte_y=byte_x;
repeat(3) asl("byte_y");
adc("byte_y",byte_x);
for(byte_x=$0;byte_x<$9;byte_x+=1)
{
    temp=string(5+byte_x);
    byte_1=cryptos(3,byte_y+1)&$30;
    byte_a=cryptos(3,byte_y+1)&$3;
    repeat(2) asl("byte_a");
    byte_a|=byte_1|variable_local_get("byte_"+temp);
    pw3+=hexed(byte_a);
    byte_y+=1;
}
cbit=1;
byte_y=stage;
lsr("byte_y");
pw3+=hexed(cryptos(1,byte_y));
name_set(0);

//Create the password as read by pw_draw()
var L,K;
pw = 0;
for (L=$1;L<$14;L+=$2)
{
    pwt=hexed(string_copy(pw3,L,2),1)
    for (K=$0;K<$10;K+=$1)
    {
        if pwt<=K*$4+$3 && pwt>=K*$4
        {
            pwt&=$3;
            pw += pwt<<(K*$2);
        }
    }
}
« Last Edit: April 14, 2012, 08:53:10 PM by TheouAegis »
Your mom has had more floppies put in her than a Commodore 64!


Follow my lack of progress on my game at my blog:
http://gmvania.blogspot.com

Tags: