Browse Source

initial SDL2 port

master
asie 5 months ago
parent
commit
9602ac5aed
10 changed files with 295 additions and 24 deletions
  1. 3
    0
      .gitignore
  2. BIN
      res/8x14.bin
  3. 2
    2
      src/emscripten_glue.js
  4. 13
    4
      src/frontend_curses.c
  5. 252
    0
      src/frontend_sdl.c
  6. 6
    12
      src/posix_vfs.c
  7. 10
    3
      src/zzt.c
  8. 4
    2
      src/zzt.h
  9. 1
    1
      zeta_curses.sh
  10. 4
    0
      zeta_sdl.sh

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
1
+build
2
+res/*.c
3
+res/*.h

BIN
res/8x14.bin View File


+ 2
- 2
src/emscripten_glue.js View File

@@ -2,7 +2,7 @@ mergeInto(LibraryManager.library, {
2 2
 	cpu_ext_log: function(s) {
3 3
 		console.log(Pointer_stringify(s));
4 4
 	},
5
-	vfs_time_ms: function() {
5
+	zeta_time_ms: function() {
6 6
 		return vfsg_time_ms();
7 7
 	},
8 8
 	vfs_open: function(fn, mode) {
@@ -26,7 +26,7 @@ mergeInto(LibraryManager.library, {
26 26
 	vfs_findnext: function(ptr) {
27 27
 		return vfsg_findnext(ptr);
28 28
 	},
29
-	vfs_has_feature: function(id) {
29
+	zeta_has_feature: function(id) {
30 30
 		return vfsg_has_feature(id);
31 31
 	},
32 32
 	speaker_on: function(freq) {

src/curses_glue.c → src/frontend_curses.c View File

@@ -24,7 +24,16 @@
24 24
 #include <ncurses.h>
25 25
 #include "zzt.h"
26 26
 
27
-void init_posix_glue();
27
+long zeta_time_ms() {
28
+	clock_t c = clock();
29
+	return c / (CLOCKS_PER_SEC/1000);
30
+}
31
+
32
+void cpu_ext_log(const char* s) {
33
+	fprintf(stderr, "%s\n", s);
34
+}
35
+
36
+void init_posix_vfs(const char* path);
28 37
 
29 38
 void speaker_on(double freq) {}
30 39
 void speaker_off() {}
@@ -32,7 +41,7 @@ void speaker_off() {}
32 41
 static int map_char_to_key[512];
33 42
 static WINDOW* window;
34 43
 
35
-int vfs_has_feature(int feature) {
44
+int zeta_has_feature(int feature) {
36 45
 	return 1;
37 46
 }
38 47
 
@@ -89,8 +98,8 @@ static void init_map_char_to_key() {
89 98
 	map_char_to_key[32] = 57; // space
90 99
 }
91 100
 
92
-int main() {
93
-	init_posix_glue();
101
+int main(int argc, char** argv) {
102
+	init_posix_vfs("vfs/");
94 103
 	init_map_char_to_key();
95 104
 	zzt_init();
96 105
 

+ 252
- 0
src/frontend_sdl.c View File

@@ -0,0 +1,252 @@
1
+/**
2
+ * Copyright (c) 2018 Adrian Siekierka
3
+ *
4
+ * This file is part of Zeta.
5
+ *
6
+ * Zeta is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * Zeta is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with Zeta.  If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#include <stdio.h>
21
+#include <stdlib.h>
22
+#include <string.h>
23
+#include <SDL2/SDL.h>
24
+#include "zzt.h"
25
+
26
+static int def_palette[] = {
27
+	0x000000, 0x0000aa, 0x00aa00, 0x00aaaa,
28
+	0xaa0000, 0xaa00aa, 0xaa5500, 0xaaaaaa,
29
+	0x555555, 0x5555ff, 0x55ff55, 0x55ffff,
30
+	0xff5555, 0xff55ff, 0xffff55, 0xffffff
31
+};
32
+
33
+static const u8 sdl_to_pc_scancode[] = {
34
+/*  0*/	0,
35
+/*  1*/	0, 0, 0,
36
+/*  4*/	0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, /* A-I */
37
+/* 13*/	0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, /* J-R */
38
+/* 22*/	0x1F, 0x14, 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C,       /* S-Z */
39
+/* 30*/	2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* 1-0 */
40
+/* 40*/	0x1C, 0x01, 0x0E, 0x0F, 0x39,
41
+/* 45*/	0x0C, 0x0D, 0x1A, 0x1B, 0x2B,
42
+/* 50*/	0x2B, 0x27, 0x28, 0x29,
43
+/* 54*/	0x33, 0x34, 0x35, 0x3A,
44
+	0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58,
45
+	0x37, 0x46, 0, 0x52, 0x47, 0x49, 0x53, 0x4F, 0x51,
46
+	0x4D, 0x4B, 0x50, 0x48, 0x45
47
+};
48
+
49
+static const int sdl_to_pc_scancode_max = sizeof(sdl_to_pc_scancode) - 1;
50
+
51
+extern unsigned char res_8x14_bin[];
52
+
53
+static SDL_Texture *create_texture_from_array(SDL_Renderer *renderer, unsigned char *data, int height) {
54
+	SDL_Texture *texture;
55
+	SDL_Rect rect;
56
+	Uint32 texdata[8 * height];
57
+	Uint32* tptr;
58
+	int ch, cx, cy, ctmp;
59
+
60
+	rect.w = 8;
61
+	rect.h = height;
62
+	texture = SDL_CreateTexture(renderer,
63
+		SDL_PIXELFORMAT_RGBA32,
64
+		SDL_TEXTUREACCESS_STATIC,
65
+		16*rect.w, 16*rect.h);
66
+
67
+	for (ch = 0; ch < 256; ch++) {
68
+		rect.x = (ch & 0x0F) * rect.w;
69
+		rect.y = (ch >> 4) * rect.h;
70
+		tptr = texdata;
71
+		for (cy = 0; cy < height; cy++, data++) {
72
+			ctmp = data[0];
73
+			for (cx = 0; cx < 8; cx++, tptr++, ctmp <<= 1) {
74
+				*tptr = ((ctmp >> 7) & 1) * 0xFFFFFFFF;
75
+			}
76
+		}
77
+		SDL_UpdateTexture(texture, &rect, texdata, 32);
78
+	}
79
+
80
+	return texture;
81
+}
82
+
83
+long zeta_time_ms() {
84
+	return SDL_GetTicks();
85
+}
86
+
87
+void cpu_ext_log(const char *s) {
88
+	fprintf(stderr, "%s\n", s);
89
+}
90
+
91
+void init_posix_vfs(const char *path);
92
+
93
+void speaker_on(double freq) {}
94
+void speaker_off() {}
95
+
96
+int zeta_has_feature(int feature) {
97
+	return 1;
98
+}
99
+
100
+static SDL_mutex *zzt_thread_lock;
101
+static u8 zzt_vram_copy[80*25*2];
102
+static u8 zzt_thread_running;
103
+static u8 video_blink = 1;
104
+
105
+static int zzt_thread_func(void *ptr) {
106
+	while (zzt_thread_running) {
107
+		if (SDL_LockMutex(zzt_thread_lock) == 0) {
108
+			if (!zzt_execute(40000)) zzt_thread_running = 0;
109
+			SDL_UnlockMutex(zzt_thread_lock);
110
+		}
111
+		SDL_Delay(1);
112
+	}
113
+
114
+	return 0;
115
+}
116
+
117
+int main(int argc, char **argv) {
118
+	SDL_Window *window;
119
+	SDL_Renderer *renderer;
120
+	SDL_Rect rectSrc, rectDst;
121
+
122
+	SDL_Texture *chartex;
123
+	int charw, charh;
124
+
125
+	SDL_Event event;
126
+	int scode, kcode;
127
+
128
+	SDL_Thread* zzt_thread;
129
+
130
+	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
131
+		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed! %s", SDL_GetError());
132
+		return 1;
133
+	}
134
+
135
+	charw = 8;
136
+	charh = 14;
137
+
138
+	window = SDL_CreateWindow("Zeta", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
139
+		80*charw, 25*charh, 0);
140
+	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
141
+	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0);
142
+
143
+	chartex = create_texture_from_array(renderer, res_8x14_bin, charh);
144
+	rectSrc.w = rectDst.w = charw;
145
+	rectSrc.h = rectDst.h = charh;
146
+
147
+	SDL_SetTextureBlendMode(chartex, SDL_BLENDMODE_BLEND);
148
+
149
+	init_posix_vfs("");
150
+	zzt_init();
151
+
152
+	zzt_thread_lock = SDL_CreateMutex();
153
+	if (!zzt_thread_lock) {
154
+		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create ZZT thread mutex! %s", SDL_GetError());
155
+		return 1;
156
+	}
157
+
158
+	long last_timer_call = zeta_time_ms();
159
+	u8 cont_loop = 1;
160
+
161
+	zzt_thread_running = 1;
162
+	zzt_thread = SDL_CreateThread(zzt_thread_func, "ZZT Executor", (void*)NULL);
163
+	if (zzt_thread == NULL) {
164
+		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create ZZT thread! %s", SDL_GetError());
165
+		return 1;
166
+	}
167
+
168
+	while (cont_loop) {
169
+		if (SDL_LockMutex(zzt_thread_lock) != 0) {
170
+			SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not lock ZZT thread mutex! %s", SDL_GetError());
171
+			cont_loop = 0;
172
+			break;
173
+		}
174
+
175
+		u8* ram = zzt_get_ram();
176
+		memcpy(zzt_vram_copy, ram + 0xB8000, 80*25*2);
177
+		zzt_mark_frame();
178
+
179
+		while (SDL_PollEvent(&event)) {
180
+			switch (event.type) {
181
+				case SDL_KEYDOWN:
182
+					scode = event.key.keysym.scancode;
183
+					kcode = event.key.keysym.sym;
184
+					if (kcode < 0 || kcode >= 127) kcode = 0;
185
+					if (scode >= 0 && scode <= sdl_to_pc_scancode_max) {
186
+						zzt_key(kcode, sdl_to_pc_scancode[scode]);
187
+					}
188
+					break;
189
+				case SDL_KEYUP:
190
+					scode = event.key.keysym.scancode;
191
+					if (scode >= 0 && scode <= sdl_to_pc_scancode_max) {
192
+						zzt_keyup(sdl_to_pc_scancode[scode]);
193
+					}
194
+					break;
195
+				case SDL_QUIT:
196
+					cont_loop = 0;
197
+					break;
198
+			}
199
+		}
200
+
201
+		long curr_timer_call = zeta_time_ms();
202
+		if ((curr_timer_call - last_timer_call) >= 55) {
203
+			zzt_mark_timer();
204
+			last_timer_call = curr_timer_call;
205
+		}
206
+		SDL_UnlockMutex(zzt_thread_lock);
207
+
208
+		int vpos = 0;
209
+		for (int y = 0; y < 25; y++) {
210
+			for (int x = 0; x < 80; x++, vpos += 2) {
211
+				u8 chr = zzt_vram_copy[vpos];
212
+				u8 col = zzt_vram_copy[vpos + 1];
213
+				rectSrc.x = (chr & 0xF)*charw;
214
+				rectSrc.y = (chr >> 4)*charh;
215
+				rectDst.x = x*charw;
216
+				rectDst.y = y*charh;
217
+
218
+				if (video_blink && col >= 0x80) {
219
+					col &= 0x7f;
220
+					if ((curr_timer_call % 466) >= 233) {
221
+						col = (col >> 4) * 0x11;
222
+					}
223
+				}
224
+
225
+				u8 render_fg = ((col >> 4) ^ (col & 0xF));
226
+
227
+				SDL_SetRenderDrawColor(renderer,
228
+					(def_palette[col >> 4] >> 16) & 0xFF,
229
+					(def_palette[col >> 4] >> 8) & 0xFF,
230
+					(def_palette[col >> 4] >> 0) & 0xFF,
231
+					255);
232
+
233
+				SDL_RenderFillRect(renderer, &rectDst);
234
+
235
+				if (render_fg) {
236
+					SDL_SetTextureColorMod(chartex,
237
+						(def_palette[col & 0xF] >> 16) & 0xFF,
238
+						(def_palette[col & 0xF] >> 8) & 0xFF,
239
+						(def_palette[col & 0xF] >> 0) & 0xFF);
240
+					SDL_RenderCopy(renderer, chartex, &rectSrc, &rectDst);
241
+				}
242
+			}
243
+		}
244
+
245
+		SDL_RenderPresent(renderer);
246
+	}
247
+
248
+	zzt_thread_running = 0;
249
+
250
+	SDL_DestroyRenderer(renderer);
251
+	SDL_Quit();
252
+}

