CHIP-8 c# - brak danych

0

Witam, to mój pierwszy post, więc proszę o wyrozumiałość. Piszę emulator chip-8 w c#, ale mam problem, gdyż mój program na ekranie nie zwraca nic (cała tablica LCD jest równa 0). Nie wiem co jest tego powodem, ale podejrzewam, że ma to coś wspólnego z wczytaniem pliku. Wrzuciłem cały kod, więc jest dosyć długi. Z góry dziękuje za pomoc.

chip8.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace testconbil
{
    class chip8
    {
        int[] pamiec;
        int[] V; // Flagi
        int I; // Indeks rejestrow
        int pc; // Licznik Programu {PROGRAM COUNTER}

        int[] stos;
        int wskaznikStosu;

        int licznik_Glowny;
        int licznik_Dzwieku;

        char[] klawisze;

        public int[] LCD;
        public bool FlagaRysowania;

        public chip8()
        {
            try
            {
                pamiec = new int[4096];
                V = new int[16];
                I = 0x0;
                stos = new int[16];
                wskaznikStosu = 0;
                licznik_Dzwieku = 0;
                licznik_Glowny = 0;
                klawisze = new char[16];
                LCD = new int[2048];
                pc = 0x200;
                FlagaRysowania = true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("Krytyczny blad inicjalizacji.");
            }
        }

        public void Wykonaj()
        {
            int opcode = (pamiec[pc] << 8) | pamiec[pc + 1];

            switch (opcode & 0xF000)
            {
                case 0x0000:
                    switch (opcode & 0x000F)
                    {
                        case 0x0000:
                            for (int i = 0; i < 2048; ++i)
                                LCD[i] = 0x0;
                            FlagaRysowania = true;
                            pc += 2;
                            break;
                        case 0x000E:
                            wskaznikStosu--;
                            pc = stos[wskaznikStosu];
                            pc += 2;
                            break;
                        default:
                            System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
                            Environment.Exit(-1);
                            break;
                    }
                    break;
                case 0x1000:
                    pc = opcode & 0x0FFF;
                    break;
                case 0x2000:
                    stos[wskaznikStosu] = pc;
                    wskaznikStosu++;
                    pc = opcode & 0x0FFF;
                    break;
                case 0x3000:
                    if (V[(opcode & 0x0F00) >> 8] == (opcode & 0x00FF))
                        pc += 4;
                    else
                        pc += 2;
                    break;
                case 0x4000:
                    if (V[(opcode & 0x0F00) >> 8] != (opcode & 0x00FF))
                        pc += 4;
                    else
                        pc += 2;
                    break;
                case 0x5000:
                    if (V[(opcode & 0x0F00) >> 8] == V[(opcode & 0x00F0) >> 4])
                        pc += 4;
                    else
                        pc += 2;
                    break;
                case 0x6000:
                    V[(opcode & 0x0F00) >> 8] = opcode & 0x00FF;
                    pc += 2;
                    break;
                case 0x7000:
                    V[(opcode & 0x0F00) >> 8] += opcode & 0x00FF;
                    pc += 2;
                    break;
                case 0x8000:
                    switch (opcode & 0x000F)
                    {
                        case 0x0000:
                            V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0001:
                            V[(opcode & 0x0F00) >> 8] |= V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0002:
                            V[(opcode & 0x0F00) >> 8] &= V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0003:
                            V[(opcode & 0x0F00) >> 8] ^= V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0004:
                            if (V[(opcode & 0x00F0) >> 4] > (0xFF - V[(opcode & 0x0F00) >> 8]))
                                V[0xF] = 1;
                            else
                                V[0xF] = 0;
                            V[(opcode & 0x0F00) >> 8] += V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0005:
                            if (V[(opcode & 0x00F0) >> 4] > V[(opcode & 0x0F00) >> 8])
                                V[0xF] = 0;
                            else
                                V[0xF] = 1;
                            V[(opcode & 0x0F00) >> 8] -= V[(opcode & 0x00F0) >> 4];
                            pc += 2;
                            break;
                        case 0x0006:
                            V[0xF] = V[(opcode & 0x0F00) >> 8] & 0x1;
                            V[(opcode & 0x0F00) >> 8] >>= 1;
                            pc += 2;
                            break;
                        case 0x0007:
                            if (V[(opcode & 0x0F00) >> 8] > V[(opcode & 0x00F0) >> 4])	// VY-VX
                                V[0xF] = 0;
                            else
                                V[0xF] = 1;
                            V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4] - V[(opcode & 0x0F00) >> 8];
                            pc += 2;
                            break;
                        case 0x000E:
                            V[0xF] = V[(opcode & 0x0F00) >> 8] >> 7;
                            V[(opcode & 0x0F00) >> 8] <<= 1;
                            pc += 2;
                            break;
                        default:
                            System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
                            Environment.Exit(-1);
                            break;
                    }
                    break;
                case 0x9000:
                    if (V[(opcode & 0x0F00) >> 8] != V[(opcode & 0x00F0) >> 4])
                        pc += 4;
                    else
                        pc += 2;
                    break;
                case 0xA000:
                    I = opcode & 0x0FFF;
                    pc += 2;
                    break;
                case 0xB000:
                    pc = (opcode & 0x0FFF) + V[0];
                    break;
                case 0xC000:
                    Random los = new Random();
                    V[(opcode & 0x0F00) >> 8] = (los.Next(0, 0xFF)) & (opcode & 0x00FF);
                    pc += 2;
                    break;
                case 0xD000:
                    {
                        int x = V[(opcode & 0x0F00) >> 8];
                        int y = V[(opcode & 0x00F0) >> 4];
                        int height = opcode & 0x000F;
                        int pixel;
                        V[0xF] = 0;
                        for (int yline = 0; yline < height; yline++)
                        {
                            pixel = pamiec[I + yline];
                            for (int xline = 0; xline < 8; xline++)
                            {
                                if ((pixel & (0x80 >> xline)) != 0)
                                {
                                    if (LCD[(x + xline + ((y + yline) * 64))] == 1)
                                    {
                                        V[0xF] = 1;
                                    }
                                    LCD[x + xline + ((y + yline) * 64)] ^= 1;
                                }
                            }
                        }
                        FlagaRysowania = true;
                        pc += 2;
                    }
                    break;
                case 0xF000:
                    switch (opcode & 0x00FF)
                    {
                        case 0x0007:
                            V[(opcode & 0x0F00) >> 8] = licznik_Glowny;
                            pc += 2;
                            break;

                        case 0x000A:		
                            {
                                bool keyPress = false;

                                for (int i = 0; i < 16; ++i)
                                {
                                    if (klawisze[i] != 0)
                                    {
                                        V[(opcode & 0x0F00) >> 8] = i;
                                        keyPress = true;
                                    }
                                }

                                if (!keyPress)
                                    return;

                                pc += 2;
                            }
                            break;

                        case 0x0015:
                            licznik_Glowny = V[(opcode & 0x0F00) >> 8];
                            pc += 2;
                            break;

                        case 0x0018:
                            licznik_Dzwieku = V[(opcode & 0x0F00) >> 8];
                            pc += 2;
                            break;

                        case 0x001E:
                            if (I + V[(opcode & 0x0F00) >> 8] > 0xFFF)
                                V[0xF] = 1;
                            else
                                V[0xF] = 0;
                            I += V[(opcode & 0x0F00) >> 8];
                            pc += 2;
                            break;

                        case 0x0029:
                            I = V[(opcode & 0x0F00) >> 8] * 0x5;
                            pc += 2;
                            break;

                        case 0x0033:
                            pamiec[I] = V[(opcode & 0x0F00) >> 8] / 100;
                            pamiec[I + 1] = (V[(opcode & 0x0F00) >> 8] / 10) % 10;
                            pamiec[I + 2] = (V[(opcode & 0x0F00) >> 8] % 100) % 10;
                            pc += 2;
                            break;

                        case 0x0055:				
                            for (int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i)
                                pamiec[I + i] = V[i];

                            I += ((opcode & 0x0F00) >> 8) + 1;
                            pc += 2;
                            break;

                        case 0x0065:				
                            for (int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i)
                                V[i] = pamiec[I + i];
                            I += ((opcode & 0x0F00) >> 8) + 1;
                            pc += 2;
                            break;
                        default:
                            System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
                            Environment.Exit(-1);
                            break;
                    }
                    break;
                default:
                    System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
                    Environment.Exit(-1);
                    break;
            }

            if (licznik_Glowny > 0)
                licznik_Glowny--;
            if (licznik_Dzwieku > 0)
            {
                if (licznik_Dzwieku == 1)
                    Console.Beep();
                licznik_Dzwieku--;
            }
        }


        public void WczytajAplikacje()
        {  
            OpenFileDialog ROM = new OpenFileDialog();
            ROM.Filter = "CHIP 8|*.c8";
            System.Windows.Forms.MessageBox.Show("Wybierz aplikacje do wczytania.");
            if (ROM.ShowDialog() == DialogResult.OK)
            {
                StreamReader pliczek = new StreamReader(ROM.FileName);
                string buforPliku = pliczek.ReadToEnd();
                for (int i = 0; i < buforPliku.Length; i++)
                {
                    pamiec[i] = buforPliku[i];
                }
                pliczek.Close();
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Aplikacja nie zostala wybrana.");
                System.Windows.Forms.MessageBox.Show("Emulator nie moze kontynuowac swojego dzialania.");
                Environment.Exit(-1);
            }
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testconbil
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            chip8 a = new chip8();
            a.WczytajAplikacje();
            while (true)
            {
                a.Wykonaj();
                if (a.FlagaRysowania == true)
                {
                    System.Threading.Thread.Sleep(500);
                    Console.Clear();
                    for (int y = 0; y < 32; ++y)
                    {
                        for (int x = 0; x < 64; ++x)
                        {
                            if (a.LCD[(y * 64) + x] == 0)
                                Console.Write(" ");
                            else
                                Console.Write("O");
                        }
                        Console.WriteLine();
                    }
                    Console.WriteLine();
                    a.FlagaRysowania = false;
                }
                else
                {
                }
            }
        }
    }
}
0
StreamReader pliczek = new StreamReader(ROM.FileName);
string buforPliku = pliczek.ReadToEnd();

