Browse code

Added SDL layer

neauoire authored on 08/02/2021 23:46:52
Showing 4 changed files
... ...
@@ -15,7 +15,7 @@ clang-format -i emulator.c
15 15
 clang-format -i uxn.h
16 16
 clang-format -i uxn.c
17 17
 rm -f ./uxn
18
-cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -o bin/emulator
18
+cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator
19 19
 
20 20
 # run
21 21
 ./bin/emulator bin/boot.rom
... ...
@@ -1,5 +1,5 @@
1
+#include <SDL2/SDL.h>
1 2
 #include <stdio.h>
2
-#include "uxn.h"
3 3
 
4 4
 /*
5 5
 Copyright (c) 2021 Devine Lu Linvega
... ...
@@ -12,6 +12,90 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 12
 WITH REGARD TO THIS SOFTWARE.
13 13
 */
14 14
 
15
+#include "uxn.h"
16
+
17
+#define HOR 32
18
+#define VER 16
19
+#define PAD 2
20
+#define SZ (HOR * VER * 16)
21
+
22
+typedef unsigned char Uint8;
23
+
24
+int WIDTH = 8 * HOR + 8 * PAD * 2;
25
+int HEIGHT = 8 * (VER + 2) + 8 * PAD * 2;
26
+int FPS = 30, GUIDES = 1, BIGPIXEL = 0, ZOOM = 2;
27
+
28
+Uint32 theme[] = {
29
+	0x000000,
30
+	0xFFFFFF,
31
+	0x72DEC2,
32
+	0x666666,
33
+	0x222222};
34
+
35
+SDL_Window *gWindow;
36
+SDL_Renderer *gRenderer;
37
+SDL_Texture *gTexture;
38
+Uint32 *pixels;
39
+
40
+int
41
+error(char *msg, const char *err)
42
+{
43
+	printf("Error %s: %s\n", msg, err);
44
+	return 0;
45
+}
46
+
47
+void
48
+clear(Uint32 *dst)
49
+{
50
+	int v, h;
51
+	for(v = 0; v < HEIGHT; v++)
52
+		for(h = 0; h < WIDTH; h++)
53
+			dst[v * WIDTH + h] = theme[0];
54
+}
55
+
56
+void
57
+redraw(Uint32 *dst)
58
+{
59
+	SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32));
60
+	SDL_RenderClear(gRenderer);
61
+	SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
62
+	SDL_RenderPresent(gRenderer);
63
+}
64
+
65
+void
66
+quit(void)
67
+{
68
+	free(pixels);
69
+	SDL_DestroyTexture(gTexture);
70
+	gTexture = NULL;
71
+	SDL_DestroyRenderer(gRenderer);
72
+	gRenderer = NULL;
73
+	SDL_DestroyWindow(gWindow);
74
+	gWindow = NULL;
75
+	SDL_Quit();
76
+	exit(0);
77
+}
78
+
79
+int
80
+init(void)
81
+{
82
+	if(SDL_Init(SDL_INIT_VIDEO) < 0)
83
+		return error("Init", SDL_GetError());
84
+	gWindow = SDL_CreateWindow("Uxn", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH * ZOOM, HEIGHT * ZOOM, SDL_WINDOW_SHOWN);
85
+	if(gWindow == NULL)
86
+		return error("Window", SDL_GetError());
87
+	gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
88
+	if(gRenderer == NULL)
89
+		return error("Renderer", SDL_GetError());
90
+	gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT);
91
+	if(gTexture == NULL)
92
+		return error("Texture", SDL_GetError());
93
+	if(!(pixels = (Uint32 *)malloc(WIDTH * HEIGHT * sizeof(Uint32))))
94
+		return error("Pixels", "Failed to allocate memory");
95
+	clear(pixels);
96
+	return 1;
97
+}
98
+
15 99
 void
16 100
 echos(Stack8 *s, Uint8 len, char *name)
17 101
 {
... ...
@@ -49,21 +133,68 @@ echof(Uxn *c)
49 133
 		getflag(&c->status, FLAG_COND) != 0);
50 134
 }
51 135
 
136
+void
137
+domouse(SDL_Event *event)
138
+{
139
+	(void)event;
140
+	printf("mouse\n");
141
+}
142
+
143
+void
144
+dokey(SDL_Event *event)
145
+{
146
+	(void)event;
147
+	printf("key\n");
148
+}
149
+
52 150
 int
