Mirai's Miscellaneous Misadventures

M29 / engines / psx.c

1// copyright 2022 zamfofex
2// license: AGPLv3 or later
3
4#include <stdlib.h>
5#include <psxgpu.h>
6
7#include <mimimi/engines.h>
8#include <mimimi/assets.h>
9#include <mimimi/behaviors.h>
10#include <mimimi/geometry.h>
11#include <mimimi/chapters.h>
12#include <mimimi/engines/psx.h>
13#include <mimimi/malloc.h>
14
15static unsigned short int mimimi_psx_palette[256] =
16{
17	0x0000, 0x0842, 0x1084, 0x18C6, 0x2529, 0x2D6B, 0x35AD, 0x3DEF,
18	0x4631, 0x4E73, 0x56B5, 0x5EF7, 0x6B5A, 0x739C, 0x7BDE, 0x8420,
19	0x1042, 0x2842, 0x4442, 0x5C42, 0x7442, 0x10C2, 0x28C2, 0x44C2,
20	0x5CC2, 0x74C2, 0x1142, 0x2942, 0x4542, 0x5D42, 0x7542, 0x11C2,
21	0x29C2, 0x45C2, 0x5DC2, 0x75C2, 0x1262, 0x2A62, 0x4662, 0x5E62,
22	0x7662, 0x12E2, 0x2AE2, 0x46E2, 0x5EE2, 0x76E2, 0x1362, 0x2B62,
23	0x4762, 0x5F62, 0x7762, 0x13E2, 0x2BE2, 0x47E2, 0x5FE2, 0x77E2,
24	0x1048, 0x2848, 0x4448, 0x5C48, 0x7448, 0x10C8, 0x28C8, 0x44C8,
25	0x5CC8, 0x74C8, 0x1148, 0x2948, 0x4548, 0x5D48, 0x7548, 0x11C8,
26	0x29C8, 0x45C8, 0x5DC8, 0x75C8, 0x1268, 0x2A68, 0x4668, 0x5E68,
27	0x7668, 0x12E8, 0x2AE8, 0x46E8, 0x5EE8, 0x76E8, 0x1368, 0x2B68,
28	0x4768, 0x5F68, 0x7768, 0x13E8, 0x2BE8, 0x47E8, 0x5FE8, 0x77E8,
29	0x104E, 0x284E, 0x444E, 0x5C4E, 0x744E, 0x10CE, 0x28CE, 0x44CE,
30	0x5CCE, 0x74CE, 0x114E, 0x294E, 0x454E, 0x5D4E, 0x754E, 0x11CE,
31	0x29CE, 0x45CE, 0x5DCE, 0x75CE, 0x126E, 0x2A6E, 0x466E, 0x5E6E,
32	0x766E, 0x12EE, 0x2AEE, 0x46EE, 0x5EEE, 0x76EE, 0x136E, 0x2B6E,
33	0x476E, 0x5F6E, 0x776E, 0x13EE, 0x2BEE, 0x47EE, 0x5FEE, 0x77EE,
34	0x1053, 0x2853, 0x4453, 0x5C53, 0x7453, 0x10D3, 0x28D3, 0x44D3,
35	0x5CD3, 0x74D3, 0x1153, 0x2953, 0x4553, 0x5D53, 0x7553, 0x11D3,
36	0x29D3, 0x45D3, 0x5DD3, 0x75D3, 0x1273, 0x2A73, 0x4673, 0x5E73,
37	0x7673, 0x12F3, 0x2AF3, 0x46F3, 0x5EF3, 0x76F3, 0x1373, 0x2B73,
38	0x4773, 0x5F73, 0x7773, 0x13F3, 0x2BF3, 0x47F3, 0x5FF3, 0x77F3,
39	0x1059, 0x2859, 0x4459, 0x5C59, 0x7459, 0x10D9, 0x28D9, 0x44D9,
40	0x5CD9, 0x74D9, 0x1159, 0x2959, 0x4559, 0x5D59, 0x7559, 0x11D9,
41	0x29D9, 0x45D9, 0x5DD9, 0x75D9, 0x1279, 0x2A79, 0x4679, 0x5E79,
42	0x7679, 0x12F9, 0x2AF9, 0x46F9, 0x5EF9, 0x76F9, 0x1379, 0x2B79,
43	0x4779, 0x5F79, 0x7779, 0x13F9, 0x2BF9, 0x47F9, 0x5FF9, 0x77F9,
44	0x105F, 0x285F, 0x445F, 0x5C5F, 0x745F, 0x10DF, 0x28DF, 0x44DF,
45	0x5CDF, 0x74DF, 0x115F, 0x295F, 0x455F, 0x5D5F, 0x755F, 0x11DF,
46	0x29DF, 0x45DF, 0x5DDF, 0x75DF, 0x127F, 0x2A7F, 0x467F, 0x5E7F,
47	0x767F, 0x12FF, 0x2AFF, 0x46FF, 0x5EFF, 0x76FF, 0x137F, 0x2B7F,
48	0x477F, 0x5F7F, 0x777F, 0x13FF, 0x2BFF, 0x47FF, 0x5FFF, 0x77FF,
49};
50
51struct mimimi_psx_data
52{
53	unsigned short int *colors;
54	int x, y;
55};
56
57static void mimimi_psx_stamp(void *data, int x1, int y1, struct mimimi_image *image)
58{
59	struct mimimi_psx_data *psx_data = data;
60	
61	int x0 = 0;
62	int y0 = 0;
63	
64	if (x1 < 0) x0 = -x1;
65	if (y1 < 0) y0 = -y1;
66	
67	int width = image->width;
68	int height = image->height;
69	
70	if (width + x1 > 512) width = 512 - x1;
71	if (height + y1 > 256) height = 256 - y1;
72	
73	for (int y = y0 ; y < height ; y++)
74	for (int x = x0 ; x < width ; x++)
75	{
76		unsigned char color = image->colors[x + y * image->width];
77		if (color == 0) continue;
78		
79		int x2 = x + x1;
80		int y2 = y + y1;
81		
82		psx_data->colors[x2 + y2 * 512] = mimimi_psx_palette[color];
83	}
84	
85	RECT rectangle = {psx_data->x, psx_data->y, 512, 256};
86	LoadImage(&rectangle, (void *) psx_data->colors);
87}
88
89void mimimi_psx(struct mimimi_chapter *(*start)(struct mimimi_engine *engine))
90{
91	static struct mimimi_size size = {512, 256};
92	
93	ResetGraph(0);
94	
95	DISPENV display[2];
96	SetDefDispEnv(display + 0, 0, 0, size.width, 384);
97	SetDefDispEnv(display + 1, size.width, 0, size.width, 384);
98	display[0].isinter = 1;
99	display[1].isinter = 1;
100	
101	SetDispMask(1);
102	
103	struct mimimi_psx_data data;
104	data.colors = malloc(size.width * size.height * 2);
105	data.x = 0;
106	data.y = 0;
107	
108	struct mimimi_engine engine;
109	engine.data = &data;
110	engine.stamp = &mimimi_psx_stamp;
111	engine.size = &size;
112	engine.allocator = mimimi_malloc;
113	struct mimimi_chapter *chapter = (*start)(&engine);
114	struct mimimi_behavior *behavior = chapter->behavior;
115	
116	int i = 0;
117	for (;;)
118	{
119		i ^= 1;
120		
121		data.x = size.width * i;
122		(*behavior->behave)(behavior->data);
123		
124		VSync(0);
125		PutDispEnv(display + i);
126	}
127}