Ładowanie do stringa pliku (jak mniemam) binarnego to bardzo zły pomysł.

Użyj File.OpenRead do otwarcia pliku a potem metody Read.

0
public void WczytajAplikacje()
        {
            FileStream fs = File.Open("pong2.c8", FileMode.Open);
            byte[] b = new byte[4096];
            fs.Read(b, 0, b.Length);

            for (int i = 0; i < 2048; i++)
            {
                Console.WriteLine(BitConverter.ToInt32(b, i));
            }

            fs.Close();
        }

Ta zmiana nic nie dała.

0

A tego BitConverter.ToInt32 na pewno dobrze używasz? Przecież potrzeba czterech bajtów, żeby zrobić z nich jednego Int32, a Ty coś tam cudujesz.

Przykład odczytu binarnego całego pliku: http://www.csharp-examples.net/filestream-read-file/

0
bool chip8::loadApplication(const char * filename)
{
	init();
	printf("Loading: %s\n", filename);
		
	// Open file
	FILE * pFile = fopen(filename, "rb");
	if (pFile == NULL)
	{
		fputs ("File error", stderr); 
		return false;
	}

	// Check file size
	fseek(pFile , 0 , SEEK_END);
	long lSize = ftell(pFile);
	rewind(pFile);
	printf("Filesize: %d\n", (int)lSize);
	
	// Allocate memory to contain the whole file
	char * buffer = (char*)malloc(sizeof(char) * lSize);
	if (buffer == NULL) 
	{
		fputs ("Memory error", stderr); 
		return false;
	}

	// Copy the file into the buffer
	size_t result = fread (buffer, 1, lSize, pFile);
	if (result != lSize) 
	{
		fputs("Reading error",stderr); 
		return false;
	}

	// Copy buffer to Chip8 memory
	if((4096-512) > lSize)
	{
		for(int i = 0; i < lSize; ++i)
			memory[i + 512] = buffer[i];
	}
	else
		printf("Error: ROM too big for memory");
	
	// Close file, free buffer
	fclose(pFile);
	free(buffer);

	return true;
}

Odczyt z pliku w cpp. Przeczytałem to co napisał 'somekind', ale to mi wciąż nie pomogło. Pomoże mi to ktoś napisać w C#?

0

Ilubitowe są instrukcje? Jeśli 16-bitowe, to tablica powinna być typu ushort[].

Do czytania po dwa albo cztery bajty na raz wykorzystaj klasę BinaryReader.

0

Przeliczyłem swoje siły. Nie potrafię tego zrobić. Temat do zamknięcia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1