Announcement

Collapse
No announcement yet.

Code Designer 3

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Code Designer 3

    CodeDesigner 3 finally has a demo release! I can't debug everything myself so it would be helpful to get some people to play with it and let me know what they think. It has made so many improvements over the old VB6 version. Now writing your 32 Bit MIPS routines is easier than ever. Utilizing some of the C syntax for implementation of IF, SWITCH, FOR Loops, While Loops, FNC Calls, etc, projects can be knocked out faster.

    Download: CD3.rar

    Update *Fixed issue with mouse click on source viewer, fixed a bug found with the multi-line comments
    Update *Added Threading, Events, Updated function Calls, Fixed minor GUI bugs, allowed function calls to pass data instead of just arguments

    It is not finished yet, it still lacks some of the features for now (but will be added soon). Some things to look forward to in the near future would be the Code Debugger, Memory dump analyzing (and possibly *decompiling* to an extent), library creation and archiving, ELF creation / modification, etc.

    If the read me file doesn't explain how to utilize newly implemented functionality, I am always here to answer any questions.

    The current (pretty sloppy, still cleaning it up) source code can be found on GIT: https://github.com/mbacker80/CodeDesigner3

    README:
    Code:
    CodeDesigner 3 (Created by Gtlcpimp)
    
    
    CodeDesigner has finally made its way onto the .NET framework. During the transition it has picked up
    a lot more functionality. Combining some syntax from C with the MIPS32 instruction set, it is capable
    of so much more possibilities than the original design. The build is not yet completely finished,
    however is ready enough to be toyed with (or even build projects with). Here's a look at the updates:
    
    ====================================================================================================
    1) Shorthand Math
    
    Yes! Finally! Shorthand math! I bet we are all sick of seeing all those ADDIU's and what not. Well
    you can't replace them entirely just yet, shorthand math is limited to 16 Bit integer math. So you'll
    still need those hideous LUI's and ADDIU's for larger values. Here's what we have for short handing:
    
    ++ // Register + 1
    -- // Register - 1
    += // Register + Value (or another register)
    -= // Register - Value (or another register)
    
    Here's some examples:
    
    a0++ // Increases the value of a0 by 1
    a0-- // Decreases the value of a0 by 1
    a0 += 50 // Increase the value of a0 by 50
    a0 -= v0 // Decrease the value of a0 by the value of v0
    
    
    Oh and don't forget bit shifting!
    
    >> // Shift right X bits (srl)
    << // Shift left X bits (sll)
    >>> // DOUBLE shift right X bits (dsrl)
    <<< // DOUBLE shift left X bits (dsll)
    >>32 // DOUBLE shift right X bits times 32 (dsrl32)
    <<32 // DOUBLE shift right X bits times 32 (dsll32)
    
    Examples:
    
    a0 >> 10 // Shifts the 32 bit word value in a0 to the right by 10 bits
    v0 << 4 // Shifts the 32 bit word value in v0 to the left by 4 bits
    t0 >>> 16 // Shifts the 64 bit double word value in t0 to the right by 16 bits
    t1 <<< 16 // Shifts the 64 bit double word value in t1 to the left by 16 bits
    v0 >>32 0 // Shifts the 64 bit double word value in v0 to the right by 32 bits
    v1 <<32 0 // Shifts the 64 bit double word value in v1 to the left by 32 bits
    
    
    Shorthand math is super simple, and can be implemented virtually everywhere in your project. What
    would we do without it? It makes life so much easier.
    
    ====================================================================================================
    2) IF Statements
    
    There are multiple ways to declare an IF statement. You can either do a single instruction IF or a
    multiple instruction IF. The difference is literally in the braces. If you do not include braces
    after declaring IF, it will compile it as a single instruction. If you do include the braces, it
    compiles as a multiple instruction IF. Here is the syntax for the declaration:
    
    //Single Instruction IF
    if (condition)
        //ONE (ONLY ONE) Instruction goes here 
    
    // Multiple Instruction IF
    if (condition)
    {
        /*
            As many instructions as your heart desires can go here
        */
    }
    
    The conditions are very simple:
    
    > Greater than
    < Less than
    >= Greather than or equal to
    <= Less than or equal to
    == Is equal to
    <> Does not equal
    
    Live code examples:
    
    //Single Instruction IF
    if (a0 > t3)
        v0 = 1
    
    // Multiple Instruction IF
    if (v0 <= 0)
    {
        a0 += 4
        lw v0, $0000(a0)
        /*
            Etc.
        */
    }
    
    
    Now we can't forget about our ELSE statements, yes we have those too! They follow the exact same 
    guidelines as the IF declarations, with the exact same syntax. All except for the ELSE itself,
    of course. ELSE IF is used for an extra conditional statement, as many times as you need. The
    ELSE statement itself however, is the fallback condition for if the IF did not execute. Here's
    the examples:
    
    // Single Instruction IF/ELSE
    if (a0 > 0)
        lw v0, $0000(a0)
    else
        v0 = -1
    
    Single Instruction IF's can be combined with a Single Instruction ELSE only. You cannot use ELSE IF
    here. That is reserved for the multi-instruction declaration (literally just add braces).
    
    // Multi-conditional IF/ELSE IF/ELSE
    if (a0 == 1)
    {
        v0 = 1
    }
    else if (a0 == 2)
    {
        v0 = 2
    }
    else if (a0 == 3)
    {
        v0 = 3
    }
    else
    {
        v0 = 0
    }
    
    What this code gets compiled out to is this:
    
    addiu at, zero, $0001
    beq a0, at, $0007
    addiu at, zero, $0002
    beq a0, at, $0008
    addiu at, zero, $0003
    beq a0, at, $0009
    nop
    beq zero, zero, $000a
    nop
    addiu v0, zero, $0001
    beq zero, zero, $0008
    nop
    addiu v0, zero, $0002
    beq zero, zero, $0005
    nop
    addiu v0, zero, $0003
    beq zero, zero, $0002
    nop
    daddu v0, zero, zero
    
    
    You can have as many ELSE IF's as you want as long as you keep them wrapped with those braces! Also
    you must note that it utilizes the "at" register (which stands for Assembler Temporary), so avoid
    the use of this register at all cost if using the IF statements.
    
    ====================================================================================================
    3) SWITCH Statements
    
    SWITCH Statements are very similar to the IF statements, however only compares the value of a single
    register to multiple cases that are specified. Syntax as follows:
    
    switch (a0)
    {
    	case 0
    	{
    		v0 = 0
    	}
    	case 1
    	{
    		v0 = 1
    	}
    	case 2
    	{
    		v0 = 2
    	}
    	case 3
    	{
    		v0 = 3
    	}
    	case default
    	{
    		v0 = -1
    	}
    }
    
    You can have as many cases as you like, with any value you choose. The default is similiar to the ELSE
    of an IF statement, it gets executed if none of the cases were true. Since everything is required to
    be wrapped in braces, you can have as many lines of code inside the cases as you desire. The SWITCH
    also compiles using the "at" register to do comparisons just like the IF statement, so avoid the use
    of this register when using a SWITCH.
    
    What the example would compile to is:
    
    beq a0, zero, $000b
    ori at, zero, $0001
    beq a0, at, $000c
    ori at, zero, $0002
    beq a0, at, $000d
    ori at, zero, $0003
    beq a0, at, $000e
    ori at, zero, $0000
    beq a0, at, $000f
    nop
    beq zero, zero, $0010
    nop
    daddu v0, zero, zero
    beq zero, zero, $000d
    nop
    addiu v0, zero, $0001
    beq zero, zero, $000a
    nop
    addiu v0, zero, $0002
    beq zero, zero, $0007
    nop
    addiu v0, zero, $0003
    beq zero, zero, $0004
    nop
    addiu v0, zero, $ffff
    beq zero, zero, $0001
    nop
    
    
    ====================================================================================================
    3) FNC Declarations
    
    You now have the capability to declare functions to save time and energy. Functions must be wrapped
    with braces, and you can specify extra stack space if needed for preserving more registers.
    
    Syntax:
    
    fnc MyFunction(EE a0, EE a1, EE a2) \s0,s1,s2,s3,s4
    {
        s0 = a0
        s1 = a1
        s2 = a2
        
        /*
            do some stuff
        */
        
        return 1;
    }
    
    
    As you see, you declare "fnc" followed by the name of your function, then in the paranthesis you
    can specify any arguments you want it to use. The backslash at the end declares what registers you
    want to be preserved onto the stack. The compiler does all of the work for you. You can force the
    function to exit by calling "return" followed by whatever value you want to have returned. The return
    will place the specified value (or register value) into "v0".
    
    As you can see, this code will compile out to this:
    
    
    addiu sp, sp, $ffa0
    sq ra, $0000(sp)
    sq s0, $0010(sp)
    sq s1, $0020(sp)
    sq s2, $0030(sp)
    sq s3, $0040(sp)
    sq s4, $0050(sp)
    daddu s0, a0, zero
    daddu s1, a1, zero
    daddu s2, a2, zero
    beq zero, zero, $0001
    ori v0, zero, $0001
    lq ra, $0000(sp)
    lq s0, $0010(sp)
    lq s1, $0020(sp)
    lq s2, $0030(sp)
    lq s3, $0040(sp)
    lq s4, $0050(sp)
    jr ra
    addiu sp, sp, $0060
    
    
    ====================================================================================================
    3) FOR Loops
    
    FOR loops can help cut down code, and remove the need to always calculate branch values or throwing
    labels everywhere. It follows the same concept from C, where you have the syntax:
    
    for (init; condition; increment)
    {
        // Code
    }
    
    You can use shorthand math in the increment statement. Live code example:
    
    for (a0 = 0; a0 < 100; a0++)
    {
        v0++
    }
    
    What this would compile to:
    
    daddu a0, zero, zero
    addiu at, zero, $0064
    subu at, a0, at
    bgez at, $0004
    nop
    addiu v0, v0, $0001
    beq zero, zero, $fffa
    addiu a0, a0, $0001
    
    
    ====================================================================================================
    4) WHILE Loops
    
    WHILE Loops are conditional only loops. While the condition is TRUE, it keeps looping. It can be used
    to create an infinite loop:
    
    while (1)
    {
        // Code
    }
    
    Or an actual conditional loop:
    
    while (a0 < 100)
    {
        v0++
    }
    
    What this example would compile out to:
    
    addiu at, zero, $0064
    subu at, a0, at
    bgez at, $0004
    nop
    addiu v0, v0, $0001
    beq zero, zero, $fffa
    nop
    
    
    ====================================================================================================
    5) BREAK
    
    BREAK has been implemented naturally since we have SWITCH, FOR, and WHILE statements. Yes there is
    a MIPS instruction called BREAK already, so what has been done is the compiler checks to see if you
    are using the instruction or the command.
    
    break; // Breaks out of current loop (or case)
    break(1); // Breaks out of current loop and parent loop (or case)
    break(2); // ^ + next parent loop (or case)
    
    So on, so forth. To use the actual MIPS instruction, you must specifically use the syntax for the
    instruction itself:
    
    break (00000)
    
    
    
    ====================================================================================================
    6) Compiler Specific "Commands"
    
    Address $00100000 // Specifies code output addressing
    Labels: // Declares a label at this current section of the source
    setreg v0, $12345678 // Sets a 32 bit value into the register
    setfpr f0, $3f800000 // Sets the float regsiter to the 32 bit value
    setfloat f0, 5 // Sets the float register to the specified integer value
    
    goto :label
    goto $00100000 // Sets a direct branch (or jump if target address is out of branch range)
    
    extern $00100000 funcName(EE t0, EE t1, COP1 f0) // Similiar to FNC only declaring an "external" function
    							at the specified memory address so you can call
    							to it.
    
    call funcname(s0, s1, s2) // Calls a function you have declared, placing the arguments you specify into the
    			corresponding argument registers
    
    define labelName $12345678 // Defines a new label of the specified value
    
    hexcode $12345678 // Directly outputs the value to the code output
    print "string" // Prints the string directly to the code output
    
    
    string labelName "my string" // Creates a string, appends to the END of the code output, preserving its
    				memory address in the specified label
    
    padding $20 // Generates 0's in the code output to the specified size
    
    
    
    ====================================================================================================
    7) Threading
    
    Yes and no. It's not actual "threading" its similiar but not the actual same. The EE can't do real
    multi-threading. So what we are going to be doing, is creating a list of functions that will be
    executed in order. Just to keep it simple to understanding, we're going to call it threading.
    
    First off let's start with how to declare a thread. Syntax is very simple:
    
    thread myFunc
    
    Simple enough, right? Let's take a look at the options available for it:
    
    thread myFunc /delay 100
    thread myFunc /off
    thread myFunc /delay 100 /off
    
    
    What does that mean? Well, the delay is an iteration delay to basically "slow down" how often it
    executes. So if you follow the example, a delay of 100 means it will only execute the thread every
    100th iteration of the main process. As for the "off", that means that our thread is not going to
    be active until specified within one of our actual functions. Default is on, without delay.
    
    A thread can be started and stopped, also put to sleep (set on delay) or woken up (delay removed).
    The syntax is simple:
    
    thread.sleep (myFunc, 1000) // Put's thread "myFunc" to a delay to only execute once every 1000th iteration
    thread.wakeup (myFunc) // Removes the delay and allows it to run as fast as the main process can call it
    thread.stop (myFunc) // Stops the execution of the thread entirely, it will never execute until its started
    thread.start (myFunc) // Starts a thread back up so it will start executing again
    
    
    ====================================================================================================
    8) Data-Watch Events
    
    Data-Watch events are basically a thread that watches a memory address, and executes your function
    if the data you set to watch appears in the memory address. Think of it like an IF statement, but
    simplified, on a higher level. Here's the syntax:
    
    event myFunc $00100000 $12345678 /w
    
    In the syntax, you declare your functions name, then the memory address to watch, followed by the
    data that you are looking for. The "/w" is the statement that declares if it's a byte "/b", half word
    "/h", or word "/w".
    
    Here's a live example:
    
    event padInput_X $007157dc $bfff /h
    
    In this example, we are setting an event to watch if the button 'x' is being held down
    (on SOCOM: Combined Assault)
    
    
    ====================================================================================================
    8) Hooks
    
    How can any of our routines run if we don't hook them from the game? We now have a simplified method
    for this. As long as you know what the memory address is you want to hook from, you can use the HOOK
    feature. Let's look at the syntax:
    
    hook myFunc $00100000 -j
    
    In this example, we are placing a "jump" hook to our function at memory address $00100000. We can do
    other types of hooks by changing the option. For example:
    
    -j = Jump
    -jal = Jump and Link
    -pointer = Pointer
    
    Pretty obvious, and very simple. Now for something important. We introduced threading, and events.
    Now we obviously must hook our handler that operates those features. For that, we have a seperate
    command called "ProcHook" (short for Process Hook). If we know what the memory address is that
    we want to hook from, and have our threads and events set up, we will do this:
    
    prochook $00100000 -j // or -jal or -pointer whichever is needed
    
    This will allow our event handler and thread manager to run.
    Some of the screen shots:
    Click image for larger version

