Tuesday, December 24, 2013

English subtitles in English soundtrack for foreign dialogue using Handbrake

I have backed up most of my video collection to a central server in my house, and I usually use AnyDVD HD and CloneDVDMobile together to do my rips; however, CloneDVDMobile has very limited support for subtitles (which I only noticed after going through dozens of my DVDs and doesn't support BluRay at all.

To get around these two issues I use Handbrake.  Using Handbrake to rip from BluRay is another topic; however, using it to effectively pull subtitles that are supposed to be shown in the English only soundtrack can be a pain, so since I've just re-figured this out again for probably the 3rd time - I'm posting it here so I can find it myself later...

Under subtitles, choose to Add and usually select the first English audio track (you may have to try others), then check 'forced only' and 'burn in' and usually you'll get the results you would get from simply playing the movie in your bluray/dvd player.

Tuesday, December 10, 2013

Unity3D 2D UI Click-Through Issues

I have message box and dialog box classes for use in Unity3D that need to act 'modally' (but not truly modal) at times, and one of the problems I've had was preventing the mouse-clicks/touches from hitting controls under the controls in the message/dialog boxes.

You'd think that the Unity3D system would already take care of this, but apparently there is some behind the scenes issue that is non-trivial to resolve (otherwise the Unity3D devs would have knocked this out a looooong time ago.)

Anyhow, I found a simple solution today that works for me (until I find it fails on iOS - fingers crossed that it doesn't!)

When my OnGUI call gets to my message/dialog box, the message/dialog box simple creates TWO full screen transparent GUI.Window objects.  The first one calls an empty method, the second one calls the method that draws the controls of the message/dialog box.

I'd tried this previously, but only created one GUI.Window - hoping (vainly) that having the window under the message/dialog box would prevent clicks from making it through.  Oddly enough, it sort of worked, it prevented clicks that were on the message/dialog box controls from going through, but you could still click anywhere on the rest of the screen and cause havoc...

Anywho - I'll have to test have badly this affects performance (it shouldn't really as the both windows entire areas have an alpha of 0.0.)

Monday, December 9, 2013

Sharing C# Source Code With A Unity3D Project

I ran into some issues recently trying to share some common networking and data classes between a client application, a middleware ASP.NET server, and a configuration/server management tool.  All three of them needed to be able to serialize/de-serialize the same XML data; however, Unity3D does not currently support (natively) the ability to reference source code files outside of its project directory structure.

The easy solution to this on Windows is to create a symbolic link, and it works nicely.

I'll be revisiting this problem when I go to build on OSX (I presume that I'll be messing with my samba conf) and there are ways you can trick your source control system into accomplishing this (but it's really hacky) - so this isn't a panacea for the issue.

Hopefully the Unity team will introduce its own linking system that handles this (if Mono doesn't already have it...)

Worst case I'll be writing some file synchronization scripts that trigger the Unity editor to copy from the common direct (which is problematic if I make changes in Unity - but hopefully I can avoid that.)

Sigh...

Wednesday, December 4, 2013

Recently converted an ASP.NET Web Site project to a Web Application project...

...because I really need to use shared/common sources for 3 inter-related projects and you need a Web Application to do it (because Web Site projects do not let you link to source files, just copy.)

Anywho - I converted, built, tested, deployed, crashed.  Turned on detailed errors, zilch.  Enabled .NET error page information.  Bingo, "Default.aspx.cs could not be found."  What?

I FTP in, look at the directory structure and see that the bin folder does contain the DLL it should.  Spend a half hour wondering what exotic setting I'd forgotten to configure.  Cursed Microsoft for a little bit.

Suddenly I remembered something rather important.  When you're using a pre-compiled version of your project (as a Web Application generally is), you don't use the CodeFile attribute in your Default.aspx html code.  You use CodeBehind.

CodeFile instructs the webserver serving the page to use the JIT compiler.  CodeBehind instructs the compiler on your dev box where to find the class it needs to shove into the DLL.

So, yet again, it was all my #F$()ing fault.  Sigh...

Monday, November 4, 2013

Flickering running Rise of Nations on Windows 7 - Intel HD 4000 Graphics

I played with the old (circa 2003 iirc) game Rise of Nations this weekend while waiting for someone to reply to e-mail inquiries and I ran into a strange flickering problem that nobody seems to have reported on the interwebs, so I thought I would post the solution I found.

Editing the ron2.ini file and setting ForceAGPVBs=1 resolved the issue for me.  Previously the graphics had flickered heavily - especially relating to text boxes.  None of the older solutions (expading resource windows or disabling vsync) worked for me, but this did.  BTW, this was on a 2012 Mac Mini running Windows 7.

Thursday, April 18, 2013

Passing a structure containing a float array from C# to a C++ DLL

For a struct defined in C++ as:

struct MyStruct
{
    float m_aFloatArray1[4];
    float m_aFloatArray2[4];
    float m_aFloatArray3[4];
};

And you want to simply pass the struct from C# straight into C++, you would define the struct on the C# side as:

[StructLayout( LayoutKind.Sequential )]
public struct MyStruct
{
    [MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 4 )]
    public float[] m_aFloatArray1;
    [MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 4 )]
    public float[] m_aFloatArray2;
    [MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 4 )]
    public float[] m_aFloatArray3;
}

