aboutsummaryrefslogblamecommitdiff
path: root/src/main.rs
blob: 2ec5601944a31c8372cf854e5705e19a6a58096a (plain) (tree)
1
2
3
4
5
6
7
8
9

                  
            


              


                  
                                      

                                

                                   




                        

                            
 
                    
                                   

 
                                  

                                                               

                      










                                              

                                                

                                               





                                                           
                                                 
                                                                                        








                                                               
                                         


                                                                    
         
     











                                                                                             

 









                                                                                   


                                
                                       




                                                                          


                                                                       



                                                  








                                                                           
                         
                                                         
















                       
           





































                                                                         
      





                                              
      
                                                                  
      





                                              
      








                                                                         
                    



                                                                        
          



                                                    

                                                       
             
                     













                                                                                                


                           
 
extern crate core;
mod memory;
mod mos6502;
mod ppu;
mod cartridge;
mod mapper;

use std::fs::File;
use std::io::Read;
use core::cell::{RefCell, UnsafeCell};
use core::intrinsics::transmute;
use cartridge::*;
use std::time::{Instant, Duration};
use std::thread::sleep;

extern crate sdl2;

use sdl2::pixels::Color;
use sdl2::rect::Rect;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

struct DummyWindow {
    buff: RefCell<[[u8; 240]; 256]>
}

impl ppu::Screen for DummyWindow {
    fn put(&self, x: u8, y: u8, color: u8) {
        self.buff.borrow_mut()[y as usize][x as usize] = color;
    }
    fn render(&self) {
        println!("a frame has been redrawn:");
        for r in self.buff.borrow().iter() {
            for c in r.iter() {
                print!("{:02x}", c);
            }
            println!("");
        }
    }
}

struct SDLWindow {
    canvas: RefCell<sdl2::render::WindowCanvas>,
    events: RefCell<sdl2::EventPump>,
    timer: RefCell<sdl2::TimerSubsystem>,
    frame_buffer: UnsafeCell<[[u8; 240]; 256]>,
}

impl SDLWindow {
    fn new() -> Self {
        let sdl_context = sdl2::init().unwrap();
        let video_subsystem = sdl_context.video().unwrap();
        let timer = sdl_context.timer().unwrap();
        let window = video_subsystem.window("RuNES", 256 * PIXEL_SIZE, 240 * PIXEL_SIZE)
                                    .position_centered()
                                    .opengl()
                                    .build()
                                    .unwrap();
        let mut canvas = window.into_canvas().build().unwrap();
        canvas.set_draw_color(Color::RGB(255, 255, 255));
        canvas.clear();
        canvas.present();
        SDLWindow {
            canvas: RefCell::new(canvas),
            timer: RefCell::new(timer),
            events: RefCell::new(sdl_context.event_pump().unwrap()),
            frame_buffer: UnsafeCell::new([[0; 240]; 256])
        }
    }

    fn poll(&self) -> bool {
        for event in self.events.borrow_mut().poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    return true;
                },
                _ => ()
            }
        }
        false
    }
}

const PIXEL_SIZE: u32 = 2;
const RGB_COLORS: [u32; 64] = [
    0x666666, 0x002a88, 0x1412a7, 0x3b00a4, 0x5c007e, 0x6e0040, 0x6c0600, 0x561d00,
    0x333500, 0x0b4800, 0x005200, 0x004f08, 0x00404d, 0x000000, 0x000000, 0x000000,
    0xadadad, 0x155fd9, 0x4240ff, 0x7527fe, 0xa01acc, 0xb71e7b, 0xb53120, 0x994e00,
    0x6b6d00, 0x388700, 0x0c9300, 0x008f32, 0x007c8d, 0x000000, 0x000000, 0x000000,
    0xfffeff, 0x64b0ff, 0x9290ff, 0xc676ff, 0xf36aff, 0xfe6ecc, 0xfe8170, 0xea9e22,
    0xbcbe00, 0x88d800, 0x5ce430, 0x45e082, 0x48cdde, 0x4f4f4f, 0x000000, 0x000000,
    0xfffeff, 0xc0dfff, 0xd3d2ff, 0xe8c8ff, 0xfbc2ff, 0xfec4ea, 0xfeccc5, 0xf7d8a5,
    0xe4e594, 0xcfef96, 0xbdf4ab, 0xb3f3cc, 0xb5ebf2, 0xb8b8b8, 0x000000, 0x000000,
];

fn get_rgb(color: u8) -> Color {
    let c = RGB_COLORS[color as usize];
    Color::RGB((c >> 16) as u8, ((c >> 8) & 0xff) as u8, (c & 0xff) as u8)
}

impl ppu::Screen for SDLWindow {
    fn put(&self, x: u8, y: u8, color: u8) {
        unsafe {
            (*self.frame_buffer.get())[x as usize][y as usize] = color;
        }
    }

    fn render(&self) {
        let mut canvas = self.canvas.borrow_mut();
        let fb = unsafe{&*self.frame_buffer.get()};
        for (x, l) in fb.iter().enumerate() {
            for (y, c) in l.iter().enumerate() {
                canvas.set_draw_color(get_rgb(*c));
                canvas.fill_rect(Rect::