Name:	CD3 Extract.png
Views:	1
Size:	66.9 KB
ID:	163947
    Click image for larger version

Name:	CD3 Classic Mode.png
Views:	1
Size:	35.5 KB
ID:	163948
    Click image for larger version

Name:	CD3 Projects Mode.png
Views:	1
Size:	21.0 KB
ID:	163949


    Code Examples (String Manipulation)
    Code:
    /*
    	Strings Library
    	Created by: Gtlcpimp
    */
    
    //============================================================
    // Upper Case -> Converts to Upper Case
    /*
    Input:
    	a0 = &String
    
    C Syntax Equivalent:
    	void toUpperCase(char *src)
    */
    
    fnc UCase(EE a0) \s0,s1
    {
    	// Take our pointer to the string
    	s0 = a0
    	
    	// Find out the length of the string
    	call strLen(s0)
    	s1 = v0
    	
    	// Loop through the entire string by its length
    	for (a0 = 0; a0 < s1; a0++)
    	{
    		// Load the character at our current position
    		lbu v0, $0000(s0)
    		
    		// Check to see if it's a lower 'a' or greater value
    		if (v0 >= $61)
    		{
    			// Check to see if it's a lower 'z' or less (a-z)
    			if (v0 < $7b)
    			{
    				// Decrease it's value to that of the Upper
    				// Case letters, then store back in place
    				v0 -= $20
    				sb v0, $0000(s0)
    			}
    		}
    		
    		// Increment our position in the string
    		s0++
    	}
    	// Return nothing, function is void
    }
    
    //============================================================
    // Lower Case -> Converts to Lower Case
    /*
    Input:
    	a0 = &String
    
    C Syntax Equivalent:
    	void toLowerCase(char *src)
    */
    fnc LCase(EE a0) \s0,s1
    {
    	// Take our pointer to the string
    	s0 = a0
    	
    	// Find out the length of the string
    	call strLen(s0)
    	s1 = v0
    	
    	// Loop through the entire string by its length
    	for (a0 = 0; a0 < s1; a0++)
    	{
    		// Load the character at our current position
    		lbu v0, $0000(s0)
    		
    		// Check to see if it's a capital 'A' or greater value
    		if (v0 >= $41)
    		{
    			// Check to see if it's a capital 'Z' or less (A-Z)
    			if (v0 < $5b)
    			{
    				// Increment it's value to that of the Lower
    				// Case letters, then store back in place
    				v0 += $20
    				sb v0, $0000(s0)
    			}
    		}
    		
    		// Increment our position in the string
    		s0++
    	}
    	// Return nothing, function is void
    }
    
    //============================================================
    // String Length -> Gets the length of the string
    /*
    Input:
    	a0 = String
    Output:
    	v0 = String Length
    
    C Syntax Equivalent:
    	int strLen(char *src)
    */
    fnc strLen(EE a0)
    {
    	// Start our counter at 0
        v0 = 0
        
        // Check the first character to make sure it's not empty
        lbu v1, $0000(a0)
        while (v1)
        {
        	// Load the character at our current position
            lbu v1, $0000(a0)
            
            // Check if it's the end of the string
            if (v1 == 0)
            	break;
            
            // Increment our position in the string
            a0++
            
            // Increment our counter, we aren't at the end yet
            v0++
        }
        // Return register v0 is already loaded as the counter
        // and will be returned to the parent function
    }
    
    //============================================================
    // String Clear -> Erases the entire string (places NULL chars)
    /*
    Input:
    	a0 = String
    
    C Syntax Equivalent:
    	void strClear(char *src)
    */
    fnc strClear(EE a0)
    {
    	// Make sure we aren't already at the end of the string
    	lbu v0, $0000(a0)
    	while (v0)
    	{
    		// Store a NULL char (erasing the existing char)
    		sb zero, $0000(a0)
    		
    		// Increment our position in the string
    		a0++
    		
    		// Load the next char for checking if it's the end
    		lbu v0, $0000(a0)
    	}
    	// Return nothing, function is void
    }
    
    //============================================================
    // String Copy -> Copies a string to the specified destination
    /*
    Input:
    	a0 = Source String
    	a1 = Destination String
    	a2 = Source Start Position (index)
    Output:
    	v0 = End of Source String (NULL + 1)
    	v1 = Number of chars copied
    
    C Syntax Equivalent:
    	int strCopy(char *src, char *dst, int index)
    */
    fnc strCopy(EE a0, EE a1, EE a2) \s0,s1
    {
    	// Set our position in the Source String
    	daddu s0, a0, a2
    	
    	// Set our destination
    	s1 = a1
    	
    	// Make sure we aren't at the end of the source string
    	lbu v1, $0000(s0)
    	while (v1)
    	{
    		// Store our character in the destination string
    		sb v1, $0000(s1)
    		
    		// Increment to the next position in the Source
    		s0++
    		
    		// Increment to the next position in the Destination
    		s1++
    		
    		// Load the character next character to copy
    		lbu v1, $0000(s1)
    	}
    	
    	// End our destination string by placing a NULL character
    	sb zero, $0000(s1)
    	
    	// Set our return register v1 to the copied byte count
    	subu v1, s1, a1
    	
    	// Set our return register v0 to be end of source + 1
    	addiu v0, s1, 1
    }
    
    //============================================================
    // String Compare -> Compares 2 Strings
    /*
    Input:
       a0 = String 1
       a1 = String 2
    Output:
       v0 = -1 or 0 or 1
       	-1: String 1 goes before String 2 (alphabetically)
       	 0: Strings are identical
       	 1: String 1 goes after String 2 (alphabetically)
    C Syntax Equivalent:
    	int strCompare(char *str1, char *str2)
    */
    fnc strCompare(EE a0, EE a1) \s0,s1,s2
    {
    	s0 = a0
    	s1 = a1
    	
    	// Get length of String 1
    	call strLen(s0)
    	s2 = v0
    	
    	// Get length of String 2
    	call strLen(s1)
    	
    	// Check if String 1 is shorter than String 2
    	if (s2 < v0)
    		return -1
    	
    	// Check if String 1 is longer than String 2
    	if (s2 > v0)
    		return 1
    	
    	for (a0 = 0; a0 < s2; a0++)
    	{
    		lbu v0, $0000(s0)
    		lbu v1, $0000(s1)
    		
    		// Compare if str1[x] is less than str2[x]
    		if (v0 < v1)
    			return -1
    		
    		// Compare if str1[x] is greater than str2[x]
    		if (v0 > v1)
    			return 1	
    	}
    	
    	// Both strings are 100% identical
    	v0 = 0
    }

    Live Code Example for Threading and Events:
    Code:
    /*
    	CodeDesigner v3 ~ Created by: Gtlcpimp
    */
    address $000c0000
    
    prochook $002e4e74 -j
    
    event padInput_X $007157dc $bfff /h
    thread threadedRunner
    
    fnc threadedRunner(void)
    {
    	/*
    		We are always running
    	*/
    }
    
    fnc padInput_X(void)
    {
    	/*
    		We only get here if X button is pressed
    	*/
    }
    Last edited by Gtlcpimp; 12-30-2016, 09:55:49 PM.

  • #2
    Looks good pimp. Soften the bright pink, yellow, and green colors in the editor, or put an option to change those colors if you haven't already. I'll check it out when I get back in town.

    Comment


    • #3
      The customization menu will be in it soon, still working on the compiler a bit. Doing some tweaks, adding more functionality. Soon though, you'll be able to change the syntax highlighting colors. For the mean time, little screen shot for the latest update:

      Click image for larger version

