From 235c7759fcd108148d2f52de3df6e59f469bf18b Mon Sep 17 00:00:00 2001 From: Cole Landers Date: Fri, 30 Jan 2026 21:35:07 -0600 Subject: [PATCH] a bunch of changes plus some more programs --- programs/RPS.ch8 | Bin 0 -> 2017 bytes programs/flightrunner.ch8 | Bin 0 -> 295 bytes programs/octojam1title.ch8 | Bin 0 -> 426 bytes programs/outlaw.ch8 | Bin 0 -> 512 bytes src/chip8.rs | 2 +- src/chip8/cpu.rs | 10 ++++----- src/chip8/debug.rs | 4 ++-- src/chip8/gpu.rs | 44 +++++++++++++++++++++++++++++++++++++ 8 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 programs/RPS.ch8 create mode 100644 programs/flightrunner.ch8 create mode 100644 programs/octojam1title.ch8 create mode 100644 programs/outlaw.ch8 diff --git a/programs/RPS.ch8 b/programs/RPS.ch8 new file mode 100644 index 0000000000000000000000000000000000000000..3ea42d4eeb79ee26cfe187f4faebe0c7088aaa63 GIT binary patch literal 2017 zcmbu9Z)_8F7{{OAUAuO-nHG?=r(4?q$yz00h?B{RZHAI@BdiPuF;OTcvX+@;FiBxk zdox2yaer7wMvQ?9)Gi|ie4)M=3r%=2-hkC;%#4mEnlK}|4OmziZO`X-cVmr&SALWB z^LzgOp69NqrN>?S<%v@#cDg~);jPFov)shQ!*0V=7vq@ywV>cO) z`D|t;t@=Hz!iU*;)mFaQnsJXDz8VG~HUe$AOav}x0Mhr{*N1Kc{4gy^H~YZQXEK$Q z+w-|RfOuHM%H;2VW@!UE`^X^MO$0y|!`bRgCXL5yKv))l>AQ*5pMlqIFE1_b}nROw69x^xon z0Rl8JpZ#!t&l*dKp25MMs*J7(1z>kjf#{8;X3|N#dO-#~3XL??f>UjmWoT{D%{%2v zvE2ls8o=k2&t`D}TC2~oYH|B3V@kc~@d^UNbTC;cCRB^Vske*D{0nzcURC4?hr?d) zZm$RXQ#Bk@Dd*(_hYncezf6>{XeJ>drl(`c*f$pe zq~SZgpN}F(r05dl2emJ^Jy!z|YT9{d`OnDL*M&~KgRHF$(OnHX)SskbDuT6mv{gq~b88ay=#ph@;;_o0$Z7jtdO~%W<%l;(V#$uzMMSHPQIms!r zIc1&!xrF0Nj3$tM{rx^_bH&9RwNw3C+*qu{wR#yQ-%g#OMyF8U0WbyA#;Iw5F*vg2 zNFBf&OxD$12e<;AwL&Mr5d75GI0;~bdZA;b)`Y_8n8K_JSK{$8tm^)2)v7tP9qv`` zVSMf1of;Z!2H4#=xpb)wpkqa0snP|ryk79aF@Q?}*BbZ&XE=FsBMbt}4$cigBS6ZR zvcU=fmSLHKo3&%dK`+jaumAXQiE_;0E~gwC7`R7yW?(?sbFO<3Cwr`DbY$eW#}-7c z51)=Kn!V9zROzO=q{tm-f%%V6FVrt4i+H3TO@4oWe_eO~4OxJSivp>*Autuw0_$8S z=$yL*y>p4B2c&bWof{u;tSOxZ)wQK4u+S@MAyH`+WmB$FwpE z&8@6LTX1!tbRwd}$F(>mjZ@l!rE0u}SaWV-z3bZHW~_6r7u~Ei=knAr{4zJg8_>)0 z&!Cs^%h1d6F0{+hOZb)OWq6m%15!c=k^q@Fns_T%O!*%EfD)@UUybG?=nH7Rkmh4R zssg?<@oDhY!1EKIBqBkUvWoD1=u^(U~Co?!( zC0hnRXjBNf(5Mio!0--aLZ3me1IV03ObINB3_YxOHa32_vk-_U0&!#G7e{8L`#uag z4mJ)9?+!30GJ@RWz|bw?z}O|~zyze3yF{B7G;K9vWq8-Hp(0uj;)vY&8Qv{!s`;PC!0?WN zV!+7E%+AhU_y7O%!_Ca>3=9om05LWp0b%@uf`Wtx2M~M+3#gTukwL+LoqztnKR*~4 zY-q&gWG4>-7M32|0T^Hfn$QgUHn-{Ih_ zq9GYDMQo}6r>QE8%&eS7$1E5anb>%&zx=ZR8fsRb9m>F<@$Lq5bu9yfNV%h9vLnQ? aK$7DC{{zMc;xl9~a2$|$z;S>PDgyxVYI6Jl literal 0 HcmV?d00001 diff --git a/programs/outlaw.ch8 b/programs/outlaw.ch8 new file mode 100644 index 0000000000000000000000000000000000000000..71eff287e8df12b216020da8fc93d2687ea8b055 GIT binary patch literal 512 zcmWgMVqsw|EiHZj-i;eSDkNlh7#IqE6r|TABvfd;k+74IsGB)+W|U3ZVFX*njDdko zp6{6*8=IVnxkQZxLJgd)lJoz6Ljv1_c?|C|8539^EX-s|-~f`$-4CicyDn6*E{eXr zkm23!h1HCnOjZ9qnX4GR7&Do@}V=|KiQ!;aF zL+SsPf)bz^R~;GNU3Dz|@61&4-ZonYC zM0m@+J0Kqm&&y-Y<;r2mFiz)6W5@*hl;Oc5rUaQp&I|I3A`=)Aoa2PlUUs)sw k)M0v~M(Kq;gYX*V1RyzMQM4t4Qk^G*Qj9T!(jnm|04yWDwEzGB literal 0 HcmV?d00001 diff --git a/src/chip8.rs b/src/chip8.rs index 22b77ba..45fb4f1 100644 --- a/src/chip8.rs +++ b/src/chip8.rs @@ -11,7 +11,7 @@ static MEMORY_LIMIT: i32 = 4096; static STACK_LIMIT: i32 = 16; static VARIABLE_REGISTER_COUNT: i32 = 16; static TIMER_TICK_RATE: u32 = 60; -static DESIRED_FPS: u32 = 165; +static DESIRED_FPS: u32 = 60; static CYCLES_PER_FRAME: u32 = 10; #[derive(Clone)] diff --git a/src/chip8/cpu.rs b/src/chip8/cpu.rs index ddf10e3..914717a 100644 --- a/src/chip8/cpu.rs +++ b/src/chip8/cpu.rs @@ -63,24 +63,24 @@ pub fn execute_instruction(state: &mut Chip8State, instruction: u16) { } } (0x8, _, _, 0x5) => { - let flag = state.r_v[x as usize] > state.r_v[y as usize]; + let flag = state.r_v[x as usize] >= state.r_v[y as usize]; state.r_v[x as usize] = state.r_v[x as usize].wrapping_sub(state.r_v[y as usize]); state.r_v[0xF] = if flag { 1 } else { 0 }; } (0x8, _, _, 0x6) => { let flag = (state.r_v[x as usize] & 0b00000001) == 1; - state.r_v[0xF] = if flag { 1 } else { 0 }; state.r_v[x as usize] = state.r_v[x as usize] / 2; + state.r_v[0xF] = if flag { 1 } else { 0 }; } (0x8, _, _, 0x7) => { - let flag = state.r_v[x as usize] < state.r_v[y as usize]; + let flag = state.r_v[x as usize] <= state.r_v[y as usize]; state.r_v[x as usize] = state.r_v[y as usize].wrapping_sub(state.r_v[x as usize]); state.r_v[0xF] = if flag { 1 } else { 0 }; } (0x8, _, _, 0xE) => { let flag = ((state.r_v[x as usize] & 0b10000000) >> 7) == 1; - state.r_v[0xF] = if flag { 1 } else { 0 }; state.r_v[x as usize] = state.r_v[x as usize].wrapping_mul(2); + state.r_v[0xF] = if flag { 1 } else { 0 }; } (0x9, _, _, _) => { if state.r_v[x as usize] != state.r_v[y as usize] { @@ -97,7 +97,7 @@ pub fn execute_instruction(state: &mut Chip8State, instruction: u16) { (0xD, _, _, _) => { state.r_v[0xF] = 0; let bytes = read_n_bytes(&state.mem, state.mem.len(), state.r_i as usize, n as usize); - gpu::draw(state, x, y, &bytes, n); + gpu::wrapping_draw(state, x, y, &bytes, n); } (0xE, _, _, 0xE) => { let key_index = state.r_v[x as usize]; diff --git a/src/chip8/debug.rs b/src/chip8/debug.rs index 22fc0f0..e31fab7 100644 --- a/src/chip8/debug.rs +++ b/src/chip8/debug.rs @@ -22,6 +22,6 @@ pub fn print_debug(state: &Chip8State, current_instruction: u16) { } println!("Current Instruction: {:04X}", current_instruction); println!("----------------"); - println!("Press Enter to continue..."); - let _ = io::stdin().read(&mut [0u8]).unwrap(); + // println!("Press Enter to continue..."); + // let _ = io::stdin().read(&mut [0u8]).unwrap(); } diff --git a/src/chip8/gpu.rs b/src/chip8/gpu.rs index c12f2e2..9e82f42 100644 --- a/src/chip8/gpu.rs +++ b/src/chip8/gpu.rs @@ -13,10 +13,12 @@ pub fn draw(state: &mut Chip8State, vx: u8, vy: u8, bytes_to_draw: &[u8], bytes_ let start_x = state.r_v[vx as usize]; let start_y = state.r_v[vy as usize]; for y in start_y..start_y + bytes_to_draw_len { + println!("{}", bytes_idx); if (y as i32) < CHIP8_DISPLAY_HEIGHT { // 8 is the hardcoded sprite width, has to atleast have 1 8 bit value to display let mut bit_idx = 0; for x in start_x..start_x + SPRITE_WIDTH { + println!("(X,Y): ({},{})", x, y); if (x as i32) < CHIP8_DISPLAY_WIDTH { let sprite_pixel = ((bytes_to_draw[bytes_idx] >> (7 - bit_idx)) & 1) == 1; let current_pixel = state.display[y as usize][x as usize]; @@ -36,6 +38,48 @@ pub fn draw(state: &mut Chip8State, vx: u8, vy: u8, bytes_to_draw: &[u8], bytes_ } } +pub fn wrapping_draw( + state: &mut Chip8State, + vx: u8, + vy: u8, + bytes_to_draw: &[u8], + bytes_to_draw_len: u8, +) { + let mut bytes_idx = 0; + let start_x = state.r_v[vx as usize]; + let start_y = state.r_v[vy as usize]; + + while bytes_idx < bytes_to_draw_len { + let mut y = start_y.wrapping_add(bytes_idx); + if y as i32 >= CHIP8_DISPLAY_HEIGHT { + y = (y - CHIP8_DISPLAY_HEIGHT as u8) % CHIP8_DISPLAY_HEIGHT as u8; + } + + let mut bit_idx = 0; + + while bit_idx < SPRITE_WIDTH { + let mut x = start_x.wrapping_add(bit_idx); + if x as i32 >= CHIP8_DISPLAY_WIDTH { + x = (x - CHIP8_DISPLAY_WIDTH as u8) % CHIP8_DISPLAY_WIDTH as u8; + } + + let sprite_pixel = ((bytes_to_draw[bytes_idx as usize] >> (7 - bit_idx)) & 1) == 1; + let current_pixel = state.display[y as usize][x as usize]; + let new_pixel = current_pixel ^ sprite_pixel; + + state.display[y as usize][x as usize] = new_pixel; + + if new_pixel != current_pixel { + state.r_v[0xF] = 1; + } + + bit_idx += 1; + } + + bytes_idx += 1; + } +} + pub fn load_builtin_sprites(state: &mut Chip8State) { memory::load_bytes( state,