Subversion Repositories Shiroi

Rev

Rev 3 | Rev 5 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: main.c 4 2024-08-28 10:07:23Z nishi $ */
2
 
3
#include <stdio.h>
4
#include <stdbool.h>
5
#include <sys/stat.h>
6
#include <stdlib.h>
7
#include <string.h>
8
 
9
#include <raylib.h>
10
 
11
#include "shiroi.h"
12
 
13
shiroi_t shiroi;
14
 
15
void thread_start(void);
16
void thread_end(void);
17
 
18
int main(int argc, char** argv) {
19
	FILE* fconf = fopen("shiroi.ini", "r");
20
	if(fconf == NULL) {
21
		printf("Creating config.\n");
22
		fconf = fopen("shiroi.ini", "w");
23
		if(fconf == NULL) {
24
			fprintf(stderr, "Failed to create config\n");
25
			return 1;
26
		}
27
		fprintf(fconf, "slot1=video_mark_1\n");
28
		fprintf(fconf, "slot2=sound_mark_1\n");
29
		fprintf(fconf, "slot3=math_mark_1\n");
3 nishi 30
		fprintf(fconf, "slot4=text_mark_1\n");
1 nishi 31
		fprintf(fconf, "rom=shiroi.rom\n");
32
		fclose(fconf);
33
	}
34
 
35
	shiroi_init_cards(&shiroi);
36
 
37
	fconf = fopen("shiroi.ini", "r");
38
 
39
	struct stat s;
40
	stat("shiroi.ini", &s);
41
 
42
	char* ini = malloc(s.st_size + 1);
43
	fread(ini, s.st_size, 1, fconf);
44
 
45
	ini[s.st_size] = 0;
46
 
47
	fclose(fconf);
48
 
49
	int incr = 0;
50
	int i;
51
	for(i = 0;; i++) {
52
		if(ini[i] == 0 || ini[i] == '\n') {
53
			char oldc = ini[i];
54
			ini[i] = 0;
55
 
56
			char* line = ini + incr;
57
 
3 nishi 58
			if(strlen(line) != 0 && line[0] != '#') {
1 nishi 59
				int j;
60
				for(j = 0; line[j] != 0; j++) {
61
					if(line[j] == '=') {
62
						line[j] = 0;
63
						if(strcmp(line, "rom") == 0) {
64
							printf("ROM: %s\n", line + j + 1);
65
							if(stat(line + j + 1, &s) != 0) {
66
								fprintf(stderr, "ROM not found\n");
67
								free(ini);
68
								return 1;
69
							}
70
							printf("ROM size: %d\n", s.st_size);
71
							FILE* f = fopen(line + j + 1, "rb");
72
							fread(shiroi.ram, s.st_size, 1, f);
73
							fclose(f);
74
						} else if(line[0] == 's' && line[1] == 'l' && line[2] == 'o' && line[3] == 't') {
75
							int slot = atoi(line + 4);
76
							const char* n = "";
77
							int dev = -1;
78
							if(strcmp(line + j + 1, "video_mark_1") == 0) {
79
								dev = SHIROI_VIDEO_MARK_I;
80
								n = "Video Mark I";
81
							} else if(strcmp(line + j + 1, "sound_mark_1") == 0) {
82
								dev = SHIROI_SOUND_MARK_I;
83
								n = "Sound Mark I";
84
							} else if(strcmp(line + j + 1, "math_mark_1") == 0) {
85
								dev = SHIROI_MATH_MARK_I;
86
								n = "Math Mark I";
3 nishi 87
							} else if(strcmp(line + j + 1, "text_mark_1") == 0) {
88
								dev = SHIROI_TEXT_MARK_I;
89
								n = "Text Mark I";
1 nishi 90
							}
91
							if(dev == -1) {
92
								fprintf(stderr, "No such device called `%s' ; ignoring\n", line + j + 1);
93
							} else {
94
								shiroi_install(&shiroi, slot, dev);
95
								printf("Installed `%s' into slot %d\n", n, slot);
96
							}
97
						}
98
						break;
99
					}
100
				}
101
			}
102
 
103
			incr = i + 1;
104
			if(oldc == 0) break;
105
		}
106
	}
107
 
108
	free(ini);
109
 
110
	shiroi_init(&shiroi);
111
 
112
	double scx = 2;
113
	double scy = 2;
114
 
115
	shiroi_card_t* videocard = shiroi_get_video_card(&shiroi);
116
	shiroi_video_t* video = NULL;
117
	if(videocard != NULL) {
118
		video = videocard->videoptr;
119
	}
3 nishi 120
	shiroi_card_t* textcard = shiroi_get_text_card(&shiroi);
121
	shiroi_text_t* text = NULL;
122
	if(textcard != NULL) {
123
		text = textcard->textptr;
124
	}
1 nishi 125
 
126
	SetTraceLogLevel(LOG_NONE);
127
	if(video != NULL) {
128
		InitWindow(video->width * scx, video->height * scy, "Shiroi Emulator");
129
	} else {
130
		InitWindow(640, 480, "Shiroi Emulator");
131
	}
132
	InitAudioDevice();
133
	SetAudioStreamBufferSizeDefault(512);
134
	AudioStream as = LoadAudioStream(48000, 16, 1);
135
	SetAudioStreamCallback(as, shiroi.play_audio);
136
	SetTargetFPS(60);
137
	uint32_t* fb = NULL;
138
 
139
	if(video != NULL) {
140
		fb = malloc(sizeof(*fb) * video->width * video->height);
141
 
142
		int x, y;
143
		for(y = 0; y < video->height; y++) {
144
			for(x = 0; x < video->width; x++) {
145
				fb[y * video->width + x] = 0xffffff;
146
			}
147
		}
148
	}
149
 
150
	RenderTexture r;
151
	if(video != NULL) r = LoadRenderTexture(video->width, video->height);
152
	PlayAudioStream(as);
153
	thread_start();
154
	while(!WindowShouldClose()) {
155
		BeginDrawing();
156
 
157
		ClearBackground(BLACK);
158
 
3 nishi 159
		if(text != NULL) {
4 nishi 160
			/*
161
			 * / 1 2 3 4 5 6 7 8 9 10 11 12 13
162
			 * 1 1 2 3 4 5 6 7 8 9 0  -  =  
163
			 * 2 q w e r t y u i o p  [  ]  rt
164
			 * 3 a s d f g h j k l ;  '  \  cl
165
			 * 4 z x c v b n m , . /  sp
166
			 */
167
			int c = GetKeyPressed();
168
			if(c == 0){
169
				text->key = 0;
170
			}else if(KEY_ONE <= c && c <= KEY_NINE){
171
				text->key = (1 << 4) | (c - KEY_ONE + 1);
172
			}else if(c == KEY_ZERO){
173
				text->key = (1 << 4) | 10;
174
			}else if(c == KEY_MINUS){
175
				text->key = (1 << 4) | 11;
176
			}else if(c == KEY_EQUAL){
177
				text->key = (1 << 4) | 12;
178
			}else if(c == KEY_LEFT_BRACKET){
179
				text->key = (2 << 4) | 11;
180
			}else if(c == KEY_RIGHT_BRACKET){
181
				text->key = (2 << 4) | 12;
182
			}else if(c == KEY_ENTER){
183
				text->key = (2 << 4) | 13;
184
			}else if(c == KEY_SEMICOLON){
185
				text->key = (3 << 4) | 10;
186
			}else if(c == KEY_APOSTROPHE){
187
				text->key = (3 << 4) | 11;
188
			}else if(c == KEY_BACKSLASH){
189
				text->key = (3 << 4) | 12;
190
			}else if(c == KEY_LEFT_SHIFT || c == KEY_RIGHT_SHIFT){
191
				text->key = (3 << 4) | 13;
192
			}else if(c == KEY_COMMA){
193
				text->key = (4 << 4) | 8;
194
			}else if(c == KEY_PERIOD){
195
				text->key = (4 << 4) | 9;
196
			}else if(c == KEY_SLASH){
197
				text->key = (4 << 4) | 10;
198
			}else if(c == KEY_SPACE){
199
				text->key = (4 << 4) | 11;
200
			}else if(c == KEY_Q){
201
				text->key = (2 << 4) | 1;
202
			}else if(c == KEY_W){
203
				text->key = (2 << 4) | 2;
204
			}else if(c == KEY_E){
205
				text->key = (2 << 4) | 3;
206
			}else if(c == KEY_R){
207
				text->key = (2 << 4) | 4;
208
			}else if(c == KEY_T){
209
				text->key = (2 << 4) | 5;
210
			}else if(c == KEY_Y){
211
				text->key = (2 << 4) | 6;
212
			}else if(c == KEY_U){
213
				text->key = (2 << 4) | 7;
214
			}else if(c == KEY_I){
215
				text->key = (2 << 4) | 8;
216
			}else if(c == KEY_O){
217
				text->key = (2 << 4) | 9;
218
			}else if(c == KEY_P){
219
				text->key = (2 << 4) | 10;
220
			}else if(c == KEY_A){
221
				text->key = (3 << 4) | 1;
222
			}else if(c == KEY_S){
223
				text->key = (3 << 4) | 2;
224
			}else if(c == KEY_D){
225
				text->key = (3 << 4) | 3;
226
			}else if(c == KEY_F){
227
				text->key = (3 << 4) | 4;
228
			}else if(c == KEY_G){
229
				text->key = (3 << 4) | 5;
230
			}else if(c == KEY_H){
231
				text->key = (3 << 4) | 6;
232
			}else if(c == KEY_J){
233
				text->key = (3 << 4) | 7;
234
			}else if(c == KEY_K){
235
				text->key = (3 << 4) | 8;
236
			}else if(c == KEY_L){
237
				text->key = (3 << 4) | 9;
238
			}else if(c == KEY_Z){
239
				text->key = (4 << 4) | 1;
240
			}else if(c == KEY_X){
241
				text->key = (4 << 4) | 2;
242
			}else if(c == KEY_C){
243
				text->key = (4 << 4) | 3;
244
			}else if(c == KEY_V){
245
				text->key = (4 << 4) | 4;
246
			}else if(c == KEY_B){
247
				text->key = (4 << 4) | 5;
248
			}else if(c == KEY_N){
249
				text->key = (4 << 4) | 6;
250
			}else if(c == KEY_M){
251
				text->key = (4 << 4) | 7;
252
			}
3 nishi 253
		}
254
 
1 nishi 255
		if(video != NULL) {
256
			BeginTextureMode(r);
257
 
258
			int y, x;
259
			for(y = 0; y < video->height; y++) {
260
				for(x = 0; x < video->width; x++) {
261
					if(video->fb[y * video->width + x] != fb[y * TMS9918_PIXELS_X + x]) {
262
						uint32_t c = video->fb[y * video->width + x];
263
						// printf("%X\n", c);
264
						DrawPixel(x, y, (Color){(c >> 24) & 0xff, (c >> 16) & 0xff, (c >> 8) & 0xff, 0xff});
265
						fb[y * video->width + x] = c;
266
					}
267
				}
268
			}
269
 
270
			EndTextureMode();
271
 
272
			DrawTexturePro(r.texture, (Rectangle){0, 0, video->width, -video->height}, (Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, (Vector2){0, 0}, 0, WHITE);
273
		} else {
274
			DrawText("No Video", 0, 0, 20, WHITE);
275
		}
276
 
277
		EndDrawing();
278
	}
279
	CloseWindow();
280
	UnloadAudioStream(as);
281
	if(video != NULL) UnloadRenderTexture(r);
282
	shiroi.stop = true;
283
	thread_end();
284
}