Jump to content
IGNORED

RMT Hacking Ideas and Progress


Recommended Posts

1 billion years later, after being busy with life and barely had any time to study the stuff more seriously, I finally some actual progress... but not really.

Now I realise the export code is REALLY working against me.


So I can manipulate the code, sure, but not really the way I was hoping for.

haha yes I am very funny when I just fuck around the hex editor (through Ghidra this time heh)

unknown.png


It literally picks the header, and compute the file size from it.... even if I know for a fact my header IS correct, but the size is not fitting since it's ORGed at different places for the other parts being $3400, $3E00 and $3F00 etc
So basically, I'd rather assemble exports manually at this point, there's no way I can fix this shit from the x86 disassembly alone, and since the RMT source code is kept away from mortal beings, there's no way I can work around this for now, ?

 

I may be ambitious, but I'm not insane. I wasted too much time trying to reverse engineer the code only to find out I would have to literally re-write an entire part from scratch if I want to avoid the header-filesize-slap.xex-slap.rmt-binary-bit-banging-orgy.

Even more frustrating is I literally have the XEX/SAP export solution available, but integrating it to RMT would either require me months of learning x86 assembly (Fuck this shit, it's like asking a 5 stars cook to cook a fancy meal using ingredients picked up from a sceptic tank), or edit the RMT source code directly, but I have a feeling the first option may be the only one that is realistic for the time being.

 

So if you guys want to get functional exports, please use my stuff from github, because that's where I stop trying for the direct .exe hack, I cannot fix exports currently, and it's just not going to work from my very limited skills, and I really am out of ideas right now.

 

Now back to the .exe I had hacked some time ago which was expanded and posted earlier in this thread, as far as I could tell, for editing purposes it does work perfectly (confirmed by @EnderDude for the last few days, a big thanks for testing it really seriously while I had no time for it this week!).

Exports obviously are broken, but like I said, you can built export binaries from the code I dropped on Github, it will just work.

That's a bit more work but that's better than nothing at all.

If you really want to save yourself time, just create a template Mono and Stereo export, and simply replace the .rmt in the file, including the whole FFFF header part, it will then be a fully functional export regardless of the module used, the only limitation is that Mono and Stereo players are not yet "merged" to be fully universal, if that even make sense anymore.

 

So with this rather disappointing experience, I suppose there is no other option than making a brand new tracker, and that's definitely not a thing I can do myself, unfortunately. ? 

 

 

  • Like 2
Link to comment
Share on other sites

36 minutes ago, VinsCool said:

It literally picks the header, and compute the file size from it.... even if I know for a fact my header IS correct, but the size is not fitting since it's ORGed at different places for the other parts being $3400, $3E00 and $3F00 etc
So basically, I'd rather assemble exports manually at this point, there's no way I can fix this shit from the x86 disassembly alone, and since the RMT source code is kept away from mortal beings, there's no way I can work around this for now, ?

Can't you just avoid using different ORGs ? if you use a single ORG there should just be a single segment and its size should be correct (I haven't exactly followed the maze of hacks you've added so maybe that's just a dumb suggestion)

 

(Not sure if I should really try to push you in this direction since I've been trying to steer you away from it for a while ?)

 

40 minutes ago, VinsCool said:

So if you guys want to get functional exports, please use my stuff from github, because that's where I stop trying for the direct .exe hack, I cannot fix exports currently, and it's just not going to work from my very limited skills, and I really am out of ideas right now.

Perhaps you could make a patch for RMT2LZSS, but that could be scary (for me anyway ?). Also SKCTL on the fly is not supported yet by LZSS.

 

43 minutes ago, VinsCool said:

So with this rather disappointing experience, I suppose there is no other option than making a brand new tracker, and that's definitely not a thing I can do myself, unfortunately. ? 

With your newly acquired coding skills, you could be part of the solution!

  • Like 1
Link to comment
Share on other sites

1 hour ago, rensoup said:

Can't you just avoid using different ORGs ? if you use a single ORG there should just be a single segment and its size should be correct (I haven't exactly followed the maze of hacks you've added so maybe that's just a dumb suggestion)

 

