Arnold

Adding new SM3 .hlsl shaders to CoD4

22 posts in this topic

:angryarnold:ARRGGHHHH!! :angryarnold:


 

after messing a while with linker_pc.exe in a debugger, i figured out how to add new .hlsl shaders to cod4 :angryarnold:

 


 

first off, download this shader tool i made :angryarnold: https://www.dropbox.com/s/tkuuc6l5d4l0r31/shader_tool_v0.1.zip?dl=0

 

once downloaded, extract the .zip into your cod4 folder and go to raw\shader_bin

at this point, i would recommend you to create a backup of shader_names file in raw\shader_bin just in case the shader tool fucks up its own backup thingy

 

 

in the raw\shader_bin folder, you should now see a folder named shader_src, open it

in the folder you will find a header file (shader_vars.h) containing some stuff you will need in shaders you create for cod4, a sample vertex shader named vs_3_0_test.hlsl and a pixel shader named ps_3_0_test.hlsl (the shader tool requires you to use these prefixes for source files  :angryarnold:)

you will also find a copy of direcx9 shader compiler from direcx9 october 2006 sdk (fxc.exe)

 

 

now, to add this shader named "test" to cod4...

 

1. open up a command prompt in raw\shader_bin

2. type in the following text

shader_tool.exe test

and press enter

3. you should see something like this

uTPSZ4o.png

 

the .hlsl files were compiled and the compiled shaders added to the shader_names file

the new shaders can now be used in cod4

 


 

how to create a material that uses the custom shaders? MORE ON THAT LATER :angryarnold: CBA TO WRITE MORE NOW

 

thanks to @Scillman for helping with figuring out the shader_names file and thanks to @BraXi(nub) for helping with a bug in the sample vertex shader :angryarnold:

 

oh, and heres an example of wat you can do with these things called 'shaders' :kingdave:

https://dl.dropboxusercontent.com/s/h6rg324aieq7iq2/cod4lel2.mp4?dl=0

4

Share this post


Link to post
Share on other sites

You're really obsessed with shaders aren't you

0

Share this post


Link to post
Share on other sites

You're really obsessed with shaders aren't you

no? :dave: why wud yu think so? :ANGRYARNOLD: ARGH!

0

Share this post


Link to post
Share on other sites

Soo can you put these on textures or just model phongs

0

Share this post


Link to post
Share on other sites

Soo can you put these on textures or just model phongs

take a look at these: http://glslsandbox.com/

 

they are all pixel shaders, and EVERY material in cod4 (model phong, world phong, 2d etc.) uses a vertex and a pixel shader, which means, any of those cool effects you see in the link above could be applied to a gun skin, hud element or even a skybox

 

vertex shaders can modify the geometry of stuff & do some other things

1

Share this post


Link to post
Share on other sites

like you know minecraft shaders, couldn't you make similar things for cod4? And make the graphics look great?

This sounds like such a nubby question but I'm wondering..

0

Share this post


Link to post
Share on other sites

like you know minecraft shaders, couldn't you make similar things for cod4? And make the graphics look great?

This sounds like such a nubby question but I'm wondering..

nub question but yu r correct

0

Share this post


Link to post
Share on other sites

nub question but yu r correct

Would it require further developments or is it possible now?

0

Share this post


Link to post
Share on other sites

Would it require further developments or is it possible now?

if ya pro @writing shaders, possible now

0

Share this post


Link to post
Share on other sites

does mikey know glsl or however you write shaders?

 

HLSL, sorry mate it is Windows ;P

0

Share this post


Link to post
Share on other sites

:angryarnold:ARRGGHHHH!! :angryarnold:

:angryarnold: pc_bear together with linker_pc... coincidence? I don't think so :angryarnold:

 


 

If Bear's nubby tool doesn't work on your Kalkulator/Komputer then you're missing Visual C++ Redistibutable 2010 x86

0

Share this post


Link to post
Share on other sites

