Wednesday, November 25, 2020

I am the queen of No Nut November!

After months of delays, they're finally gone! One more step to becoming who I truly am. No need to worry about testosterone anymore.

Thank you to the doctors, nurses, and hospital staff at the University of Kansas Bell Hospital who were very patient answering my questions and making me comfortable.

And a very special thank you to my sweetie dragon Scrydan, who was there with me the whole time. I couldn't ask for a better boyfriend!

Thursday, October 15, 2020

Saying goodbye to my two best friends

Not the ones in the Winnebago.

My two friends have forced testosterone on me for years. I've already blocked them, and I'm about to cut them out of my life entirely. Next month, I'm going in for surgery to get rid of these dysphoria dumplings once and for all.

Goodbye and good riddance.

Monday, September 21, 2020

Fixing an obscure Undertale bug

Undertale's 5th anniversary was a couple of weeks ago, so I decided to play through it again. However, when I tried to start it up, it just crashed right away. There was a lot of diagnostic output, but no error messages, just an exit. These kinds of bugs are difficult to diagnose, but I wasn't going to let that stop me from enjoying those goat hugs.

I ran Steam in a console window, and changed the launch options to run the game under a debugger:

That at least told me what the error was: SIGFPE - usually caused by an integer division by zero.

Reading symbols from /media/disk1/lstuff/steam/steamapps/common/Undertale/runner...(no debugging symbols found)...done.
(gdb) r
Starting program: /media/disk1/lstuff/steam/steamapps/common/Undertale/runner 
.
.
.
Thread 1 "runner" received signal SIGFPE, Arithmetic exception.
0x081d7332 in ?? ()
(gdb) 

What could it be trying to divide by zero? Maybe the rest of the output might give me a hint.

***************************************
*     YoYo Games Linux Runner V1.3    *
***************************************
CommandLine: -game game.unx
ExeName= /media/disk1/lstuff/steam/steamapps/common/Undertale/runner
MemoryManager allocated: 4031222
INI DisplayName=UNDERTALE
SavePrePend /home/ktpanda/.config/UNDERTALE/
GAMEPAD: Initialising Ubuntu support
Attempting to set gamepadcount to 4
display=0x9682cd0
Display Size(Pixels): 1920,1080
CreateDesktopWindow 640,480
Win #1
XF86VidModeExtension-Version 2.2
Got Doublebuffered Visual!
glX-Version 1.4
Icon: w=64 h=64
Creating window of width 640, height 480
sw=0 wh=0
WindowCentre: 640,300
Depth 24
Congrats, you have Direct Rendering!
sync = 1
**** GLX Extensions ***
GLX_EXT_visual_info GLX_EXT_visual_rating ...
Checking for GLX_EXT_swap_control
Vsync: GLX_EXT
DOUBLE BUFFERED
OpenGL: version string 4.6.0 NVIDIA 440.66.12
OpenGL: vendor string NVIDIA Corporation
OpenGL GLSL: version string 4.60 NVIDIA
Extensions:
GL_AMD_multi_draw_indirect GL_AMD_seamless_cubemap_per_texture ...
Anisotropic filtering supported, max aniso 16
This is where it would have set them fullscreen= 0, they are 0,0    displaywidth/h 0,0
Texture #1 16,16
Texture #2 16,16
Texture #1 16,16
Texture #2 16,16
finished(2)!!
Texture #1 1,1
Texture #2 1,1
finished(2)!!
Total memory used = 81515771(0x04dbd4fb) bytes

So one thing that stands out is the line that says displaywidth/h 0,0. If for some reason it was seeing the display resolution as 0x0, it is very plausible that trying to calculate something related to the aspect ratio would result in division by zero. But where is it getting that size from? Especially since earlier, it detects it correctly: Display Size(Pixels): 1920,1080.

Time to fire up xtrace. This utility intercepts all communication between the program and the X display server and dumps it. Undertale must be calling some weird function and misinterpreting the results.