(Not sure if I should really try to push you in this direction since I've been trying to steer you away from it for a while ?)

Of course, but that breaks all the memory map I wanted to use.

 

The code for exports is weird, and in my opinion, goes wayyyy too hard on the concatenation process.

 

What could have been a 4 parts binary stack gets trapped in a maze of code that works around several things just to achieve something that became counter-intuitive and doesn't even offer any advantage over the method I wanted to use, in my opinion.

 

In order, this is what I could reconstruct of the process, more or less:

Check the export format, check the module format (RMT4 or RMT8), load the Export Player binary with the matching region, use the ORG data from the header to determine what memory region is used, as well as its size (regardless of the "size" I could assign to it), slap the Export Player code right after it, itself ORGed to $3E00 (unconditional), immediately after, compute the text data if XEX (including the Rasterbar colour and Songspeed data on the last 2 bytes) ORGed at $3F00, and finally put the stripped RMT module after it, minus its FFFF part of the header, keeping only the $4000 $XXXX RMT4/8 parts of it there, and finally set the run start memory address there ($3E00 in this case).

 

All of the above starting from the assumption all the memory will be in sequential order.

Since it's not doing this at all in my own patch, that just doesn't work there.

 

The 6502 ASM code can be fragmented and works perfectly fine as it is, but if I want to work around the export puzzle I will have to be a more creative, and I don't know what else I could do for now.

 

The actual player calls do work perfectly fine in the tracker binary itself using the exact same code + the extra code that was also included in RMT.exe that I was able to recreate from scratch too, so clearly there is something else that cause a havok only from a few bytes when I attempts to produce exported data.

 

As you can see, this makes things annoying as hell to piece together from a hacking perspective.

 

 

My export approach is a bit more on the loose side, but it certainly is considerably easier to put together with much less fiddling around, and produces almost exactly the same results, and is also much easier to edit later if there is even a point to do it:

 

Get the Player Export binary first, already assembled before, keep its ORG and FFFF header but let its full be loaded, load the Player upper part load on top of it (ORG $3E00), set the Run Start address here, then load the text and data next, (ORG $3F00), then simply paste your .rmt at the end of the file and not worry about it.

Rasterbar colour could use the same part if wanted, but the songspeed will be computed from the player itself at runtime, the only difference is how the region would be handled, being only 2 bytes to change in either case.

SAP is almost the same deal except it is only SAP header (INIT $3E00, PLAYER $3403), then Player Binary (exactly the same one as before, so no extra code needed!) then the extra SAP INIT stuff as well as subtunes if wanted (ORG $3E00), and just like before, slap any .rmt module at the end of the file.

 

 

Anyway, I know I sounded a bit upset earlier, but to be fair, I did find a few clues from that failure, so maybe it's not all lost yet.

I can't deny it, I'm getting a little impatient over this, It may be possible for me able to recreate this part in C, but working around it directly in x86 is straight up going to drive me mad.

 

2 hours ago, rensoup said:

Perhaps you could make a patch for RMT2LZSS, but that could be scary (for me anyway ?). Also SKCTL on the fly is not supported yet by LZSS.

Certainly it could be done, I was able to port almost all of my patch to the Javascript Web RMT so I don't see why the same couldn't be done in RMT2LZSS.

No idea for SKCTL either, not too familiar with the way the compression and byte stream works.

 

2 hours ago, rensoup said:

With your newly acquired coding skills, you could be part of the solution!

Hopefully I could turn useful, I am not the kind of person to cry a river for 36 years, I'm more stubborn to try doing things when told they won't work and so I keep pushing out of spite just to prove it could be done, I guess, lol

  • Like 2
Link to comment
Share on other sites

6 hours ago, VinsCool said:

All of the above starting from the assumption all the memory will be in sequential order.

Since it's not doing this at all in my own patch, that just doesn't work there.

? Clearly I've missed a few episodes!

 

6 hours ago, VinsCool said:

Certainly it could be done, I was able to port almost all of my patch to the Javascript Web RMT so I don't see why the same couldn't be done in RMT2LZSS.

No idea for SKCTL either, not too familiar with the way the compression and byte stream works.

Cool! For SKCTL, it isn't very difficult...

 

6 hours ago, VinsCool said:

Hopefully I could turn useful, I am not the kind of person to cry a river for 36 years, I'm more stubborn to try doing things when told they won't work and so I keep pushing out of spite just to prove it could be done, I guess, lol

?

Link to comment
Share on other sites

Ok well that's enough for the exports mystery-- they simply won't work.

 

I've tried out some other things, but now I have to admit this is a failure.

There is simply way too many things to work around, and it's seriously disappointing how much work went into the export format to make sure to retain the most hardcoded setup as possible.

 

Let me explain what have been my observations since the last week, up to right now:

 

1- ORG data must be in sequential order only.

2- Data must be below $4000 only, otherwise it will be overflown and be filled with garbage (which was my experience at first)

3- Data with blank spaces between sections will be filled up with zeroes, so having fragmented executables will be inflated with empty spaces that serve no purpose at all!

4- The very first ORG at the FFFF header at the start of exports WILL be overwritten as a "whole" file, so you cannot ORG from 1 spot to another, you are literally required to have it from start to end, and RMT is going to overwrite it anyway.

5- XEX and SAP exports data is hardcoded to their location regardless of what is in memory, so moving them around is both tricky and going to break everything

6- Run Start address is hardcoded to be written to the file after everything was done literally because the points above are causing problems with anything attempting to ORG anywhere

7- You cannot "hardcode" memory addresses yourself, I have no idea how but any ORG in a binary is going to break things, even if you hid everything into extra bytes! They WILL be detected, and cause all the problems mentioned above!

 

I am not making this up by the way! This is all I was able to more or less reconstruct so far!

 

Even if you have all your memory maps nicely organised and stacked together, the RMT exporter will give you the middle finger and do whatever it wants to do.

And you wanna know the best part? The Tracker binary has none of these problems, and obviously, manually assembling export binaries from my own 6502 re-creation code is still much easier to do despite the limitations of 6502 itself!

 

That's a game over screen from now on, I'm afraid guys :( There's nothing I can do about this, and I think I wasted too much time already.

The idea I visualised looked quite easy to do, but as I wrote there, it's buried under several layers of fucks... I and have no comprehension for why this was even was done this way!

It's so frustrating to be so close to the solution and realise you''ve walked right into the death trap!

 

So anyway, this time I will say it without beating around the bush: There is absolutely nothing I can change with the exporter code itself within the .exe file, especially without the original code. 

There are way too many things that would required to be changed, and this is not going to be done anytime soon from the reverse-engineering tools alone, especially because I don't have the patience of a monk.

 

Sorry for deceiving you all, everyone. I promise I did try my best this time, but that was not enough. ?

The best I can offer, is the larger custom Tracker binary, memory addresses patching, and the functional expanded .exe, that's still better than nothing at all, I guess.

  • Like 1
Link to comment
Share on other sites

19 hours ago, _The Doctor__ said:

perhaps taking everything you've done on all parts of entire group of works you have done to the https://atariage.com/forums/forum/51-atari-5200-8-bit-programming/

section of AA will yield some serious help on this...

You're right... If a moderator sees this message please move the thread to this section :)

 

13 hours ago, miker said:

I think that without given access to the source, all the changes seem pointless, unfortunately.

Not all changes are pointless!

But it's a lot more difficult to do.

 

 

 

 

3 hours ago, Mathy said:

Hello @VinsCool

 

I've sent you a message that I know you want to read, I'm just not sure it won't be blocked by your spamfilter.  If I didn't get that message by now, please send me a mail via address you can find on my site (see my avatar).

 

Sincerely

 

Mathy

 

I have replied and sent you an email now, thank you.

Link to comment
Share on other sites

Ok so I finally have figured out the export format code.

It really was making me pulling my hair, but finally I have some progress for that part in particular.

 

Shown below: functional XEX export generated from RMT directly, making use of my patched rmtplayr binaries.

image.thumb.png.b9511bfe7914ded9c206717d87fd6457.png

 

I can tell you all, it really was a frustrating puzzle, but I am really happy to finally have reached the results I wanted.

 

More about this soon.

  • Like 4
Link to comment
Share on other sites

So while I have the export format mostly understood I left it on the side to try some more things, and well 
image.png.ecc4b7fc6fed3cf525aa005f1a542cf7.png

The UI isn't as complex as I first imagined once I started to poke at it a bit more seriously,

I hope I'll be able to do something without breaking too much of it XD

 

I'm sorry RASTER for the destruction, I promise this is for science LOL

What I am trying to do for now is to move some things in a larger canvas, I'm also able to edit the window size now, it's a bit messy but it's mostly functional for that part so far, there's still many things to edit, but it's coming together :D 

Another thing I wanted to try doing is to display few Register infos in a block just below the soon to be moved SONG block, Famitracker style, if you see what I mean.

I also wanted to try editing more of the interface to be able to pick instrument and volume directly without the window popups, but that's probably going to take me some more time since it's quite difficult to go from blindfolded guesses, hahaha

 

[EDIT] Oh yeah, I forgot to mention, I managed to get the native LoadBinaryFile function to work again, so I have finally solved the troubles with memory and binary loader.

Simply drop the necessary files in a new "RMT Binaries' folder, binaries being 'tracker.obx', Mono and Stereo Player.obx, etc and RMT will load all the necessary files when requested.

I've also added another dumb hack in which loading and saving songs with Instrument Speed up to 8 is possible.

Exports will still refuse them for now, but loading and saving .rmt will have no problem. There will still be warning messages at loading (and I added saving too) when it's above 4.

8 seems quite overkill, but I know of a certain RMT2LZSS converter that does support this unconventional speed... ?

Edited by VinsCool
More infos about progress with my patch
  • Like 1
Link to comment
Share on other sites

Here's a test, I apologise for the broken UI, I'll do my best to repair it later, as well as finish the export format compatibility changes :)

 

So far a bunch of things work, mainly the native 'tracker.obx' loader this time without the necessity of using ivop's hijacked plugin.

That means the Altirra Plugins are 100% compatible with this, and the size restriction of the binaries loaded in memory is no longer a problem, thankfully :D 

The exports are not 100% working yet but the preliminary .xex exports do work, even if unfinished due to the changes I have to apply to the 6502 patch from the code I reverse engineered some time ago when I re-created the export format with some of my own changes to them.

The UI is a bit broken due to the changes I did, but so far resizing window works, and the program is still fully functional in this state, as demonstrated below.

 

 

 

  • Like 3
Link to comment
Share on other sites

1 million of years later I finally made some progress.

 

 

That was a lot of work, but I finally got my custom SAP and XEX exports fully working!
I'm also learning how to code out of necessity, so that's also good practice ? 

That was difficult to work around the original design to fit my own between.

So far so good!

 

- Experimental custom XEX and SAP export format implemented, still work in progress but so far, it works pretty well now.

- SAP now supports NTSC speed, and adjusts itself cross region.

- SAP format also has some special Altirra hijack code in place, making it behave like a typical .xex export, otherwise, NTSC and FASTPLAY tags will take care of the speed in most SAP players.

- XEX format has been a nightmare to rework, but I was able to implement my own design, which made a few things done differently, however it should work almost like the original code by Raster.

- Multispeed and Cross-Region was altered in a way that is easier to maintain, and is set during the executable initialisation. Cross region changes only involve 2 byte, otherwise the exact same code is used in all formats.

- Moved the display list in the $3F00 page, and generated it directly from RMT instead, stored after the 5 lines of user input text.

- The colour shuffling is optional, I want to make this an optional feature later.

- Notes tables and other rmtplayr data can be moved very easily, ORG addresses are very easy to change when necessary.
- XEX graphic routines are slightly different, but overall seem pretty stable too. This is mostly noticeable in cross-region situation, NTSC renders PAL with excellent timing stability now :) 

 