How about a WaW version?

 

Well CoDWaW doesn't have shader_names file <.< however WaW does have a tool named "ShaderCompiler.exe" I would recommend experimenting with that :sir:

0

Share this post


Link to post
Share on other sites

Just in case anyone interested in the source of the shader tool ...

 

/*
Copyright (c) 2015 Otso O.
 
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
 
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
 
1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgement in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
 
#ifdef _DEBUG
#   define _CRTDBG_MAP_ALLOC
#   include <stdlib.h>
#   include <crtdbg.h>
#endif // _DEBUG
 
int isDefined(void const *ptr)
{
    return (*(uint32_t*)ptr != 0);
}
 
#include <windows.h>
int colorPrint(uint8_t color, char const *fmt, ...)
{
    int result;
    va_list arg;
 
    HANDLE handle = 0;
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
 
    va_start(arg, fmt);
    if(isDefined(&handle))
    {
        SetConsoleTextAttribute(handle, color);
        result = vprintf(fmt, arg);
        SetConsoleTextAttribute(handle, 0x07);
    } else
        result = vprintf(fmt, arg);
 
    va_end(arg);
    return result;
}
 
uint32_t swapByteOrder32(uint32_t uint)
{
    return ((uint & 0x000000ff) << 24) |
           ((uint & 0x0000ff00) << 8)  |
           ((uint & 0x00ff0000) >> 8)  |
           ((uint & 0xff000000) >> 24);
}
 
uint32_t generateHashValue(char const *str)
{
    uint32_t esi, eax, ebx, ecx;
    ebx = ebx ^ ebx;
    for(esi = 0; esi < strlen(str); ++esi)
    {
        ecx = str[esi];
        eax = ebx;
        eax = eax << 5;
        ebx = ebx + eax;
        ebx = ebx ^ ecx;
    }
    return ebx;
}
 
enum COLORS {BLACK, DARK_BLUE, DARK_GREEN, DARK_CYAN, DARK_RED, DARK_MAGENTA, DARK_YELLOW, 
             GRAY, DARK_GRAY, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE};
 
enum SHADER_TYPES {VERTEX_SHADER = 0x01, PIXEL_SHADER = 0x02};
 
typedef struct Shader
{
    uint8_t  type;
    uint32_t hlsl_file;
    uint32_t bin_file;
} Shader;
 
int updateShaders(Shader **shaders, uint32_t num_new);
int getNumShaders(FILE *file, uint32_t *num_vs, uint32_t *num_ps);
int backupShaders(Shader const *shaders, uint32_t ofs, uint32_t num_vs, uint32_t num_ps);
int getUniqueShaders(Shader **shaders, uint32_t num_new, uint32_t num_vs, uint32_t num_ps);
int updateNumShaders(Shader const *shaders, uint32_t num_new, uint32_t *num_vs, uint32_t *num_ps);
int sortShaders(void const *pa, void const *pb);
int compileShaders(int argc, char const **argv);
int updateShaderSize(char const *filename);
 
int main(int argc, char **argv)
{
    int i;
 
    Shader *shaders = 0;
 
    if(argc < 2)
    {
        printf("USAGE: shader_tool.exe <shader_name> <shader_name2> <shader_name3> ...\n");
        colorPrint(YELLOW, "WARNING: The use of special characters in shader names will result in undefined behavior!\n");
        return 0;
    }
 
    shaders = malloc((argc - 1) * sizeof(Shader));
    if(!isDefined(&shaders))
    {
        colorPrint(RED, "ERROR: Failed to allocate %u bytes of memory!\n", ((argc - 1) * sizeof(Shader)));
        return 1;
    }
 
    printf("#----------------------------------------------------------------------------#\n");
    printf("|                  -- Call of Duty 4 - Shader Tool v0.1 --                   |\n");
    printf("|                         Copyright (c) 2015 Otso O.                         |\n");
    printf("#----------#----------------------------#------------------------------------#\n");
    printf("| Hash     | Shader name for techniques | File name in raw\\shader_bin        |\n");
    printf("#----------#----------------------------#------------------------------------#\n");
    for(i = 0; i < (argc - 1); ++i)
    {
        int x;
 
        char const *arg = argv[i + 1];
 
        for(x = 1; x < argc; ++x)
        {
            if(strcmp(argv[x], arg) == 0 && x != (i + 1))
            {
                free(shaders);
                printf("#----------#----------------------------#------------------------------------#\n");
                colorPrint(RED, "ERROR: Encountered a duplicate shader name '%s'!\n", arg);
                colorPrint(RED, "Remove the duplicate shader name from command line arguments and try again.\n");
                return 1;
            }
        }
 
        shaders[i].type      = 0;
        shaders[i].hlsl_file = generateHashValue(arg);
        shaders[i].bin_file  = 0xFFFFFFFF - swapByteOrder32(shaders[i].hlsl_file);
        printf("| %.8X | %-24.24s%s | vs_3_0_%.8x or ps_3_0_%.8x |\n", 
                   swapByteOrder32(shaders[i].hlsl_file), arg, strlen(arg) > 24 ? ".." : "  ", 
                   shaders[i].bin_file, shaders[i].bin_file);
    }
    printf("#----------#----------------------------#------------------------------------#\n");
 
    qsort(shaders, (argc - 1), sizeof(Shader), sortShaders);
    updateShaders(&shaders, (argc - 1));
    free(shaders);
 
    compileShaders(argc, argv);
 
#ifdef _DEBUG
    system("pause");
    _CrtDumpMemoryLeaks();
#endif // _DEBUG
 
    return 0;
}
 
int updateShaders(Shader **shaders, uint32_t num_new)
{
    int i, j;
 
    FILE *file      = 0;
    Shader *temp    = 0;
    void *ptr       = 0;
    uint32_t ofs    = num_new;
    uint32_t num_vs = 0;
    uint32_t num_ps = 0;
    uint32_t total  = 0;
    int count       = 0;
 
    printf("\nUpdating 'shader_names' file ...\n");
    file = fopen("shader_names", "rb");
    if(!isDefined(&file))
    {
        colorPrint(RED, "ERROR: Failed to open file 'shader_names' for reading!\n");
        colorPrint(RED, "Make sure you are running shader_tool.exe in the raw\\shader_bin\\ directory.\n");
        return 0;
    }
    if(!getNumShaders(file, &num_vs, &num_ps))
    {
        fclose(file);
        return 0;
    }
 
    total = (num_vs + num_ps + num_new);
    temp = realloc(*shaders, total * sizeof(Shader));
    if(!isDefined(&temp))
    {
        fclose(file);
        colorPrint(RED, "ERROR: Failed to allocate %u bytes of memory!\n", total * sizeof(Shader));
        return 0;
    }
    
    *shaders = temp;
    ptr = ((uint32_t)*shaders + (ofs * sizeof(Shader)));
    memset(ptr, 0, ((num_vs + num_ps) * sizeof(Shader)));
 
    fseek(file, sizeof(uint32_t), SEEK_SET);
    for(i = 0; i < (num_vs + num_ps); ++i)
    {
        if(i == num_vs)
            fseek(file, sizeof(uint32_t), SEEK_CUR);
        
        if(i < num_vs)
            (*shaders)[i + ofs].type = VERTEX_SHADER;
        else
            (*shaders)[i + ofs].type = PIXEL_SHADER;
 
        if(!fread(&(*shaders)[i + ofs].hlsl_file, 1, sizeof(uint32_t), file) || !fread(&(*shaders)[i + ofs].bin_file, 1, sizeof(uint32_t), file))
        {
            fclose(file);
            colorPrint(RED, "ERROR: Failed to read shader #%d!\n", i);
            return 0;
        }
    }
 
    fclose(file);
    if(!backupShaders(*shaders, ofs, num_vs, num_ps))
    {
        colorPrint(RED, "ERROR: Failed to backup the current 'shader_names' file!\n");
        return 0;
    }
 
    file = fopen("shader_names", "wb");
    if(!isDefined(&file))
    {
        colorPrint(RED, "ERROR: Failed to open file 'shader_names' for writing!\n");
        colorPrint(RED, "Make sure you are running shader_tool.exe as administrator!\n");
        return 0;
    }
 
    count = getUniqueShaders(shaders, num_new, num_vs, num_ps);
    printf("%d new shaders\n", count);
    updateNumShaders(*shaders, num_new, &num_vs, &num_ps);
 
    fwrite(&num_vs, sizeof(uint32_t), 1, file);
    for(i = 0; i < total; ++i)
    {
        if((*shaders)[i].type == VERTEX_SHADER)
        {
            for(j = 0; j < num_new; ++j)
            {
                if((*shaders)[i].hlsl_file > (*shaders)[j].hlsl_file && (*shaders)[j].type == 0x00)
                {
                    (*shaders)[j].type = 0xAA;
                    fwrite(&(*shaders)[j].hlsl_file, sizeof(uint32_t), 1, file);
                    fwrite(&(*shaders)[j].bin_file, sizeof(uint32_t), 1, file);
                }
            }
            fwrite(&(*shaders)[i].hlsl_file, sizeof(uint32_t), 1, file);
            fwrite(&(*shaders)[i].bin_file, sizeof(uint32_t), 1, file);
        } else
        if((*shaders)[i].type == 0x00 && (*shaders)[i].hlsl_file < (*shaders)[num_new].hlsl_file)
        {
            (*shaders)[i].type = 0xAA;
            fwrite(&(*shaders)[i].hlsl_file, sizeof(uint32_t), 1, file);
            fwrite(&(*shaders)[i].bin_file, sizeof(uint32_t), 1, file);
        }
    }
 
    fwrite(&num_ps, sizeof(uint32_t), 1, file);
    for(i = 0; i < total; ++i)
    {
        if((*shaders)[i].type == PIXEL_SHADER)
        {
            for(j = 0; j < num_new; ++j)
            {
                if((*shaders)[i].hlsl_file > (*shaders)[j].hlsl_file && (*shaders)[j].type == 0xAA)
                {
                    (*shaders)[j].type = 0xBB;
                    fwrite(&(*shaders)[j].hlsl_file, sizeof(uint32_t), 1, file);
                    fwrite(&(*shaders)[j].bin_file, sizeof(uint32_t), 1, file);
                }
            }
            fwrite(&(*shaders)[i].hlsl_file, sizeof(uint32_t), 1, file);
            fwrite(&(*shaders)[i].bin_file, sizeof(uint32_t), 1, file);
        } else
        if((*shaders)[i].type == 0xAA && (*shaders)[i].hlsl_file < (*shaders)[num_vs].hlsl_file)
        {
            (*shaders)[i].type = 0xBB;
            fwrite(&(*shaders)[i].hlsl_file, sizeof(uint32_t), 1, file);
            fwrite(&(*shaders)[i].bin_file, sizeof(uint32_t), 1, file);
        }
    }
 
    fclose(file);
    return count;
}
 
int getNumShaders(FILE *file, uint32_t *num_vs, uint32_t *num_ps)
{
    uint32_t fsize = 0;
 
    fseek(file, 0, SEEK_END);
    fsize = ftell(file);
    fseek(file, 0, SEEK_SET);
 
    if(fsize == 0)
    {
        colorPrint(RED, "ERROR: File 'shader_names' is empty!\n");
        colorPrint(RED, "Please restore the original 'shader_names' file and try again.\n");
        return 0;
    }
    if(fread(num_vs, sizeof(uint32_t), 1, file))
    {
        if(fseek(file, 8 * (*num_vs) + sizeof(uint32_t), SEEK_SET) == 0 && fread(num_ps, sizeof(uint32_t), 1, file))
        {
            if(fsize == ((2 * sizeof(uint32_t)) + (((*num_vs) + (*num_ps)) * 8)))
            {
                printf("%u vertex shaders\n%u pixel shaders\n", (*num_vs), (*num_ps));
                return 1;
            }
 
            colorPrint(RED, "ERROR: File 'shader_names' is corrupt! Expected size of %u bytes, got %u bytes instead.\n", 
                      ((2 * sizeof(uint32_t)) + (((*num_vs) + (*num_ps)) * 8)), fsize);
        } else
            colorPrint(RED, "ERROR: Could not read the number of pixel shaders!\n");
    } else
        colorPrint(RED, "ERROR: Could not read the number of vertex shaders!\n");
 
    colorPrint(RED, "Please restore the original 'shader_names' file and try again.\n");
    return 0;
}
 
int backupShaders(Shader const *shaders, uint32_t ofs, uint32_t num_vs, uint32_t num_ps)
{
    int i;
    time_t now;
    struct tm *t;
    char filename[64];
 
    FILE *file = 0;
 
    now = time(0);
    t = localtime(&now);
    strftime(filename, sizeof(filename), "backups\\shader_names_%d%m%y%H%M%S.bak", t);
 
    file = fopen(filename, "wb");
    if(!isDefined(&file))
    {
        colorPrint(RED, "ERROR: Failed to create file '%s'!\n", filename);
        colorPrint(RED, "Make sure you are running shader_tool.exe as administrator!\n");
        return 0;
    }
 
    fwrite(&num_vs, sizeof(uint32_t), 1, file);
    for(i = 0; i < (num_vs + num_ps); ++i)
    {
        if(i == num_vs)
            fwrite(&num_ps, sizeof(uint32_t), 1, file);
 
        if(!fwrite(&shaders[i + ofs].hlsl_file, sizeof(uint32_t), 1, file) || !fwrite(&shaders[i + ofs].bin_file, sizeof(uint32_t), 1, file))
        {
            colorPrint(RED, "ERROR: Failed to write shader #%d!\n", i);
            fclose(file);
            return 0;
        }
    }
    fclose(file);
    return 1;
}
 
int getUniqueShaders(Shader **shaders, uint32_t num_new, uint32_t num_vs, uint32_t num_ps)
{
    int i, j;
 
    int uniques    = 0;
    int duplicates = 0;
 
    for(i = 0; i < num_new; ++i)
    {
        for(j = 0; j < (num_vs + num_ps); ++j)
        {
            if((*shaders)[i].hlsl_file == (*shaders)[j + num_new].hlsl_file || (*shaders)[i].bin_file == (*shaders)[j + num_new].bin_file)
            {
                (*shaders)[i].type = 0xFF;
                (*shaders)[i].hlsl_file = 0xDEADBEEF;
                (*shaders)[i].bin_file = 0xDEADBEEF;
                ++duplicates;
            }
        }
    }
    if(duplicates > 0)
        colorPrint(YELLOW, "WARNING: %d of the new shaders already exist in 'shader_names' file!\n", duplicates);
 
    uniques = num_new - duplicates;
    return uniques;
}
 
int updateNumShaders(Shader const *shaders, uint32_t num_new, uint32_t *num_vs, uint32_t *num_ps)
{
    int i;
 
    for(i = 0; i < num_new; ++i)
    {
        if(shaders[i].type != 0xFF)
        {
            ++(*num_vs);
            ++(*num_ps);
        }
    }
    return 1;
}
 
int sortShaders(void const *pa, void const *pb)
{
    Shader *a = (Shader*)pa;
    Shader *b = (Shader*)pb;
    return a->hlsl_file >= b->hlsl_file ? 1 : 0;
}
 
int compileShaders(int argc, char const **argv)
{
    int i;
 
    printf("\nCompiling shaders with fxc.exe ...\n");
    for(i = 0; i < (argc - 1); ++i)
    {
        char shader[32];
        char cmd[256];
 
        char const *arg = argv[i + 1];
        uint32_t bin_file = 0xFFFFFFFF - swapByteOrder32(generateHashValue(arg));
 
        sprintf(shader, "vs_3_0_%.8x", bin_file);
        sprintf(cmd, "shader_src\\fxc.exe shader_src\\vs_3_0_%s.hlsl /T vs_3_0 /E vs_main /Fo vs_3_0_%.8x > nul", arg, bin_file);
        system(cmd);
        updateShaderSize(shader);
 
        sprintf(shader, "ps_3_0_%.8x", bin_file);
        sprintf(cmd, "shader_src\\fxc.exe shader_src\\ps_3_0_%s.hlsl /T ps_3_0 /E ps_main /Fo ps_3_0_%.8x > nul", arg, bin_file);
        system(cmd);
        updateShaderSize(shader);
    }
 
    return 1;
}
 
int updateShaderSize(char const *filename)
{
    FILE *file = 0;
 
    file = fopen(filename, "rb");
    if(isDefined(&file))
    {
        uint8_t *buffer;
 
        uint32_t fsize = 0;
 
        fseek(file, 0, SEEK_END);
        fsize = ftell(file);
        fseek(file, 0, SEEK_SET);
 
        buffer = malloc(fsize * sizeof(uint8_t));
        if(isDefined(&buffer))
        {
            fread(buffer, sizeof(uint8_t), fsize, file);
            fclose(file);
 
            fopen(filename, "wb");
            if(isDefined(&file))
            {
                fwrite(&fsize, sizeof(uint32_t), 1, file);
                fwrite(buffer, sizeof(uint8_t), fsize, file);
                printf("%s, %u bytes\n", filename, fsize);
                fclose(file);
            } else {
                colorPrint(RED, "ERROR: Failed to open file '%s' for writing!\n", filename);
                colorPrint(RED, "Make sure you are running shader_tool.exe as administrator!\n");
            }
            free(buffer);
        } else {
            fclose(file);
            colorPrint(RED, "ERROR: Failed to allocate %u bytes of memory!\n", fsize);
        }
    }
    return 1;
}
 
/*
00464EC0  /$ 55             PUSH EBP
00464EC1  |. 8BEC           MOV EBP,ESP
00464EC3  |. 53             PUSH EBX
00464EC4  |. 56             PUSH ESI
00464EC5  |. 57             PUSH EDI
00464EC6  |. 8B7D 08        MOV EDI,DWORD PTR SS:[EBP+8]
00464EC9  |. 33DB           XOR EBX,EBX
00464ECB  |. 381F           CMP BYTE PTR DS:[EDI],BL
00464ECD  |. 8BF7           MOV ESI,EDI
00464ECF  |. 74 5B          JE SHORT linker_p.00464F2C
00464ED1  |> 8A06           /MOV AL,BYTE PTR DS:[ESI]
00464ED3  |. 3C 41          |CMP AL,41
00464ED5  |. 7C 20          |JL SHORT linker_p.00464EF7
00464ED7  |. 3C 5A          |CMP AL,5A
00464ED9  |. 7F 1C          |JG SHORT linker_p.00464EF7
00464EDB  |. 57             |PUSH EDI                                ; /Arg6
00464EDC  |. 68 9C044F00    |PUSH linker_p.004F049C                  ; |Arg5 = 004F049C ASCII "(*pos < 'A' || *pos > 'Z')"
00464EE1  |. 68 EC554D00    |PUSH linker_p.004D55EC                  ; |Arg4 = 004D55EC ASCII "%s
        (name) = %s"
00464EE6  |. 6A 00          |PUSH 0                                  ; |Arg3 = 00000000
00464EE8  |. 6A 2A          |PUSH 2A                                 ; |Arg2 = 0000002A
00464EEA  |. 68 5C044F00    |PUSH linker_p.004F045C                  ; |Arg1 = 004F045C ASCII "C:\trees\cod3-pc\cod3-modtools\cod3src\src\gfx_d3d\r_utils.cpp"
00464EEF  |. E8 AC970200    |CALL linker_p.0048E6A0                  ; \linker_p.0048E6A0
00464EF4  |. 83C4 18        |ADD ESP,18
00464EF7  |> 803E 5C        |CMP BYTE PTR DS:[ESI],5C
00464EFA  |. 75 1C          |JNZ SHORT linker_p.00464F18
00464EFC  |. 57             |PUSH EDI                                ; /Arg6
00464EFD  |. 68 3C044F00    |PUSH linker_p.004F043C                  ; |Arg5 = 004F043C ASCII "(*pos != '\\' || *pos == '/')"
00464F02  |. 68 EC554D00    |PUSH linker_p.004D55EC                  ; |Arg4 = 004D55EC ASCII "%s
        (name) = %s"
00464F07  |. 6A 00          |PUSH 0                                  ; |Arg3 = 00000000
00464F09  |. 6A 2B          |PUSH 2B                                 ; |Arg2 = 0000002B
00464F0B  |. 68 5C044F00    |PUSH linker_p.004F045C                  ; |Arg1 = 004F045C ASCII "C:\trees\cod3-pc\cod3-modtools\cod3src\src\gfx_d3d\r_utils.cpp"
00464F10  |. E8 8B970200    |CALL linker_p.0048E6A0                  ; \linker_p.0048E6A0
00464F15  |. 83C4 18        |ADD ESP,18
00464F18  |> 0FBE0E         |MOVSX ECX,BYTE PTR DS:[ESI]
00464F1B  |. 8BC3           |MOV EAX,EBX
00464F1D  |. C1E0 05        |SHL EAX,5
00464F20  |. 03D8           |ADD EBX,EAX
00464F22  |. 83C6 01        |ADD ESI,1
00464F25  |. 33D9           |XOR EBX,ECX
00464F27  |. 803E 00        |CMP BYTE PTR DS:[ESI],0
00464F2A  |.^75 A5          \JNZ SHORT linker_p.00464ED1
00464F2C  |> 5F             POP EDI
00464F2D  |. 5E             POP ESI
00464F2E  |. 8BC3           MOV EAX,EBX
00464F30  |. 5B             POP EBX
00464F31  |. 5D             POP EBP
00464F32  \. C3             RETN
*/

 