Note that this approach only works for fixed size arrays (otherwise things get hairy.)

Tuesday, March 19, 2013

Consuming Google Translate API v2 with C#

I spent far too much time today figuring this out (never having dealt with JSON or Google APIs before.)

It is very simple to use Google's translate services (provided you have an API key), but in the interest of sharing (and avoiding some little oopsies I hit today - such as unwrapping certain characters) here's a crude and simplified version of what I implemented.

BTW - Please note that I am using the JavaScriptSerializer below, which means that although I use a data contract (for other reasons) this particular deserializer maps by property name; ergo, the class member names MUST match the JSON property names.


[DataContract]
public class GoogleTranslation
{
    [DataMember( Name = "data" )]
    public Data Data { get; set; }
}

[DataContract]
public class Data
{
    [DataMember ( Name = "translations" )]
    public List Translations {get; set;}
}

[DataContract]
public class Translation
{
    [DataMember( Name = "translatedText" )]
    public string TranslatedText { get; set; }
}


The 3 classes above are going to be used to deserialize the returned JSON data in the method below.  BTW, you need to add three references to your project (at least, if you use the code I supply below you do - there are surely many alternatives.)

     System.Web
     System.Web.Extensions
     System.Runtime.Serialization

Sorry I didn't spend the time formatting this code (I just dumped it in) - I may do so later as it is late and I have miles to go before I do anything resembling sleep.



public string GoogleTranslate( string in_strFromLanguageCode, string in_strToLanguageCode, string in_strString )
{
    string l_strKey = "YOUR_API_KEY_GOES_HERE";
    string l_strURL = "https://www.googleapis.com/language/translate/v2?key=" + l_strKey + "&q=" + in_strString + "&source=" + in_strFromLanguageCode.ToLower() + "&target=" + in_strToLanguageCode.ToLower();
    string l_strTranslation = "";

    try
    {
        WebClient l_oWebClient = new WebClient();
        string l_strResult = "";

        //Notify the webclient we're expecting UTF-8
        l_oWebClient.Encoding = System.Text.Encoding.UTF8;
        l_strResult = l_oWebClient.DownloadString( l_strURL );

        //Unwrap special characters
        l_strResult = HttpUtility.HtmlDecode( l_strResult );

        //Deserialize JSON
        JavaScriptSerializer l_oSerializer = new JavaScriptSerializer();
        GoogleTranslation l_oTranslation = l_oSerializer.Deserialize( l_strResult );

        l_strTranslation = l_oTranslation.Data.Translations[ 0 ].TranslatedText;
    }
    catch( WebException )
    {
        //Evaluate status code
    }

    return l_strTranslation;
}


Now, there's lots of things missing you'd use in real production code (such as any basic error handling) - but that should be enough to get you rolling.

Enjoy!

Wednesday, February 13, 2013

Hmmm... New motherboard, Windows 7, low audio volume...

...after thinking too much about solving this issue with my fancy 'everything AND the kitchen sink" motherboard - it turns out that listening with headphones when your HD audio thinks you're plugged into a 7.1 surround sound system (no idea why it defaulted to this) results in really low 'max volume.'

Settings it to 'stereo' nearly blew my head off (since I was playing some Buckethead on full blast...)