I hope I can add more things to RMT later, if I am able to.

 

Here's all the conversions I did in the video if anyone is interested.

They were not altered externally, it was all generated from RMT directly this time, and they're not broken because of my patch either :D 

 

 

SAP and XEX export test 1.zip

  • Like 7
Link to comment
Share on other sites

  • 2 weeks later...
On 11/1/2021 at 8:38 AM, VinsCool said:

Here's a test, I apologise for the broken UI, I'll do my best to repair it later, as well as finish the export format compatibility changes :)

 

So far a bunch of things work, mainly the native 'tracker.obx' loader this time without the necessity of using ivop's hijacked plugin.

That means the Altirra Plugins are 100% compatible with this, and the size restriction of the binaries loaded in memory is no longer a problem, thankfully :D 

The exports are not 100% working yet but the preliminary .xex exports do work, even if unfinished due to the changes I have to apply to the 6502 patch from the code I reverse engineered some time ago when I re-created the export format with some of my own changes to them.

The UI is a bit broken due to the changes I did, but so far resizing window works, and the program is still fully functional in this state, as demonstrated below.

 

 

 

Most people feel annoyed, if you show them the problems. 

But you definitely learn from critical statements. 

Big thumbs up. 

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, emkay said:

Most people feel annoyed, if you show them the problems. 