53
-main(int argc, char *argv[])
151
+start(Uxn *u)
54 152
 {
55
-	Uxn cpu;
153
+	int ticknext = 0;
154
+	evaluxn(u, u->vreset);
155
+	while(1) {
156
+		int tick = SDL_GetTicks();
157
+		SDL_Event event;
158
+		if(tick < ticknext)
159
+			SDL_Delay(ticknext - tick);
160
+		ticknext = tick + (1000 / FPS);
161
+		evaluxn(u, u->vframe);
162
+		while(SDL_PollEvent(&event) != 0) {
163
+			switch(event.type) {
164
+			case SDL_QUIT: quit(); break;
165
+			case SDL_MOUSEBUTTONUP:
166
+			case SDL_MOUSEBUTTONDOWN:
167
+			case SDL_MOUSEMOTION: domouse(&event); break;
168
+			case SDL_KEYDOWN: dokey(&event); break;
169
+			case SDL_WINDOWEVENT:
170
+				if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
171
+					redraw(pixels);
172
+				break;
173
+			}
174
+		}
175
+	}
176
+}
177
+
178
+int
179
+main(int argc, char **argv)
180
+{
181
+	Uxn u;
56 182
 
57 183
 	if(argc < 2)
58
-		return error(&cpu, "No input.", 0);
59
-	if(!load(&cpu, argv[1]))
60
-		return error(&cpu, "Load error", 0);
61
-	if(!boot(&cpu))
62
-		return error(&cpu, "Boot error", 0);
63
-
64
-	/* print result */
65
-	echos(&cpu.wst, 0x40, "stack");
66
-	echom(&cpu.ram, 0x40, "ram");
67
-	echof(&cpu);
184
+		return error("Input", "Missing");
185
+	if(!bootuxn(&u))
186
+		return error("Boot", "Failed");
187
+	if(!loaduxn(&u, argv[1]))
188
+		return error("Load", "Failed");
189
+	if(!init())
190
+		return error("Init", "Failed");
191
+
192
+	start(&u);
193
+
194
+	echos(&u.wst, 0x40, "stack");
195
+	echom(&u.ram, 0x40, "ram");
196
+	echof(&u);
197
+
198
+	quit();
68 199
 	return 0;
69 200
 }