src/posix_glue.c → src/posix_vfs.c View File

@@ -26,7 +26,7 @@
26 26
 
27 27
 long vfs_time_ms() {
28 28
 	clock_t c = clock();
29
-	return c / 1000;
29
+	return c / (CLOCKS_PER_SEC/1000);
30 30
 }
31 31
 
32 32
 #define MAX_FNLEN 259
@@ -38,14 +38,12 @@ static int vfs_fnprefsize;
38 38
 int vfs_findfirst(u8* ptr, u16 mask, char* spec) { return -1; }
39 39
 int vfs_findnext(u8* ptr) { return -1; }
40 40
 
41
-void init_posix_glue() {
42
-	vfs_fnbuf[0] = 'v';
43
-	vfs_fnbuf[1] = 'f';
44
-	vfs_fnbuf[2] = 's';
45
-	vfs_fnbuf[3] = '/';
46
-	vfs_fnprefsize = 4;
47
-	for (int i = 0; i < MAX_FILES; i++)
41
+void init_posix_vfs(const char* path) {
42
+	strncpy(vfs_fnbuf, path, MAX_FNLEN);
43
+	vfs_fnprefsize = strlen(vfs_fnbuf);
44
+	for (int i = 0; i < MAX_FILES; i++) {
48 45
 		file_pointers[i] = NULL;
46
+	}
49 47
 }
50 48
 
51 49
 int vfs_open(const char* filename, int mode) {
@@ -99,7 +97,3 @@ int vfs_close(int handle) {
99 97
 	FILE* fptr = file_pointers[handle-1];
100 98
 	return fclose(fptr);
101 99
 }
102
-
103
-void cpu_ext_log(const char* s) {
104
-	fprintf(stderr, "%s\n", s);
105
-}

+ 10
- 3
src/zzt.c View File

@@ -68,6 +68,13 @@ void zzt_key(int c, int k) {
68 68
 	fprintf(stderr, "kbget %d %d\n", zzt.qch, zzt.qke);
69 69
 }
70 70
 
71
+void zzt_keyup(int k) {
72
+	if (zzt.qke == k) {
73
+		zzt.qch = -1;
74
+		zzt.qke = -1;
75
+	}
76
+}
77
+
71 78
 static void cpu_func_intr_0x10(cpu_state* cpu);
72 79
 static void cpu_func_intr_0x13(cpu_state* cpu);
73 80
 static void cpu_func_intr_0x16(cpu_state* cpu);
@@ -139,7 +146,7 @@ static u16 cpu_func_port_in_main(cpu_state* cpu, u16 addr) {
139 146
 		case 0x61:
140 147
 			return zzt->port_61;
141 148
 		case 0x201:
142
-			if (!vfs_has_feature(FEATURE_JOY_CONNECTED))
149
+			if (!zeta_has_feature(FEATURE_JOY_CONNECTED))
143 150
 				return 0xF0;
144 151
 			zzt->port_201 &= 0xF0;
145 152
 			if (zzt->joy_xstrobes > 0) {
@@ -203,7 +210,7 @@ static void cpu_func_intr_0x33(cpu_state* cpu) {
203 210
 
204 211
 	switch (cpu->ax) {
205 212
 		case 0:
206
-			if (vfs_has_feature(FEATURE_MOUSE_CONNECTED)) {
213
+			if (zeta_has_feature(FEATURE_MOUSE_CONNECTED)) {
207 214
 				cpu->ax = 0xFFFF;
208 215
 				cpu->bx = 0xFFFF;
209 216
 			}
@@ -424,7 +431,7 @@ static void cpu_func_intr_0x21(cpu_state* cpu) {
424 431
 			cpu->ram[cpu->al * 4 + 3] = cpu->seg[SEG_DS] >> 8;
425 432
 			return;
426 433
 		case 0x2C: { // systime
427
-			long ms = vfs_time_ms();
434
+			long ms = zeta_time_ms();
428 435
 			cpu->ch = (ms / 3600000) % 24;
429 436
 			cpu->cl = (ms / 60000) % 60;
430 437
 			cpu->dh = (ms / 1000) % 60;

+ 4
- 2
src/zzt.h View File

@@ -39,6 +39,8 @@ int zzt_video_mode(void);
39 39
 USER_FUNCTION
40 40
 void zzt_key(int ch, int key);
41 41
 USER_FUNCTION
42
+void zzt_keyup(int key);
43
+USER_FUNCTION
42 44
 void zzt_kmod_set(int mod);
43 45
 USER_FUNCTION
44 46
 void zzt_kmod_clear(int mod);
@@ -66,7 +68,7 @@ USER_FUNCTION
66 68
 void zzt_mark_timer(void);
67 69
 
68 70
 IMPLEMENT_FUNCTION
69
-long vfs_time_ms(void);
71
+long zeta_time_ms(void);
70 72
 
71 73
 #define VFS_SEEK_SET 0
72 74
 #define VFS_SEEK_CUR 1
@@ -94,7 +96,7 @@ int vfs_findnext(u8* ptr);
94 96
 #define FEATURE_JOY_CONNECTED 1
95 97
 #define FEATURE_MOUSE_CONNECTED 2
96 98
 IMPLEMENT_FUNCTION
97
-int vfs_has_feature(int feature);
99
+int zeta_has_feature(int feature);
98 100
 
99 101
 IMPLEMENT_FUNCTION
100 102
 void speaker_on(double freq);

+ 1
- 1
zeta_curses.sh View File

@@ -1,3 +1,3 @@
1 1
 #!/bin/sh
2 2
 gcc -o build/zeta86 -g -O3 -std=c11 -Wall -lncurses \
3
-  src/curses_glue.c src/posix_glue.c src/zzt.c src/cpu.c
3
+  src/frontend_curses.c src/posix_vfs.c src/zzt.c src/cpu.c

+ 4
- 0
zeta_sdl.sh View File

@@ -0,0 +1,4 @@
1
+#!/bin/sh
2
+xxd -i res/8x14.bin > res/8x14.c
3
+gcc -o build/zeta86 -g -O3 -std=c11 -Wall -lSDL2 \
4
+  res/8x14.c src/posix_vfs.c src/frontend_sdl.c src/zzt.c src/cpu.c

Loading…
Cancel
Save