But you definitely learn from critical statements. 

Big thumbs up. 

Thanks.

 

The thing is, when I show a problem like this, I am also actively trying to find a solution to it.

I'm happy to say I have in fact, come a lot more advanced into this project since my last post in thist thread too, and earlier today I also have made a pretty hilarious discovery.

 

Current state of progress since my last reply in this thread:


 

Spoiler

 

DONE - Fix the UI bugs I have introduced with my experiments (in emkay's quoted reply, it's all fixed now). There is still a lot of room for improvements

DONE - Adjust the UI to either 4 or 8 tracks layout, making things look cleaner in general

DONE - Adjust the UI to display 32 Tracks rows, and 8 Song rows. Design still in progress so it's likely to change again to be more interactive (ie window size to adjust the layout)

DONE - Adjust the Instrument popup window width so full names can be visible, making instruments with long names easier to find

DONE - Fix the exports formats to be compatible to the Patch 16 design. Full support of MONO, STEREO, and NTSC parameters, in both SAP and XEX formats (still in progress for some details, but they are fully functional)
DONE - Re-introduce the external binary loader, using the obx extension. This makes a lot of the things I am doing a lot more modular and easier to maintain since I don't have to hack pointers and memory addresses every time
DONE - Allow modules instrument speed to support up to speed 8 / Maximum of speed 4 in exports still!!
DONE - Fix the Tracker UI's hitbox so the 4th/8th channel's speed column could be clicked using the mouse pointer
DONE - Change ALT+DEL to CTRL+Z for undo, same for the redo whatever ALT+SHIFT+DEL, to CTRL+Y. This now seems to be fully functional, the previous redo combo had random chances of missing due to the implementation of how keys were checked

