Subversion Repositories Shiroi

Rev

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

/* $Id: main.c 4 2024-08-28 10:07:23Z nishi $ */

#include <stdio.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>

#include <raylib.h>

#include "shiroi.h"

shiroi_t shiroi;

void thread_start(void);
void thread_end(void);

int main(int argc, char** argv) {
        FILE* fconf = fopen("shiroi.ini", "r");
        if(fconf == NULL) {
                printf("Creating config.\n");
                fconf = fopen("shiroi.ini", "w");
                if(fconf == NULL) {
                        fprintf(stderr, "Failed to create config\n");
                        return 1;
                }
                fprintf(fconf, "slot1=video_mark_1\n");
                fprintf(fconf, "slot2=sound_mark_1\n");
                fprintf(fconf, "slot3=math_mark_1\n");
                fprintf(fconf, "slot4=text_mark_1\n");
                fprintf(fconf, "rom=shiroi.rom\n");
                fclose(fconf);
        }

        shiroi_init_cards(&shiroi);

        fconf = fopen("shiroi.ini", "r");

        struct stat s;
        stat("shiroi.ini", &s);

        char* ini = malloc(s.st_size + 1);
        fread(ini, s.st_size, 1, fconf);

        ini[s.st_size] = 0;

        fclose(fconf);

        int incr = 0;
        int i;
        for(i = 0;; i++) {
                if(ini[i] == 0 || ini[i] == '\n') {
                        char oldc = ini[i];
                        ini[i] = 0;

                        char* line = ini + incr;

                        if(strlen(line) != 0 && line[0] != '#') {
                                int j;
                                for(j = 0; line[j] != 0; j++) {
                                        if(line[j] == '=') {
                                                line[j] = 0;
                                                if(strcmp(line, "rom") == 0) {
                                                        printf("ROM: %s\n", line + j + 1);
                                                        if(stat(line + j + 1, &s) != 0) {
                                                                fprintf(stderr, "ROM not found\n");
                                                                free(ini);
                                                                return 1;
                                                        }
                                                        printf("ROM size: %d\n", s.st_size);
                                                        FILE* f = fopen(line + j + 1, "rb");
                                                        fread(shiroi.ram, s.st_size, 1, f);
                                                        fclose(f);
                                                } else if(line[0] == 's' && line[1] == 'l' && line[2] == 'o' && line[3] == 't') {
                                                        int slot = atoi(line + 4);
                                                        const char* n = "";
                                                        int dev = -1;
                                                        if(strcmp(line + j + 1, "video_mark_1") == 0) {
                                                                dev = SHIROI_VIDEO_MARK_I;
                                                                n = "Video Mark I";
                                                        } else if(strcmp(line + j + 1, "sound_mark_1") == 0) {
                                                                dev = SHIROI_SOUND_MARK_I;
                                                                n = "Sound Mark I";
                                                        } else if(strcmp(line + j + 1, "math_mark_1") == 0) {
                                                                dev = SHIROI_MATH_MARK_I;
                                                                n = "Math Mark I";
                                                        } else if(strcmp(line + j + 1, "text_mark_1") == 0) {
                                                                dev = SHIROI_TEXT_MARK_I;
                                                                n = "Text Mark I";
                                                        }
                                                        if(dev == -1) {
                                                                fprintf(stderr, "No such device called `%s' ; ignoring\n", line + j + 1);
                                                        } else {
                                                                shiroi_install(&shiroi, slot, dev);
                                                                printf("Installed `%s' into slot %d\n", n, slot);
                                                        }
                                                }
                                                break;
                                        }
                                }
                        }

                        incr = i + 1;
                        if(oldc == 0) break;
                }
        }

        free(ini);

        shiroi_init(&shiroi);

        double scx = 2;
        double scy = 2;

        shiroi_card_t* videocard = shiroi_get_video_card(&shiroi);
        shiroi_video_t* video = NULL;
        if(videocard != NULL) {
                video = videocard->videoptr;
        }
        shiroi_card_t* textcard = shiroi_get_text_card(&shiroi);
        shiroi_text_t* text = NULL;
        if(textcard != NULL) {
                text = textcard->textptr;
        }

        SetTraceLogLevel(LOG_NONE);
        if(video != NULL) {
                InitWindow(video->width * scx, video->height * scy, "Shiroi Emulator");
        } else {
                InitWindow(640, 480, "Shiroi Emulator");
        }
        InitAudioDevice();
        SetAudioStreamBufferSizeDefault(512);
        AudioStream as = LoadAudioStream(48000, 16, 1);
        SetAudioStreamCallback(as, shiroi.play_audio);
        SetTargetFPS(60);
        uint32_t* fb = NULL;

        if(video != NULL) {
                fb = malloc(sizeof(*fb) * video->width * video->height);

                int x, y;
                for(y = 0; y < video->height; y++) {
                        for(x = 0; x < video->width; x++) {
                                fb[y * video->width + x] = 0xffffff;
                        }
                }
        }

        RenderTexture r;
        if(video != NULL) r = LoadRenderTexture(video->width, video->height);
        PlayAudioStream(as);
        thread_start();
        while(!WindowShouldClose()) {
                BeginDrawing();

                ClearBackground(BLACK);

                if(text != NULL) {
                        /*
                         * / 1 2 3 4 5 6 7 8 9 10 11 12 13
                         * 1 1 2 3 4 5 6 7 8 9 0  -  =  
                         * 2 q w e r t y u i o p  [  ]  rt
                         * 3 a s d f g h j k l ;  '  \  cl
                         * 4 z x c v b n m , . /  sp
                         */
                        int c = GetKeyPressed();
                        if(c == 0){
                                text->key = 0;
                        }else if(KEY_ONE <= c && c <= KEY_NINE){
                                text->key = (1 << 4) | (c - KEY_ONE + 1);
                        }else if(c == KEY_ZERO){
                                text->key = (1 << 4) | 10;
                        }else if(c == KEY_MINUS){
                                text->key = (1 << 4) | 11;
                        }else if(c == KEY_EQUAL){
                                text->key = (1 << 4) | 12;
                        }else if(c == KEY_LEFT_BRACKET){
                                text->key = (2 << 4) | 11;
                        }else if(c == KEY_RIGHT_BRACKET){
                                text->key = (2 << 4) | 12;
                        }else if(c == KEY_ENTER){
                                text->key = (2 << 4) | 13;
                        }else if(c == KEY_SEMICOLON){
                                text->key = (3 << 4) | 10;
                        }else if(c == KEY_APOSTROPHE){
                                text->key = (3 << 4) | 11;
                        }else if(c == KEY_BACKSLASH){
                                text->key = (3 << 4) | 12;
                        }else if(c == KEY_LEFT_SHIFT || c == KEY_RIGHT_SHIFT){
                                text->key = (3 << 4) | 13;
                        }else if(c == KEY_COMMA){
                                text->key = (4 << 4) | 8;
                        }else if(c == KEY_PERIOD){
                                text->key = (4 << 4) | 9;
                        }else if(c == KEY_SLASH){
                                text->key = (4 << 4) | 10;
                        }else if(c == KEY_SPACE){
                                text->key = (4 << 4) | 11;
                        }else if(c == KEY_Q){
                                text->key = (2 << 4) | 1;
                        }else if(c == KEY_W){
                                text->key = (2 << 4) | 2;
                        }else if(c == KEY_E){
                                text->key = (2 << 4) | 3;
                        }else if(c == KEY_R){
                                text->key = (2 << 4) | 4;
                        }else if(c == KEY_T){
                                text->key = (2 << 4) | 5;
                        }else if(c == KEY_Y){
                                text->key = (2 << 4) | 6;
                        }else if(c == KEY_U){
                                text->key = (2 << 4) | 7;
                        }else if(c == KEY_I){
                                text->key = (2 << 4) | 8;
                        }else if(c == KEY_O){
                                text->key = (2 << 4) | 9;
                        }else if(c == KEY_P){
                                text->key = (2 << 4) | 10;
                        }else if(c == KEY_A){
                                text->key = (3 << 4) | 1;
                        }else if(c == KEY_S){
                                text->key = (3 << 4) | 2;
                        }else if(c == KEY_D){
                                text->key = (3 << 4) | 3;
                        }else if(c == KEY_F){
                                text->key = (3 << 4) | 4;
                        }else if(c == KEY_G){
                                text->key = (3 << 4) | 5;
                        }else if(c == KEY_H){
                                text->key = (3 << 4) | 6;
                        }else if(c == KEY_J){
                                text->key = (3 << 4) | 7;
                        }else if(c == KEY_K){
                                text->key = (3 << 4) | 8;
                        }else if(c == KEY_L){
                                text->key = (3 << 4) | 9;
                        }else if(c == KEY_Z){
                                text->key = (4 << 4) | 1;
                        }else if(c == KEY_X){
                                text->key = (4 << 4) | 2;
                        }else if(c == KEY_C){
                                text->key = (4 << 4) | 3;
                        }else if(c == KEY_V){
                                text->key = (4 << 4) | 4;
                        }else if(c == KEY_B){
                                text->key = (4 << 4) | 5;
                        }else if(c == KEY_N){
                                text->key = (4 << 4) | 6;
                        }else if(c == KEY_M){
                                text->key = (4 << 4) | 7;
                        }
                }

                if(video != NULL) {
                        BeginTextureMode(r);

                        int y, x;
                        for(y = 0; y < video->height; y++) {
                                for(x = 0; x < video->width; x++) {
                                        if(video->fb[y * video->width + x] != fb[y * TMS9918_PIXELS_X + x]) {
                                                uint32_t c = video->fb[y * video->width + x];
                                                // printf("%X\n", c);
                                                DrawPixel(x, y, (Color){(c >> 24) & 0xff, (c >> 16) & 0xff, (c >> 8) & 0xff, 0xff});
                                                fb[y * video->width + x] = c;
                                        }
                                }
                        }

                        EndTextureMode();

                        DrawTexturePro(r.texture, (Rectangle){0, 0, video->width, -video->height}, (Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, (Vector2){0, 0}, 0, WHITE);
                } else {
                        DrawText("No Video", 0, 0, 20, WHITE);
                }

                EndDrawing();
        }
        CloseWindow();
        UnloadAudioStream(as);
        if(video != NULL) UnloadRenderTexture(r);
        shiroi.stop = true;
        thread_end();
}