Subversion Repositories Shiroi

Rev

Rev 3 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: main.c 1 2024-08-28 08:10:28Z 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");
30
		fprintf(fconf, "rom=shiroi.rom\n");
31
		fclose(fconf);
32
	}
33
 
34
	shiroi_init_cards(&shiroi);
35
 
36
	fconf = fopen("shiroi.ini", "r");
37
 
38
	struct stat s;
39
	stat("shiroi.ini", &s);
40
 
41
	char* ini = malloc(s.st_size + 1);
42
	fread(ini, s.st_size, 1, fconf);
43
 
44
	ini[s.st_size] = 0;
45
 
46
	fclose(fconf);
47
 
48
	int incr = 0;
49
	int i;
50
	for(i = 0;; i++) {
51
		if(ini[i] == 0 || ini[i] == '\n') {
52
			char oldc = ini[i];
53
			ini[i] = 0;
54
 
55
			char* line = ini + incr;
56
 
57
			if(strlen(line) != 0) {
58
				int j;
59
				for(j = 0; line[j] != 0; j++) {
60
					if(line[j] == '=') {
61
						line[j] = 0;
62
						if(strcmp(line, "rom") == 0) {
63
							printf("ROM: %s\n", line + j + 1);
64
							if(stat(line + j + 1, &s) != 0) {
65
								fprintf(stderr, "ROM not found\n");
66
								free(ini);
67
								return 1;
68
							}
69
							printf("ROM size: %d\n", s.st_size);
70
							FILE* f = fopen(line + j + 1, "rb");
71
							fread(shiroi.ram, s.st_size, 1, f);
72
							fclose(f);
73
						} else if(line[0] == 's' && line[1] == 'l' && line[2] == 'o' && line[3] == 't') {
74
							int slot = atoi(line + 4);
75
							const char* n = "";
76
							int dev = -1;
77
							if(strcmp(line + j + 1, "video_mark_1") == 0) {
78
								dev = SHIROI_VIDEO_MARK_I;
79
								n = "Video Mark I";
80
							} else if(strcmp(line + j + 1, "sound_mark_1") == 0) {
81
								dev = SHIROI_SOUND_MARK_I;
82
								n = "Sound Mark I";
83
							} else if(strcmp(line + j + 1, "math_mark_1") == 0) {
84
								dev = SHIROI_MATH_MARK_I;
85
								n = "Math Mark I";
86
							}
87
							if(dev == -1) {
88
								fprintf(stderr, "No such device called `%s' ; ignoring\n", line + j + 1);
89
							} else {
90
								shiroi_install(&shiroi, slot, dev);
91
								printf("Installed `%s' into slot %d\n", n, slot);
92
							}
93
						}
94
						break;
95
					}
96
				}
97
			}
98
 
99
			incr = i + 1;
100
			if(oldc == 0) break;
101
		}
102
	}
103
 
104
	free(ini);
105
 
106
	shiroi_init(&shiroi);
107
 
108
	double scx = 2;
109
	double scy = 2;
110
 
111
	shiroi_card_t* videocard = shiroi_get_video_card(&shiroi);
112
	shiroi_video_t* video = NULL;
113
	if(videocard != NULL) {
114
		video = videocard->videoptr;
115
	}
116
 
117
	SetTraceLogLevel(LOG_NONE);
118
	if(video != NULL) {
119
		InitWindow(video->width * scx, video->height * scy, "Shiroi Emulator");
120
	} else {
121
		InitWindow(640, 480, "Shiroi Emulator");
122
	}
123
	InitAudioDevice();
124
	SetAudioStreamBufferSizeDefault(512);
125
	AudioStream as = LoadAudioStream(48000, 16, 1);
126
	SetAudioStreamCallback(as, shiroi.play_audio);
127
	SetTargetFPS(60);
128
	uint32_t* fb = NULL;
129
 
130
	if(video != NULL) {
131
		fb = malloc(sizeof(*fb) * video->width * video->height);
132
 
133
		int x, y;
134
		for(y = 0; y < video->height; y++) {
135
			for(x = 0; x < video->width; x++) {
136
				fb[y * video->width + x] = 0xffffff;
137
			}
138
		}
139
	}
140
 
141
	RenderTexture r;
142
	if(video != NULL) r = LoadRenderTexture(video->width, video->height);
143
	PlayAudioStream(as);
144
	thread_start();
145
	while(!WindowShouldClose()) {
146
		BeginDrawing();
147
 
148
		ClearBackground(BLACK);
149
 
150
		if(video != NULL) {
151
			BeginTextureMode(r);
152
 
153
			int y, x;
154
			for(y = 0; y < video->height; y++) {
155
				for(x = 0; x < video->width; x++) {
156
					if(video->fb[y * video->width + x] != fb[y * TMS9918_PIXELS_X + x]) {
157
						uint32_t c = video->fb[y * video->width + x];
158
						// printf("%X\n", c);
159
						DrawPixel(x, y, (Color){(c >> 24) & 0xff, (c >> 16) & 0xff, (c >> 8) & 0xff, 0xff});
160
						fb[y * video->width + x] = c;
161
					}
162
				}
163
			}
164
 
165
			EndTextureMode();
166
 
167
			DrawTexturePro(r.texture, (Rectangle){0, 0, video->width, -video->height}, (Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, (Vector2){0, 0}, 0, WHITE);
168
		} else {
169
			DrawText("No Video", 0, 0, 20, WHITE);
170
		}
171
 
172
		EndDrawing();
173
	}
174
	CloseWindow();
175
	UnloadAudioStream(as);
176
	if(video != NULL) UnloadRenderTexture(r);
177
	shiroi.stop = true;
178
	thread_end();
179
}