DONE - CTRL+TAB jumps to the speed columns of the currently edited channel
DONE - Fix the NUMLOCK bug in which it would get toggled at random, and would make the line step values increment at random when other keys were used
DONE - Fix the song timer to always reset when the player stops

DONE - Add the ability to either set a song bookmark, or remove it. Shortcut using it would either play from set bookmark, or from cursor position when unset. Bookmarks used to stay for as long as the module was edited

DONE - Cursor follow during play is now toggled with the F12 key, and playing from one of the shortcuts (now F5, F6 and F7) will not overwrite it, but instead make use of either case, making the overall interface less awkward when it's playing.

DONE - Reset the entire sound process (including reloading the .dll plugin) with a SHIFT+ESC combo, helps removing stutters or crackling in some cases

DONE - Fix a small visual bug related to the colours displayed, which caused conflicts with certain colours used together, and added a case for either being in JAM or EDIT mode when necessary.
DONE - JAM mode is toggled with CTRL+SPACE, the other SPACE shortcuts were removed (since other, better ways to stop the sounds exist anyway). Bug: Space is input when exiting Jam mode, due to a missing parameter, but will be fixed later
DONE - Instruments and song infos can now all be edited in Jam mode, leaving the Tracks and Song blocks the only ones which will be in live test mode.
DONE - Permanently display what mode is being used (EDIT, JAM (MONO) and JAM (STEREO)), with matching colour palettes (still in progress)

 

PARTIAL - General improvements of the text in the program, correcting English grammar and/or making things easier to understand when they were ambiguous
PARTIAL - Remove the necessity to use CAPSLOCK for typing uppercase characters holding SHIFT, this was counter-intuitive and rather unpleasant to have to use it like that, Currently there is few things to look further to make things 100% functional