Name:	CD3 Threads and Events.png
Views:	1
Size:	63.9 KB
ID:	162934


      Also, an example of Controller Key Press checking.
      Code:
      /*
      	CodeDesigner v3 ~ Created by: Gtlcpimp
      */
      address $000c0000
      
      hook main $002e4e74 -j
      
      define pad_address $007157dc
      
      fnc main() \at,a0,a1,a2,v0,v1
      {
      	call Controller_KeyPress()
      	
      	setreg a0, $006b8934
      	
      	switch (v0)
      	{
      		case $bfff // X Button
      		{
      			lw a1, $0000(a0)
      			lui v0, $4000
      			if (a1 == v0) // Toggle On
      			{
      				lui v0, $3f80
      				sw v0, $0000(a0)
      			}
      			else // Toggle Off
      			{
      				sw v0, $0000(a0)
      			}
      		}
      	}
      }
      
      fnc Controller_KeyPress(void) \s0,s1
      {
      	beq zero, zero, :Controller_KeyPress_SaveData_Branch
      	nop
      	Controller_KeyPress_SaveData:
      	nop
      	Controller_KeyPress_SaveData_Branch:
      	
      	setreg s0, :pad_address
      	setreg s1, :Controller_KeyPress_SaveData
      	
      	lhu a0, $0000(s0)
      	xori a0, a0, $ffff
      	
      	lhu a1, $0000(s1)
      	nor a2, a1, a1
      	and v0, a0, a2
      	sw a0, $0000(s1)
      	
      	addiu v1, zero, -1
      	xor v0, v0, v1
      	
      	// v0 = new button press
      }
      Last edited by Gtlcpimp; 12-30-2016, 10:00:55 PM.

      Comment


      • #4
        This is starting to look really good.

        Comment


        • #5
          and... he's back! and in three weeks manage's to code this amazing mips scripting language... holy shit man, you fuckin rock welcome back, AND you wrote it in a supported language! TFW.... has hell completly frozen over

          Comment

          Working...
          X