Forum Announcement, Click Here to Read More From EA_Cade.

Images in UI.package

simalary44simalary44 Posts: 17 Member
edited March 5 in Nominated Threads
I was looking through the ui.package file and saw that the images were all in a blue/pink hue, and wanted to edit them, but don't know how they work.

@SimGuruModSquad any ideas?
Post edited by EA_Cade on

Comments

  • SimGuruModSquadSimGuruModSquad Posts: 597 Member
    Hey @simalary44 , oh yeah forgot about that. The textures in UI.package use a custom encoding which is why they are not showing up correctly.

    They use YCoCg color space instead of RBG and each texture has two associated resources in the package, both in ATI2N format. Texture # 1 (group ID 0x00064dca) is full sized and contains luminance and alpha, Texture # 2 (group ID 0x00064dc9) is half sized and contains the two chroma channels.

    There will be no off the shelf texture editors that can edit these exactly as is, but these are standard formats so it should be possible to build a converter. I can provide more information as needed.

    -SGMS
  • IngeJonesIngeJones Posts: 3,247 Member
    Ugh... thank goodness for TS4 we have simguru modding advisors. I don't think there'd be mods at all this time around if we'd had to work everything out ourselves like we had to in the previous three games
  • simalary44simalary44 Posts: 17 Member
    @SimGuruModSquad that sounds interesting. Would it be possible to give a few pointers? I just never heard about that, and when I first opened them, I thought I broke something :D

    I'd appreciate it a lot, thank you.
  • DarkWalkerDarkWalker Posts: 64 Member
    I found a paper by NVidia about working with the YCoCg colorspace: http://www.nvidia.com/object/real-time-ycocg-dxt-compression.html
    It's focused on DXT5, but provides some useful pointers in handling that kind of encoding.

    (Incidentally, what the Sims is doing for those files is fairly similar to how analog color TV works: a higher definition signal with just the luminance and a lower definition one with the color information. Turns out we are much better at detecting flaws in the luminance than in the color, so if there is a need to degrade the quality due to technical limitations it's better to degrade the color information while keeping the luminance at a higher quality.)
  • cmarinetticmarinetti Posts: 147 Member
    @SimGuruModSquad - I'm working on converting the pairs of ATI2-encoded images into one bitmap and from a bitmap back to two DDS-ATI2 images. So far I seem to be getting luminance and alpha correctly, but the RGB colors are off - too much green and not enough blue is what it looks like to me.

    Would it be possible to get the algorithms you're using for RGB -> YCoCg and YCoCg -> RGB?

    Thanks!
    cmarNYC on MTS.
  • SimGuruModSquadSimGuruModSquad Posts: 597 Member
    Awesome @cmarinetti !

    Here you go:
    /// Sims 4
    /// Copyright 2014-2016 Electronic Arts Inc. All rights reserved.
    
    void ConvertBGRAToYCoCgARef(
        void * __restrict pDst0, ptrdiff_t dstPitch,
        uint32_t w, uint32_t h)
    {
        if (!w || !h)
            return;
    
        // flip to forward pitch if necessary
        if (dstPitch < 0)
        {
            pDst0 = (char *)pDst0 + dstPitch * (h - 1);
            dstPitch = -dstPitch;
        }
    
        // check if we can do one linear span
        if (dstPitch == 4*w)
        {
            dstPitch = 0;
            w *= h;
            h = 1;
        }
    
        // The matrix conversion we need to do is as follows:
        //
        //                      |0.25  0.5   -0.25 |
        // [Y Co Cg] = [R G B 1]|0.5   0      0.5  |
        //                      |0.25 -0.5   -0.25 |
        //                      |0     0.502  0.502|
        //
        // The funky 0.502 bias is actually 128/255, so that we can exactly
        // represent the grayscale axis. This encodes R,G,B in [0, 1] to
        // Y, Co, Cg in [0, 1].
    
        {   // We need this apparently useless block to isolate the restricted child pointers.
            uint8_t *__restrict pDst = (uint8_t *)pDst0;
            const uint32_t w4 = w * 4;
    
            do
            {
                for(uint32_t x = 0; x < w4; x += 4)
                {
                    const uint32_t b = pDst[x];
                    const uint32_t g = pDst[x+1];
                    const uint32_t r = pDst[x+2];
                    const uint8_t a  = pDst[x+3];
    
                    // The formulation here is slightly funky, but written this way to match
                    // the rounding of an optimized, vectorized routine. The unusual primitives
                    // used here are:
                    //
                    //    invert(x) = ~x = 1 - x
                    //    average(x, y) = round_up((x + y)/2)
                    //
                    const uint8_t co = (uint8_t)((r + (b ^ 0xff) + 1) >> 1);
                    const uint8_t cg = (uint8_t)(((((r + b + 1) >> 1) ^ 0xff) + g + 1) >> 1);
                    const uint8_t y = (uint8_t)((((r + b) >> 1) + g + 1) >> 1);
    
                    pDst[x+0] = y;
                    pDst[x+1] = co;
                    pDst[x+2] = cg;
                    pDst[x+3] = a;
                }
            
                pDst += dstPitch;
            } while(--h);
        }
    }
    
    void ConvertYCoCgToBGRARef(
        void * __restrict pDst0, ptrdiff_t dstPitch,
        const void * __restrict pSrcY0, ptrdiff_t srcYPitch,
        const void * __restrict pSrcC0, ptrdiff_t srcCPitch,
        uint32_t w, uint32_t h)
    {
        if (!w || !h)
            return;
    
        // The matrix conversion we need to do is as follows:
        //
        //                                        | 1  1   1|
        // [R G B] = ([Y Co Cg] - [0 0.502 0.502])| 1  0  -1|
        //                                        |-1  1  -1|
        //
        // This is the inverse of the RGB -> YCoCg conversion. We do not require
        // this to be bit exact as the shader won't be and we don't have enough
        // bits in Co/Cg for that anyway. Black and white do round-trip, however.
        //
        // Note that we do need to clamp, however, as the asymmetrical signed
        // encoding means that we can get -0.502 out of the chroma.
    
        {   // We need this apparently useless block to isolate the restricted child pointers.
            const uint8_t *__restrict pSrcY = (const uint8_t *)pSrcY0;
            const uint8_t *__restrict pSrcC = (const uint8_t *)pSrcC0;
                  uint8_t *__restrict pDst  = (      uint8_t *)pDst0;
            const uint32_t w2 = w * 2;
    
            do
            {
                for(uint32_t x = 0; x < w2; x += 2)
                {
                    const int32_t y  = pSrcY[x];
                    const uint8_t a  = pSrcY[x+1];
                    const int32_t cg = pSrcC[x];
                    const int32_t co = pSrcC[x+1];
    
                    // apply conversion matrix and remove chroma encoding bias
                    int32_t r = y + co - cg;
                    int32_t g = y + cg - 128;
                    int32_t b = y - co - cg + 256;
    
                    // clamp
                    if ((uint32_t)r >= 256) r = ~r >> 31;
                    if ((uint32_t)g >= 256) g = ~g >> 31;
                    if ((uint32_t)b >= 256) b = ~b >> 31;
    
                    pDst[x*2+0] = b;
                    pDst[x*2+1] = g;
                    pDst[x*2+2] = r;
                    pDst[x*2+3] = a;
                }
            
                pDst += dstPitch;
                pDst += dstPitch;
                pSrcY += srcYPitch;
                pSrcC += srcCPitch;
            } while(--h);
        }
    }
    
  • cmarinetticmarinetti Posts: 147 Member
    edited August 2016
    Thanks so much! Especially on a Sunday! I had pretty much worked out the YCoCg to RGB but your code gave me a final correction for some color distortion, and of course it's great to have confirmation I'm not doing something terribly wrong. Now to tackle the conversion back - RGB to YCoCg should be easy with the example code, but have to see if my ATI2 compression works.

    Here's an image I converted from the UI:
    OutdoorPic.jpg

    And another - not sure what's with the magenta trees; are they supposed to be that color?
    converted27.bmp
    Post edited by cmarinetti on
    cmarNYC on MTS.
  • SimGuruModSquadSimGuruModSquad Posts: 597 Member
    Great, looking good. Yeah those trees are the correct colors, same as what you will see in game. That's the map for Magnolia Promenade from Get to Work.

    -SGMS
  • cmarinetticmarinetti Posts: 147 Member
    edited August 2016
    I guess I never noticed the tree color - shows how observant I am.

    Anyway, success! My Willow Creek is now terrorized by Monster Kitten.
    MonsterKitteninWillowCreek.jpg

    Thanks for your help, @SimGuruModSquad !

    Edit: The tool is available here: http://www.modthesims.info/download.php?t=581475
    Post edited by cmarinetti on
    cmarNYC on MTS.
  • Petarce123Petarce123 Posts: 493 Member
    cmarinetti wrote: »
    I guess I never noticed the tree color - shows how observant I am.

    Anyway, success! My Willow Creek is now terrorized by Monster Kitten.
    MonsterKitteninWillowCreek.jpg

    Thanks for your help, @SimGuruModSquad !

    Edit: The tool is available here: http://www.modthesims.info/download.php?t=581475

    When I try to convert it says that I am missing "squishinterface_Win32.dll".
    What do I do?
    I want Seasons and Island Paradise for The Sims 4!

  • Petarce123Petarce123 Posts: 493 Member
    edited August 2016
    Well,Now it's working.Here is my test! :)

    http://imgur.com/a/uDszQ
    I want Seasons and Island Paradise for The Sims 4!

  • cmarinetticmarinetti Posts: 147 Member
    edited August 2016
    Nice!

    That error would happen if you load the wrong kind of .dds image file. Do you think that's what happened?
    cmarNYC on MTS.
  • Petarce123Petarce123 Posts: 493 Member
    cmarinetti wrote: »
    Nice!

    That error would happen if you load the wrong kind of .dds image file. Do you think that's what happened?

    Thanks!
    Yea,I'm pretty sure that's what happened. ;)
    I want Seasons and Island Paradise for The Sims 4!

  • cmarinetticmarinetti Posts: 147 Member
    If I do an update I'll put in an error check for that.
    cmarNYC on MTS.
  • Petarce123Petarce123 Posts: 493 Member
    @cmarinetti is it possible for you to make a tool that can convert other UI pictures and not only the map pictures? :)
    I want Seasons and Island Paradise for The Sims 4!

  • Petarce123Petarce123 Posts: 493 Member
    Petarce123 wrote: »
    @cmarinetti is it possible for you to make a tool that can convert other UI pictures and not only the map pictures? :)

    Oh,I just saw that this works with everything!
    Thanks for the great tool! :)
    I want Seasons and Island Paradise for The Sims 4!

  • ofscifiofscifi Posts: 2 New Member
    noob here - where do i find the map ui files? i'm looking to make a spring and winter version of the mod but would be awesome if i could change the map images as well.
  • cmarinetticmarinetti Posts: 147 Member
    The maps are in C:\Program Files (x86)\Origin Games\The Sims 4\Data\Client\UI.package, if you installed in the default location. You'll have to go though the _IMG files using s4pe to find the images for the maps. There are two images for each map, with the same Instance number but different Group numbers. Extract both to files and use my tool linked above to convert to and from a .png image.
    cmarNYC on MTS.
  • ofscifiofscifi Posts: 2 New Member
    awesome thank you :3

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file
Return to top