Mirai's Miscellaneous Misadventures
M29 / engines / psx.c
1
2
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}