... ...
@@ -97,24 +97,44 @@ Uint8 opr[][2] = {
97 97
 /* clang-format on */
98 98
 
99 99
 int
100
-error(Uxn *u, char *name, int id)
100
+haltuxn(Uxn *u, char *name, int id)
101 101
 {
102 102
 	printf("Error: %s#%04x, at 0x%04x\n", name, id, u->counter);
103 103
 	return 0;
104 104
 }
105 105
 
106
+void
107
+inituxn(Uxn *u)
108
+{
109
+	size_t i;
110
+	char *cptr = (char *)u;
111
+	for(i = 0; i < sizeof u; i++)
112
+		cptr[i] = 0;
113
+}
114
+
115
+int
116
+loaduxn(Uxn *u, char *filepath)
117
+{
118
+	FILE *f;
119
+	if(!(f = fopen(filepath, "rb")))
120
+		return haltuxn(u, "Missing input.", 0);
121
+	fread(u->ram.dat, sizeof(u->ram.dat), 1, f);
122
+	printf("Uxn Loaded: %s\n", filepath);
123
+	return 1;
124
+}
125
+
106 126
 int
107
-doliteral(Uxn *u, Uint8 instr)
127
+lituxn(Uxn *u, Uint8 instr)
108 128
 {
109 129
 	if(u->wst.ptr >= 255)
110
-		return error(u, "Stack overflow", instr);
130
+		return haltuxn(u, "Stack overflow", instr);
111 131
 	wspush8(u, instr);
112 132
 	u->literal--;
113 133
 	return 1;
114 134
 }
115 135
 
116 136
 int
117
-dodevices(Uxn *u) /* experimental */
137
+devuxn(Uxn *u) /* experimental */
118 138
 {
119 139
 	if(u->ram.dat[0xfff1]) {
120 140
 		printf("%c", u->ram.dat[0xfff1]);
... ...
@@ -124,7 +144,7 @@ dodevices(Uxn *u) /* experimental */
124 144
 }
125 145
 
126 146
 int
127
-doopcode(Uxn *u, Uint8 instr)
147
+opcuxn(Uxn *u, Uint8 instr)
128 148
 {
129 149
 	Uint8 op = instr & 0x1f;
130 150
 	setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1);
... ...
@@ -133,61 +153,40 @@ doopcode(Uxn *u, Uint8 instr)
133 153
 	if(getflag(&u->status, FLAG_SHORT))
134 154
 		op += 16;
135 155
 	if(u->wst.ptr < opr[op][0])
136
-		return error(u, "Stack underflow", op);
156
+		return haltuxn(u, "Stack underflow", op);
137 157
 	if(u->wst.ptr + opr[op][1] - opr[op][0] >= 255)
138
-		return error(u, "Stack overflow", instr);
158
+		return haltuxn(u, "Stack overflow", instr);
139 159
 	if(!getflag(&u->status, FLAG_COND) || (getflag(&u->status, FLAG_COND) && wspop8(u)))
140 160
 		(*ops[op])(u);
141
-	dodevices(u);
142
-	return 1;
143
-}
144
-
145
-int
146
-eval(Uxn *u)
147
-{
148
-	Uint8 instr = u->ram.dat[u->ram.ptr++];
149
-	if(u->literal > 0)
150
-		return doliteral(u, instr);
151
-	else
152
-		return doopcode(u, instr);
161
+	devuxn(u);
153 162
 	return 1;
154 163
 }
155 164
 
156 165
 int
157
-load(Uxn *u, char *filepath)
166
+evaluxn(Uxn *u, Uint16 vec)
158 167
 {
159
-	FILE *f;
160
-	if(!(f = fopen(filepath, "rb")))
161
-		return error(u, "Missing input.", 0);
162
-	fread(u->ram.dat, sizeof(u->ram.dat), 1, f);
168
+	u->ram.ptr = vec;
169
+	setflag(&u->status, FLAG_HALT, 0);
170
+	while(!(u->status & FLAG_HALT)) {
171
+		Uint8 instr = u->ram.dat[u->ram.ptr++];
172
+		u->counter++;
173
+		if(u->literal > 0)
174
+			return lituxn(u, instr);
175
+		else
176
+			return opcuxn(u, instr);
177
+	}
163 178
 	return 1;
164 179
 }
165 180
 
166
-void
167
-reset(Uxn *u)
168
-{
169
-	size_t i;
170
-	char *cptr = (char *)u;
171
-	for(i = 0; i < sizeof u; i++)
172
-		cptr[i] = 0;
173
-}
174
-
175 181
 int
176
-boot(Uxn *u)
182
+bootuxn(Uxn *u)
177 183
 {
178
-	reset(u);
184
+	inituxn(u);
179 185
 	u->vreset = mempeek16(u, 0xfffa);
180 186
 	u->vframe = mempeek16(u, 0xfffc);
181 187
 	u->verror = mempeek16(u, 0xfffe);
182
-	/* eval reset */
183
-	u->ram.ptr = u->vreset;
184
-	setflag(&u->status, FLAG_HALT, 0);
185
-	while(!(u->status & FLAG_HALT) && eval(u))
186
-		u->counter++;
187
-	/* eval frame */
188
-	u->ram.ptr = u->vframe;
189
-	setflag(&u->status, FLAG_HALT, 0);
190
-	while(!(u->status & FLAG_HALT) && eval(u))
191
-		u->counter++;
188
+	printf("Uxn Ready.\n");
192 189
 	return 1;
193 190
 }
191
+
192
+/* to start: evaluxn(u, u->vreset); */
... ...
@@ -44,6 +44,6 @@ typedef struct {
44 44
 
45 45
 void setflag(Uint8 *status, char flag, int b);
46 46
 int getflag(Uint8 *status, char flag);
47
-int error(Uxn *c, char *name, int id);
48
-int load(Uxn *c, char *filepath);
49
-int boot(Uxn *c);
47
+int loaduxn(Uxn *c, char *filepath);
48
+int bootuxn(Uxn *c);
49
+int evaluxn(Uxn *u, Uint16 vec);
50 50
\ No newline at end of file