Pit to car radio app available - work in progress

Discussion in 'Community Workshop' started by mr_belowski, Jun 24, 2015.

  1. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    • Winner x 28
    • Like x 12
    • Love it! x 6
    • Wonderful x 2
    • Useful x 1
    Last edited: Dec 22, 2016
  2. ViperNo23

    ViperNo23 Member

    Joined:
    Feb 1, 2015
    Ratings:
    +17 / 0 / -0
    that would be some awesome app - too bad that I'm a total noob when it comes to coding (more or less) so I can't help you doing it - but count me in as a pre-alpha/beta/gamma tester :);)
     
  3. The_Grunt

    The_Grunt Well-Known Member

    Joined:
    Jun 19, 2015
    Ratings:
    +168 / 0 / -0
    Sounds awesome! That kind of software wouldn't be only useful, but definitely soups up the experience.

    NR2003 has spotter/crew chief system pretty much like that, where based on the info, sim plays some prerecorded audio files. That has given also the modders the ability to make spotter sound packs using recordings of real spotter/crew chief announcements. I don't mean that there would be anything wrong with OP's recordings, just that there are possibilities for those seeking ultimate realism and having access to the material.

    Thumbs up!
     
  4. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    OK, I'll package it up properly and make it available in the next couple of days when I've had more time to test the logic and make sure its playing the right messages at the right time.

    Don't expect miracles tho - its just a personal project that I thought others might like to try ;)
     
    • Like Like x 2
  5. Mikael Hermansson

    Mikael Hermansson Well-Known Member

    Joined:
    May 3, 2015
    Ratings:
    +48 / 0 / -0
    If you want to I can have a look at making a sample in Java as well, if it's something you're more comfortable with. Java seems to have some kind of shared memory construct with MappedByteBuffer, otherwise it can probably be achieved with some JNI/FFI hocus pocus.

    Have a look at Inno Setup instead. It's free, unlike InstallShield, and easier to deal with in my opinion.

    If you put the thing up on GitHub or Bitbucket I might be able to give you a helping hand or two. Strictly unofficially that is. :)
     
    • Like Like x 9
    • Love it! Love it! x 4
  6. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Ta, I'll have a look at Inno Setup.

    Spent a frustrating afternoon trying to access the object in Java using MappedByteBuffer (RandomAccessFile). It appears to want an actual file handle and doesn't work with just the object name. I can see the $Race$ object in a session explorer app (under Sessions/1/ or something), but couldn't find a way to get it in Java. I got far enough down the JNI rabbit hole to feel dirty and angry, hence the least-worst solution to port it over to C#. It was a good excuse to try a technology I've never used before, and making a JNI call to a native C dll just seemed like a really bonkers way to get the data.

    In terms of help, a Java fragment that can read the object without resorting to JNI would be brilliant, but don't waste a lot of time on it - I'm not convinced it can be done. The main other help I could do with is more data adding to the shared memory object (I'll make a list - it's not much stuff and nothing awkward) and some info about ranges for the car data - like what ranges to expect for tyre temperatures, oil pressures, etc so it's possible to trigger 'high tyre temp' or 'low oil pressure' messages and things like that.

    I'll add the code to GitHub when it reaches a point where I'm not embarrassed to show it. Like I said, it's a bit grotty at the moment.
     
    • Like Like x 1
  7. Dave R

    Dave R Well-Known Member

    Joined:
    Apr 19, 2015
    Ratings:
    +576 / 0 / -0
    Fantastic. I'd be interested as well.
     
    • Agree Agree x 2
  8. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Righty, I'm out this evening but should get some time to look at this again tomorrow and sanity check the current version. I've packaged it up in a .zip file which I'll bung on Google Drive with view permissions for anyone when I'm happy that it works reasonably well. Should just be a case of downloading it from the link, unzipping it and running the .exe

    Like I said, it's early days for the app (I specced it out in the sauna on holiday last week, wrote a Java version on Monday, ported it to C# yesterday, re-recorded the sounds this morning, and spent a couple of hours debugging this afternoon) so expect flakiness :)
     
    • Like Like x 2
  9. heppsan

    heppsan Well-Known Member

    Joined:
    Jan 29, 2015
    Ratings:
    +1,268 / 0 / -0
    This is something I really miss in this game!
    And I don't like vertual huds, so would love to be able to try this out!! :)
     
  10. Jay Ekkel

    Jay Ekkel Well-Known Member

    Joined:
    Jan 13, 2015
    Ratings:
    +412 / 0 / -0
    Great initiative, looking forward to try it!
     
    • Like Like x 1
  11. Mikael Hermansson

    Mikael Hermansson Well-Known Member

    Joined:
    May 3, 2015
    Ratings:
    +48 / 0 / -0
    JNA seems to have bindings for the same Win32 functions we use in the C sample. I assume they use JNI calls to kernel32.dll underneath though. Either way, I can't find any way to control object memory layout in Java, which might be deal breaker for Java, unless you write that JNI DLL you mentioned.

    Please post it in the sticky, so people have a chance to see what's already been suggested. :)
     
    • Like Like x 1
  12. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Will do. When I get a few minutes I'll rummage through that thread and list all the requests just so I don't add a load of duplicates.

    I did have a look at JNA but not in much detail. Will see if it offers anything useful
     
  13. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Cool, JNI looks like it will provide what I want. Will tidy up the C# version then move it all back into Java, as all this new-fangled C# is a bit too modern for an old dog like me :)
     
    • Like Like x 1
  14. Mikael Hermansson

    Mikael Hermansson Well-Known Member

    Joined:
    May 3, 2015
    Ratings:
    +48 / 0 / -0
    Again, you will need some way to control the memory layout of your shared memory object, if that's the route you're planning to go down. Basically something that equates to what
    Code:
    #pragma pack(push, 1)
    struct { ... };
    #pragma pack(pop)
    ... is to C/C++, and what
    Code:
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct { ... }
    ... is to C#.

    Otherwise the Java compiler might put in some "invisible" padding between the members for alignment reasons and offset the memory location of any subsequent member. It might be that it gets the right padding with whatever runtime you're using, but if anyone were to run it on an x64 JRE it would almost certainly break.

    I feel bad that this is even an issue really, but such is life when working with raw memory access.
     
  15. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    You sure? Won't the jna call just get me a jna POINTER reference which I can call stuff like getFloat(int offset), so I can control exactly where I am as I unpack it?
     
  16. Mikael Hermansson

    Mikael Hermansson Well-Known Member

    Joined:
    May 3, 2015
    Ratings:
    +48 / 0 / -0
    If that's possible, then yeah, that'd be the way to go. I just figured you'd recreate the struct in Java and somehow send the address/pointer of it to JNA.

    EDIT: I don't have that much experience with Java, so I'm probably out of my depth here, but you might be able to recreate the memory layout in a Java class, and then use custom annotations to assign specific offsets to each member. You could then, to populate an instance of this class, use reflection to get the type and offset of each member. Might be a bit overkill, but would at least save you the hassle of keeping track of which of the getFloat/getByte/getDouble to use. :)
     
    Last edited: Jun 24, 2015
  17. Paul Darke

    Paul Darke Moderator Beta tester

    Joined:
    Jan 29, 2015
    Ratings:
    +249 / 0 / -0
    This sounds great. I would like to say thank you for your efforts.
     
    • Agree Agree x 2
  18. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Don't say it sounds great till you heard it. I sound like Wurzle Gummage trying to be Rob Smedly ;)

    My plan is to tidy up the C# version tomorrow and (hopefully) make it available then (if I can get the JNA stuff to work) concentrate future efforts on the Java version
     
    • Funny Funny x 4
    • Like Like x 1
  19. ozcanuck55

    ozcanuck55 Well-Known Member

    Joined:
    Feb 13, 2015
    Ratings:
    +145 / 0 / -0
    "it can probably be achieved with some JNI/FFI hocus pocus."
    ...and some Swedish Death Metal....
     
    • Like Like x 1
  20. mr_belowski

    mr_belowski Well-Known Member Beta tester

    Joined:
    Apr 23, 2015
    Ratings:
    +1,307 / 0 / -0
    Having spent some more time farting about with it today, I've uploaded a version to Google Drive here:

    [edit - fixed the link]
    https://drive.google.com/file/d/0B4KQS820QNFbbUtrSWZKOEQ0NVk/view?usp=sharing

    This is still very much a work in progress.

    To run it, you'll need to install .net 4 or above. Then just unzip the folder I've put on Google Drive somewhere and run the enclosed CrewChief.exe (run it on the same box as R3E of course).

    I recommend having the master volume in R3E set to around 50%. If you get no sounds from my app, check the mixer for your sound card (the speaker icon on the task bar, then 'mixer') - it might start out at zero volume.


    There are lots of caveats here. Here are some...

    First, I've not finished it. Not nearly. I'm going to work on it a little more tonight. As far as I know this version works but I'll replace it if I find it doesn't. I'm putting it up not as a finished piece of software, but as a preview I guess.

    Second, the sound files aren't great. I'm not an actor and putting the "I'm excited and give a toss" tone into my voice hasn't worked - the clips were plain embarrassing when I tried so they're a little dead-pan. So I'm sorry for the poor acting.

    Third, the shared memory object I'm using wasn't designed with this stuff in mind. There are lots of things missing and some stuff I've had to hack to make it work. The pit window messages only work for the DTM 2014 experience. The fuel messages only work for online races where fuel usage is enabled. Detecting whether it's a DTM 2014 race is impossible. I don't have DTM 2013 so for me, I can just check if the race is a fixed number of laps rather than a time (AFAIK only the DTM experiences support this). This means that any other race type which has a fixed number of laps (DTM 2013?) will trigger pit window / option - prime tyre change messages. Races with time rather than number of laps won't trigger pit window messages or 'two laps to go' type messages because the remaining race time race length, mandatory pit stop flag, and a bunch of other stuff aren't in the shared memory object. Once these are added, this app will become a bit more clever.

    I think the penalties stuff is working properly, but I've not tried it when there are multiple outstanding penalties.


    To change the sound files, just replace the .wav files in the sounds subfolder. Each subfolder can have 1 or more wav files and the app picks one at random to play. The wav file in the root of the sound folder is the radio 'beep' - again, there can be more than one of these and the app will select one at random.


    I'll document it further as I develop it, like I said, it's a proof of concept but hopefully is still useful in its current state :)


    Oh, and when you run it it'll spawn a command window with some debug messages. It should, after loading all the sound files, beep and say "smoke test" in my bunged-up-farmer accent. If it doesn't please tell me


    [edit 2]

    Gah, I think I might have left some debug code in the fuel usage tracker stuff. Rather than "you've used half your fuel" triggering when you've used half your fuel, triggers when you've used about 10% of it. I think. So if you get much too early fuel warnings don't panic - I'll fix that later today
     
    • Like Like x 9
    Last edited: Jun 25, 2015