Sorry for the lack of comments in the code and sloppy coding at some parts :dave:

It's under zlib license though, so feel free to improve :angryarnold:

 

I shall now continue playing Super Mario 64 :happycry:

 

Oh, and yes, the tool is written in C :troll:

Edited by Bear
0

Share this post


Link to post
Share on other sites

"void const" is like "perkeleen perkele" :troll:

Const as suffix makes more sense than const as prefix in terms of consistency :dave: const as suffix is always valid unlike const as prefix nub

int const *p // pointer to an constant int

int* const p // constant pointer to an int

int const* const p // constant pointer to an constant int

const int* p // pointer to an constant int

const* int p // nope, this is invalid

const* const int p // wtf :angryarnold: GET TO THE CHOPPAAAAH!!

And as you said void const is like "perkeleen perkele" (correct finnish grammar) while const void would be "perkele perkeleeen" (nope) :troll: nub

0

Share this post


Link to post
Share on other sites

And as you said void const is like "perkeleen perkele" (correct finnish grammar) while const void would be "perkele perkeleeen" (nope) :troll: nub

:angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: :angryarnold: 

1

Share this post


Link to post
Share on other sites

 

 

Bear is in the army due to forced conscription.. kekekekeke :angryarnold: and also I thought this was finished 

0

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now