***************************************
*     YoYo Games Linux Runner V1.3    *
***************************************
CommandLine: -game game.unx
ExeName= /media/disk1/lstuff/steam/steamapps/common/Undertale/runner
MemoryManager allocated: 4031222
INI DisplayName=UNDERTALE
SavePrePend /home/ktpanda/.config/UNDERTALE/
GAMEPAD: Initialising Ubuntu support
Attempting to set gamepadcount to 4
000:<: am lsb-first want 11:0 authorising with 'MIT-MAGIC-COOKIE-1' of length 16
000:>: Success, version is 11:0 vendor='The X.Org Foundation' release=11906000 resource-id=0x0a200000 resource-mask=0x001fffff [...] width[pixel]=1920 height[pixel]=1080 [...]
000:<:0001: 20: Request(98): QueryExtension name='BIG-REQUESTS'
000:>:0001:32: Reply to QueryExtension: present=true(0x01) major-opcode=133 first-event=0 first-error=0
000:<:0002:  4: BIG-REQUESTS-Request(133,0): Enable
000:>:0002:32: Reply to Enable: maximum-request-length=4194303
000:<:0003: 20: Request(55): CreateGC cid=0x0a200000 drawable=0x00000245 values={background=0x00ffffff}
000:<:0004: 24: Request(20): GetProperty delete=false(0x00) window=0x00000245 property=0x17("RESOURCE_MANAGER") type=0x1f("STRING") long-offset=0x00000000 long-length=0x05f5e100
000:>:0004:2168: Reply to GetProperty: type=0x1f("STRING") bytes-after=0x00000000 data='[...]'
000:<:0005: 20: Request(98): QueryExtension name='XKEYBOARD'
000:>:0005:32: Reply to QueryExtension: present=true(0x01) major-opcode=135 first-event=85 first-error=137
000:<:0006:  8: XKEYBOARD-Request(135,0): UseExtension major=1 minor=0
000:>:0006:32: Reply to UseExtension: major=1 minor=0
display=0x95bacd0
Display Size(Pixels): 1920,1080
CreateDesktopWindow 640,480
Win #1
.
.
.
000:<:003a: 16: Request(98): QueryExtension name='RANDR'
000:>:003a:32: Reply to QueryExtension: present=true(0x01) major-opcode=140 first-event=89 first-error=147
000:<:003b: 12: RANDR-Request(140,0): QueryVersion major-version=1 minor-version=5
000:<:003c:  8: RANDR-Request(140,8): GetScreenResources window=0x0a200003
000:>:003b:32: Reply to QueryVersion: major-version=1 minor-version=5
000:>:003c:3680: Reply to GetScreenResources: timestamp=0x42ae9f12 config-timestamp=0x0003cf23 [...]
000:<:003d: 12: RANDR-Request(140,20): GetCrtcInfo crtc=0x0000023a config-timestamp=0x0003cf23
000:>:003d:44: Reply to GetCrtcInfo: status=Success(0x00) timestamp=0x42ae9f12 x=0 y=0 width=0 height=0 mode=0x00000000 current rr=0 possible rr=Rotate_0,Rotate_90,Rotate_180,Rotate_270,Reflect_X,Reflect_Y outputs=; possible outputs=0x0000023e,0x0000023f,0x00000240;
sw=0 wh=0
WindowCentre: 640,300
Depth 24

Well, would you look at that!? GetCrtcInfo returns 0 for both width and height. This is an XRandR function, so its actual name is XRRGetCrtcInfo. This function is so obscure that searching for it brings up a few examples, some StackOverflow questions, and the header file where it's defined, but no actual documentation for it. I played around with the xrandr utility, hoping to figure out what's causing it to return zero, but nothing worked.

But it's still just a hypothesis that this one call is what's causing the crash. If I could just trick the game into thinking that it returned the correct size, then maybe it will work. The definition of XRRGetCrtcInfo looks like this:

typedef struct _XRRCrtcInfo {
    Time	    timestamp;
    int		    x, y;
    unsigned int    width, height;
    RRMode	    mode;
    Rotation	    rotation;
    int		    noutput;
    RROutput	    *outputs;
    Rotation	    rotations;
    int		    npossible;
    RROutput	    *possible;
} XRRCrtcInfo;

XRRCrtcInfo *
XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc);

I can use the debugger and break on the call to XRRGetCrtcInfo, then step out, then poke values into the structure it returns:

Reading symbols from /media/disk1/lstuff/steam/steamapps/common/Undertale/runner...(no debugging symbols found)...done.
(gdb)
(gdb) break XRRGetCrtcInfo
Breakpoint 1 at 0x804f4a0
(gdb) r
Starting program: /media/disk1/lstuff/steam/steamapps/common/Undertale/runner
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

***************************************
*     YoYo Games Linux Runner V1.3    *
***************************************
CommandLine: -game game.unx
ExeName= /media/disk1/lstuff/steam/steamapps/common/Undertale/runner
MemoryManager allocated: 4031222
INI DisplayName=UNDERTALE
SavePrePend /home/ktpanda/.config/UNDERTALE/
GAMEPAD: Initialising Ubuntu support
Attempting to set gamepadcount to 4
display=0x880ccd0
Display Size(Pixels): 1920,1080
CreateDesktopWindow 640,480
Win #1
XF86VidModeExtension-Version 2.2
Got Doublebuffered Visual!
glX-Version 1.4
Icon: w=64 h=64
Creating window of width 640, height 480

