Rambling about Javascript Frameworks

– Typescript
– React
– Anglular
– Framework 7

I’ve been looking into switching jobs recently. And while most of my freetime is spent analyzing file formats, my day job is working on web applications. In general my philosophy for web is that I want as little “magic” as possible between me and the code that I’m writing. The easiest example of this is jQuery. Back in the 2000’s there were still a lot of differences with browsers, and jQuery was the hottest library that managed the differences between the browsers, and did it with short and generally intuitive syntax. The problem was that when ever you searched, “how do i do x in Javascript?”, you would get 20 pages of results about jQuery and you had to filter through those to try and find any mention of how to implement what you wanted in vanilla Javascript.

And my issue with jQuery was that while it was a simple and effective way to write code, I didn’t want to have something that was interpreting Javascript for me. Sure it might be easier to write $(‘#elem’).removeClass(‘active’), than it is to write something like:

var elem = document.getElementById('elem');
var class_text = elem.getAttribute('class');
var classes = class_text.split(" ");
var index = classes.indexOf("active");
classes.splice(index, 1);
elem.setAttribute('class', classes.join(" "));

LBRY Videos

Tempted to start producing some videos for LBRY. Content that I have on my head:

– concept for open source handheld
– linux show for kids
– Gameboy Pocket Mod
– Gameboy Color Mod
– Gameboy Advance Mod
– DSiLL Mod
– PSP Mod
– PsVita Mod
– Playstation TV
– Wii Softmod
– WiiU Softmod
– Raspberry Pi NAS
– NextCloud on Raspberry Pi
– Nexus 5
– Nexus 5X
– Galaxy Note 3
– Galaxy S5
– Xperia Z3 Compact
– Pixel 1 / 2 / 3
– Pixel 2xl / 3xl
– Pinebook Pro
– NexDock
– Samsung Dex
– Ubuntu Touch
– Pinephone
– Fairphone
– Mobile Monitor
– Portable Projector
– Chrome Cast
– Cheap Windows Tablet as Linux

DMF 2.0 Specification

Really tempted to start drafting out the specification for DMF version 2.0. One thing I’m tempted to think about is the name. Maybe the “libre model format”? Not sure, maybe I’ll ask around and see what sticks.

Offset 0x00 0x02 0x04 0x06 0x08 0x0a 0x0c 0x0e
0x0000 DASH File Length magor minor header_ofs
– – – – Head Data – – – –
0x0020 META Block Length Count Offset
0x0030 TEX Block Length Count Offset
0x0040 MAT Block Length Count Offset
0x0050 VERT Block Length Count Offset
0x0060 FACE Block Length Count Offset
0x0070 BONE Block Length Count Offset
0x0080 ANIM Block Length Count Offset
– – – – Meta Data – – – –
– – – – Tex Data – – – –
0x0000 texture name line
0x0010 TexId isURL wrapS wrapT minFilter magFilter flipY format
0x0020 centerX centerY length offset
– – – – Mat Data – – – –
0x0000 material name line
0x0010 MatId TexId mat type visible Use Blend Blend EQ Blend Src Blend Dst
0x0020 shadow mat side Use Alpha v-colors alphaTest opacity
0x0030 Diffuse R Diffuse G Diffuse B Diffuse A
0x0040 Emmissive R Emmissive G Emmissive B Emmissive A
0x0050 Specular R Specular G Specular B Specular Coef
– – – – Vert Data – – – –
0x0000 VertexId Position X Position Y Position Z
0x0010 BoneId 1 BoneId 2 BoneId 3 BoneId 4 Weight 1 Weight 2 Weight 3 Weight 4
– – – – Face Data – – – –
0x0000 VertexId A VertexId B VertexId C MatId A Norm X
0x0010 A Norm Y A Norm Z B Norm X B Norm Y B Norm Z C Norm X C Norm Y C Norm Z
0x0020 A Map U A Map V B Map U B Map V
0x0030 C Map U C Map V A Clr R A Clr G A Clr B A Clr A
0x0040 B Clr R B Clr G B Clr B B Clr A C Clr R C Clr G C Clr B C Clr A
– – – – Bone Data – – – –
0x0000 Bone Name
0x0000 BoneId ParentId
0x0000 Local Matrix 00 Local Matrix 01 Local Matrix 02 Local Matrix 03
0x0000 Local Matrix 10 Local Matrix 11 Local Matrix 12 Local Matrix 13
0x0000 Local Matrix 20 Local Matrix 21 Local Matrix 22 Local Matrix 23
0x0000 Local Matrix 30 Local Matrix 31 Local Matrix 32 Local Matrix 33

Planning Tutorials

I’ve been trying to come up with a content management system dashgl.com for a while now. And I think I finally have something that might actually work. With content management i’ve always wanted something that’s simple where I can declare a few a few categories and then post a series of articles in a specific sequence. WordPress is good for stream-of-consciousness, but it’s kind of plugin hell to try and force a rigid layout.

Anyways, so content management seems to work. A few glaring omissions are a 404 not found page, mobile layout and client based navigation. And while it’s tempted to get into some of the bells and whistles right away, it’s a lot more important to focus on the content. So in terms of content, we need to start with the first EGL tutorial.

So in the first tutorial for the forward, we need to cover what the tutorial covers, which is going from drawing a simple triangle, and moving our way up to rendering a simple model in OpenGL. For the environment that we want to do this is, we need to cover the expected set up, which is programming for the Raspberry Pi 3b with a display hat. And to do this we need another computer to act as the ssh-client and the first computer to act as the ssh host.

To summarize the forward should layout the environment and conditions needed to use to program for the tutorial. And then we need to cover what the tutorial is for, and what the final output should be. So we should create drawings for all for the environment that needs to be used.

From there the easiest way to get started for the tutorials themselves is to provide a framework, list the title, and provide an image for each step, and fill in a gitlab link where the tutorial code can be viewed by the person taking the tutorial. From there we should probably try and provide a summary of what will be covered in the tutorial, what parts of the tutorial are challenging and try to come up with aspects that we should either attempt to cover or not. And then we can highlights parts of the code that we want to cover, and think about if or how we want to illustrate each point.

More Paperwork

Paperwork sucks. Have to renew my daughter’s visa. So I guess I should go over the list of documents that I need.

1. Application for extension: http://www.moj.go.jp/content/001290225.pdf
2. 外国人登録証 (コピー)
3. パスポート(コピー)
4. 健康保険被保険者証(コピー)
5. 住民票
6. 市県民税所得課税証明書
7. 納税証明書
8. 在職証明書
9. 給与所得の源泉徴収表

Seems easy enough, I guess I’ll get to it and start to build a folder for the documents. I also might as well go to the store and start making copies for stuff.

X220 + X240 vs e495

I’m not sure if I’m trying to talk myself into or talk myself out of this stupid idea. Right now I have two computers, an Asus UX305 and a HP Chromebook 13 G1. The Asus UX305 has been my main driver for the last several years. Over all it’s a pretty good computer, 13.3″ full hd with a fanless processor 4GB of RAM, and a 128GB SSD. Has a decent battery life and a nice keyboard layout. My ideal daily driver would be 14″ 1440p, 8GB RAM, 256GB SDD, and USB-C charging. Right now the Thinkpad Carbon X1 series seems to be ideal replacement, but those computers are stupidly expensive.

The HP Chromebook 13 G1 is a computer that I bought as a replacement. It has a 13.3″ 4k screen, fanless, usb-c charging, and 32GB of onboard storage. My thinking was that I could get around the short comings of the hardware, but after trying, there are too many flaws. The main flaw is track pad. It’s tiny and over all pretty terrible. It doesn’t feel anywhere as fluid as the Asus track pad. The keyboard doesn’t stack up, and while the keys have a decent click, the Chromebook keyboard leaves out a lot of common keys like delete, page up, page down, home and end, which I use a lot. The computer will always force suspend mode when closed, there isn’t a driver for the onboard audio, and 32GB of onboard storage fill up stupidly fast.

So I figured I’d go back to the drawing board. Effectively I want two computers. One computer would basically be a windows computer. I don’t use Windows every often, but there are a few occasions when it comes in handy. Specifically Daemon tools and really information from disks is a life saver. And I don’t like running Wine on Linux. If I need to do anything on Windows I prefer to have a network drive where I can drag and drop files to have something done on Windows and then copy back to Linux directly.

So my thinking was to have an X220 computer and an X240 computer. The X220 would be a simple Windows computer to run stuff on occasionally and the X240 would my main driver with Debian Gnome. Either that or get a e495 and use that as my main driver and convert my current Asus into a windows computer. Though my issue is that the e495 seems pretty expensive for a minor upgrade. It has 8GB of memory, 256GB of SDD, and USB-c for charging. But basically without the 1440p screen it seems like an expensive mid-step for a year or two before I replace it again.

So effectively for my uses, the X240 with a 1080p fills the same roll as the e495 for a fraction of the price. Originally I was thinking an X220 and an X240, but I’m actually tempted to go for 2x X240’s to have one with Windows 10 and the other with Debian/Gnome. That means that I can effectively have the same power connector and have one that uses windows and one that uses Linux and share the same hardware experience between them.

Youtube Cover Bands

This is not something that would normally go on this blog, but I wanted to try and make a list of Youtube bands

Against the Current – https://www.youtube.com/playlist?list=OLAK5uy_mo0aDYpNNJhFWkYLyGyst_B-mU4vDBnZw
Beast in Black – https://www.youtube.com/channel/UCZ6oHxEMKXlnjCzs_Ae55oA
Cristina Grimmie – https://www.youtube.com/playlist?list=OLAK5uy_lx788HkfcMMJgJ1Tel0jC0Jg1scgvINgA
Jonathan Young – https://www.youtube.com/user/jonathanyoungmusic/videos
Caleb Hyles – https://www.youtube.com/user/CalebsCovers/videos
NINA – https://www.youtube.com/user/NinaSingzMusic/videos
The Midnight – https://www.youtube.com/playlist?list=OLAK5uy_l6hWMoCv_dj643agxih8yEIc_F-igrT3k

Load Save State issue

OK so. After trying to set the memory I ran into several problems. At 1st I thought it was because I tried to change too many things to fast. And then after walking back several changes The reason seemed to be because Save States were not loading at all. The main reason I can think of for this is because the version I ForkedHad an issue with it.

I think there are several ways to do with This. One would be to look for a different version to fork. And another will be the right tools for looking at save states directly. As far as looking at save States directly I mean is you is looking into the Decompression. No in general would make more sense to use a version that actually works. So I think I’m going to look into the apt-get version and find out where that repository is.

https://github.com/pcsxr/PCSX-Reloaded

Edit:

After a few tests I found that trying to move around the order so that the system memory comes at the start of the save state has the side effect that save states don’t seem to be listed when loading. So there could be some check that happens ahead of time to throw these away. Not sure if I want to track down this process or not.

And then I also find that the 10th save state tends to be pretty annoying. The 10th state seems to a backup state that is automatically created when the emulation had stopped to be able to restore the state again. So I might try and check the last three characters of the save state, and if it’s ‘010’, then skip and don’t write a state.

Pcsx-Reloaded Memory Debug Edition

I’ve finally had a tiny bit of time to put into looking into PSX graphics again. And I think it would be a good idea to fork pcsx-r to try and re-write the save state writing and save state loading to make it easier to debug system memory. The cloned version is over at https://gitlab.com/kion-dgl/pcsxr-mem.

The code responsible for reading and writing states is libpcsxcore/misc.c.

int SaveState(const char *file) {
    gzFile f;
    long size;

    f = gzopen(file, "wb9"); // Best ratio but slow
    if (f == NULL) return -1;
    return SaveStateGz(f, &size);
}

int LoadState(const char *file) {
    gzFile f;

    f = gzopen(file, "rb");
    if (f == NULL) return -1;
    return LoadStateGz(f);
}

We have two functions SaveState and LoadState. And they both use a gxFile object type to create a compressed snapshot of memory to save as a state. We really don’t need this to be compressed. An easy change would probably be to change the compression from a 9 to a 0 for no compression. But I’m also tempted to change the order the file is written to make editing and reading easier.

nt SaveStateGz(gzFile f, long* gzsize) {
	int Size;
	unsigned char pMemGpuPic[SZ_GPUPIC];

	//if (f == NULL) return -1;

	gzwrite(f, (void *)PcsxrHeader, sizeof(PcsxrHeader));
	gzwrite(f, (void *)&SaveVersion, sizeof(u32));
	gzwrite(f, (void *)&Config.HLE, sizeof(boolean));

	if (gzsize)GPU_getScreenPic(pMemGpuPic); // Not necessary with ephemeral saves
	gzwrite(f, pMemGpuPic, SZ_GPUPIC);

	if (Config.HLE)
		psxBiosFreeze(1);

	gzwrite(f, psxM, 0x00200000);
	gzwrite(f, psxR, 0x00080000);
	gzwrite(f, psxH, 0x00010000);
	gzwrite(f, (void *)&psxRegs, sizeof(psxRegs));

	// gpu
	if (!gpufP)gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
	gpufP->ulFreezeVersion = 1;
	GPU_freeze(1, gpufP);
	gzwrite(f, gpufP, sizeof(GPUFreeze_t));

	// SPU Plugin cannot change during run, so we query size info just once per session
	if (!spufP) {
		spufP = (SPUFreeze_t *)malloc(offsetof(SPUFreeze_t, SPUPorts)); // only first 3 elements (up to Size)        
		SPU_freeze(2, spufP);
		Size = spufP->Size;
		SysPrintf("SPUFreezeSize %i/(%i)\n", Size, offsetof(SPUFreeze_t, SPUPorts));
		free(spufP);
		spufP = (SPUFreeze_t *) malloc(Size);
		spufP->Size = Size;

		if (spufP->Size <= 0) {
			gzclose(f);
			free(spufP);
			spufP = NULL;
			return 1; // error
		}
	}
	// spu
	gzwrite(f, &(spufP->Size), 4);
	SPU_freeze(1, spufP);
	gzwrite(f, spufP, spufP->Size);

	sioFreeze(f, 1);
	cdrFreeze(f, 1);
	psxHwFreeze(f, 1);
	psxRcntFreeze(f, 1);
	mdecFreeze(f, 1);

	if(gzsize)*gzsize = gztell(f);
	gzclose(f);

	return 0;
}

Here is the save state. And I think we’re interested in system memory and the framebuffer specifically. So we we’re interested in:

gzwrite(f, psxM, 0x00200000); 
...
// gpu
if (!gpufP)gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
gpufP->ulFreezeVersion = 1;
GPU_freeze(1, gpufP);
gzwrite(f, gpufP, sizeof(GPUFreeze_t));

And I think if we turn off compression and move these to the start of the function, we should get an uncompressed save state with memory for the first 2MB, followed by vram for the next 1MB, and then everything else thrown in after that. But then we need to make sure the Load state function also matches.

int LoadStateGz(gzFile f) {
	SPUFreeze_t *_spufP;
	int Size;
	char header[sizeof(PcsxrHeader)];
	u32 version;
	boolean hle;

	if (f == NULL) return -1;

	gzread(f, header, sizeof(header));
	gzread(f, &version, sizeof(u32));
	gzread(f, &hle, sizeof(boolean));

	// Compare header only "STv4 PCSXR" part no version
	if (strncmp(PcsxrHeader, header, PCSXR_HEADER_SZ) != 0 || version != SaveVersion || hle != Config.HLE) {
		gzclose(f);
		return -1;
	}

	psxCpu->Reset();
	gzseek(f, SZ_GPUPIC, SEEK_CUR);

	gzread(f, psxM, 0x00200000);
	gzread(f, psxR, 0x00080000);
	gzread(f, psxH, 0x00010000);
	gzread(f, (void *)&psxRegs, sizeof(psxRegs));

	if (Config.HLE)
		psxBiosFreeze(0);

	// gpu
	if (!gpufP)gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
	gzread(f, gpufP, sizeof(GPUFreeze_t));
	GPU_freeze(0, gpufP);

	// spu
	gzread(f, &Size, 4);
	_spufP = (SPUFreeze_t *)malloc(Size);
	gzread(f, _spufP, Size);
	SPU_freeze(0, _spufP);
	free(_spufP);

	sioFreeze(f, 0);
	cdrFreeze(f, 0);
	psxHwFreeze(f, 0);
	psxRcntFreeze(f, 0);
	mdecFreeze(f, 0);

	gzclose(f);

	return 0;
}

In which case we also need to move the read system ram and vram to the start of the function.

gzread(f, psxM, 0x00200000);
...
// gpu
if (!gpufP)gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
gzread(f, gpufP, sizeof(GPUFreeze_t));
GPU_freeze(0, gpufP);

That means the version checks for the state state version will come after, but I think that should be okay. So we might as well give this a shot and see if it works.