Subversion Repositories Shiroi

Rev

Rev 1 | Rev 4 | 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 3 2024-08-28 09:19:04Z 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) {
160
			text->key = GetCharPressed();
161
		}
162
 
1 nishi 163
		if(video != NULL) {
164
			BeginTextureMode(r);
165
 
166
			int y, x;
167
			for(y = 0; y < video->height; y++) {
168
				for(x = 0; x < video->width; x++) {
169
					if(video->fb[y * video->width + x] != fb[y * TMS9918_PIXELS_X + x]) {
170
						uint32_t c = video->fb[y * video->width + x];
171
						// printf("%X\n", c);
172
						DrawPixel(x, y, (Color){(c >> 24) & 0xff, (c >> 16) & 0xff, (c >> 8) & 0xff, 0xff});
173
						fb[y * video->width + x] = c;
174
					}
175
				}
176
			}
177
 
178
			EndTextureMode();
179
 
180
			DrawTexturePro(r.texture, (Rectangle){0, 0, video->width, -video->height}, (Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, (Vector2){0, 0}, 0, WHITE);
181
		} else {
182
			DrawText("No Video", 0, 0, 20, WHITE);
183
		}
184
 
185
		EndDrawing();
186
	}
187
	CloseWindow();
188
	UnloadAudioStream(as);
189
	if(video != NULL) UnloadRenderTexture(r);
190
	shiroi.stop = true;
191
	thread_end();
192
}