Breakpoint 1, 0xf7829d50 in XRRGetCrtcInfo () from /usr/lib/i386-linux-gnu/libXrandr.so.2
(gdb) finish
Run till exit from #0  0xf7829d50 in XRRGetCrtcInfo () from /usr/lib/i386-linux-gnu/libXrandr.so.2
0x082fc8f7 in ?? ()
(gdb) info registers
eax            0x888ccd0	143183056
ecx            0x0	0
edx            0x89606e8	144049896
ebx            0x873fae4	141818596
esp            0xffffa8a0	0xffffa8a0
ebp            0xf709db00	0xf709db00
esi            0x1002	4098
edi            0x895c170	144032112
eip            0x82fc8f7	0x82fc8f7
eflags         0x200282	[ SF IF ID ]
cs             0x23	35
ss             0x2b	43
ds             0x2b	43
es             0x2b	43
fs             0x0	0
gs             0x63	99
(gdb) p ((unsigned int*)0x888ccd0)[0]
$1 = 1133426070
(gdb) p ((unsigned int*)0x888ccd0)[1]
$2 = 0
(gdb) p ((unsigned int*)0x888ccd0)[2]
$3 = 0
(gdb) p ((unsigned int*)0x888ccd0)[3]
$4 = 0
(gdb) p (((unsigned int*)0x888ccd0)[3] = 1920)
$5 = 1920
(gdb) p (((unsigned int*)0x888ccd0)[4] = 1080)
$6 = 1080
(gdb) c
Continuing.
sw=1920 wh=1080
WindowCentre: 640,300
Depth 24

Success! It sees the proper display size now, and the game starts up!

But that's a lot of work I'd have to do every time I launch the game, especially given what happens near the end. Fortunately, Linux and some other Unix-like operating systems support a feature called LD_PRELOAD, which allows injecting a library into a program before it loads, allowing it to override functions in other libraries. I created a simple C library that I could use with LD_PRELOAD for an automated fix. I'm currently working on cleaning up the code to upload it.

Let me know if you see something similar! I couldn't find anyone else posting about this bug, so it must not be common.

Thursday, April 30, 2020

Ouch

I just did my first self-injection of estradiol valerate earlier! It went pretty well, even though I was extremely nervous and my hands were shaking. I recorded the process so I could review it - it took 22 seconds to actually stick the needle in. I'm sure it will get easier with time.

My doctor initially prescribed estriadiol cypionate, but it's not available as a generic, only under the brand name Depo-Estradiol. She changed it to estradiol valerate, which is generic and seems to be more common anyway. My insurance would cover the EV, but not completely. It was actually cheaper with GoodRX, with the caveat that it doesn't apply to my deductible. Yay, privatized healthcare.

On the subject of estradiol, I read an article about a clinical trial where doctors are going to try giving transdermal estradiol to cis men who test positive for COVID-19, because data shows that women are more likely to survive. I really hope this doesn't cause a shortage. There are already nutjobs making up stories about how this whole thing is a conspiracy to feminize men and turn them into "soy-boy cucks" or "simps" (or whatever their latest slur is for men who don't fall in line with what they think a man should be), with a good deal of racism thrown in for good measure. It's the kind of thing you laugh at until you realize they are 100% serious.

Friday, April 24, 2020

It's my E-nniversary!

Time goes by so fast. One year ago - April 24, 2019 - I took my first estradiol pill. So much has changed for me since I began HRT! My skin is smoother, I sweat a lot less, and of course - certain... features have started growing. Those little blue pills have done more to treat my depression than any of the antidepressants I've taken in the past!

I may not be taking them much longer, though - I'm going to try switching to intramuscular injections of estradiol valerate, which has less risk of being metabolized to estrone in the liver. Among the transfeminine people I've spoken to, it seems pretty common to switch to injections after a year. It's honestly kind of exciting!

I ended up starting HRT sooner than I had planned. I still wasn't 100% certain I wanted to transition. But I knew that if I was going to transition, the sooner I started, the better. The effects would not be immediate, and I could stop taking it if I didn't like it. In the end, I'm really glad I started when I did! Every day I delayed would have made it harder to be who I am inside.

Tuesday, March 31, 2020

It's been an interesting year

I began my transition nearly a year ago, on April 3rd, 2019. I'm posting this a bit early, because today, March 31st, is International Transgender Day of Visibility. I can't put into words how much happier I am now! This past year has been the best year of my life so far, despite the struggles of dealing with dysphoria and transphobia. My transition has gone realtively smoothly, and I realize it's not that easy for everyone. Sure, my family hasn't been super supportive, but they haven't disowned me, cut off contact, or attacked me. I'm lucky that I work for a company with a strong anti-discrimination policy. All of my friends have been extremely supportive.

Many people aren't so lucky, though. Every day, trans people are harrassed, bullied, evicted, fired, attacked, and even murdered — just because they are trans. Some trans people have to hide the fact that they are trans for their own safety. This is why we need a Trans Day of Visibility. It's easier to hate someone you don't know. It's getting better though, and as long as we continue to fight for our rights, it will continue to get better in the future.

So once again, thank you to all the people who have supported me this past year. I could not have done this alone!

Saturday, March 07, 2020

Texas Furry Fiesta 2020!

I had so much fun at TFF this year! TFF is special to me because it's where I met my wonderful dragon boyfriend Scrydan last year.