PARTIAL - Re-map the entire set of hotkeys and shortcuts to make things more user friendly, and removing a lot of redundancy or just pointless commands (in my own opinion, more on that later)
PARTIAL - Attempt to re-create most of the 1.30 changes such as window resizing and bugfixes(?)
PARTIAL - Grammar and spelling correction in most dialogues and tracker UI
PARTIAL - Improvements in the Tracker UI for less confusing blocks of texts and/or elements being in better position, so they would display in more clarity (such as, what can and cannot be edited, as well as different colours between edit and jam (prove/test) mode
PARTIAL - Attempts to improve the sound buffer and latency to reduce wobbling and cracklings, this is not quite perfect and my edits may actually make things worse
PARTIAL - Implement more colours and/or graphical elements in the bitmap graphics for a visually more enjoyable interface (still in progress)

 

 

About the last one, it's really funny.

It sparkled from a dumb idea I had earlier today, and to my surprise...

unknown.png

Yep, indeed, it was just as dumb as this.

Add the graphic data in the bitmap image to be in the "boundaries" that would be expected in values above the ones exisiting, and RMT will happily load them, thus I will be able to add even more colours and graphical elements this way :D 

 

Anyway, that's the progress I have so far with my own experimental version, and I'm still actively working on it.

I hope I will have more to show soon :) 


 

  • Like 4
Link to comment
Share on other sites

 I have been sick for the last few days but I finally had the energy tonight and so here's some more progress done into the Patched RMT :)

 

- Display Two-Tone Filter, requires the Altirra plugins for proper functionality 
- PAL/NTSC toggle in-tracker using CTRL+F12
- Colours fix in the UI
- New font by PG
- Fixed the CTRL+SPACEBAR bug when exiting JAM MODE

 

More coming later, hopefully :D 

Can't wait to share an executable once I'm fully satisfied/am sure I didn't break everything.

  • Like 6
  • Thanks 2
Link to comment
Share on other sites

1 hour ago, andymanone said:

You are genius! 

THAT sounds amazing great ?! Both thumbs up!

This is not in the least comparable to Emkay´s releases....

 

Sorry, no hate.... 

 

Cheers,
andY

 

Careful now - you could be the next one accused of being a troll that pays people off to continue trolling :)

  • Haha 5
Link to comment
Share on other sites

Finally got more progress and hopefully more stuff to come soon.
Now I can build my patch version with Visual Studio 2019!

There was a frustrating bug to track down, and it was only an out of bounds array that broke everything... I spent over 2 days on that one. ?
And now, I can get in more serious thing related to it based directly on the code of 1.30 too ?

 

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Hey guys, long time no update, but despite the appearances, there is still a lot of work into thing going on, so here's a quick demonstration of my latest changes, the UI is getting revamped with a lot of changes, both visually and with the behaviour itself, so here's some progress so far :P 

 

It's a lot of fun to learn how things work, so I'm slowly understanding how to code in C++ every day I put my brain into this project :D 

I hope I can get more done once I figure things out, other than that, I've put into this a ton of tweaks, additions, and improvements, so I have good hope this may be ready soon for a new version.

  • Like 5
Link to comment
Share on other sites

So I just made a pretty cool discovery regarding the sound initialisation stage.

So some of you probably remember the combination of Clock and Pitches being a weird combination in RMT, something close to NTSC clock with PAL framerate?

Well I've dug a little further tonight with this, and to much of my surprise, it was a very easy fix to the RMT code to implement a proper clock for either region, and even could be re-initialised on the fly!

 

Here's a quick demonstration using the old sa_pokey.dll for the purpose, since the Pokey_SoundInit() call does not apply to apokeysnd.dll:

Which brings me to the next observation: this does not actually seem to work with Altirra's sa_pokey.dll

It will always return PAL pitch.

 

Sorry for tagging you here @phaeron but I thought this may interest you :D 
I remember you mentioned having worked around this situation when you created the Altirra plugins.

Do you think it is possible to allow the Altirra plugins to accept the calls for the CPU clock speed while still keeping cycle accuracy? 

From what I could understand, I had to only send 3 parameters: the CPU clock speed depending on which region is emulated (1789773 for NTSC or 1773447 for PAL), the output frequency (44100hz), as well as the number of channels (2).

 

I've pretty much figured a way to implement an automatic switch simply by looking for the g_ntsc BOOL, at initialisation time, or through a forced sound re-init each time I manually switch region.

As far as I could tell, this is definitely working with the old plugin, the "intended" way sa_pokey.dll operates I think? It even sounds like it's running at the proper pitch with this method, too :) 

 

Thanks in advance if you happen to be around, I would love to hear your thoughts about this!

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...