git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

Core/rumble.c

      1 #include "rumble.h"
      2 #include "gb.h"
      3 
      4 void GB_set_rumble_mode(GB_gameboy_t *gb, GB_rumble_mode_t mode)
      5 {
      6     gb->rumble_mode = mode;
      7     if (gb->rumble_callback) {
      8         gb->rumble_callback(gb, 0);
      9     }
     10 }
     11 
     12 void GB_handle_rumble(GB_gameboy_t *gb)
     13 {
     14     if (gb->rumble_callback) {
     15         if (gb->rumble_mode == GB_RUMBLE_DISABLED) {
     16             return;
     17         }
     18         if (gb->cartridge_type->has_rumble &&
     19             (gb->cartridge_type->mbc_type != GB_TPP1 || (gb->rom[0x153] & 1))) {
     20             if (gb->rumble_on_cycles + gb->rumble_off_cycles) {
     21                 gb->rumble_callback(gb, gb->rumble_on_cycles / (double)(gb->rumble_on_cycles + gb->rumble_off_cycles));
     22                 gb->rumble_on_cycles = gb->rumble_off_cycles = 0;
     23             }
     24         }
     25         else if (gb->rumble_mode == GB_RUMBLE_ALL_GAMES) {
     26             unsigned volume = (gb->io_registers[GB_IO_NR50] & 7) + 1 + ((gb->io_registers[GB_IO_NR50] >> 4) & 7) + 1;
     27             unsigned ch4_volume = volume * (!!(gb->io_registers[GB_IO_NR51] & 8) + !!(gb->io_registers[GB_IO_NR51] & 0x80));
     28             unsigned ch1_volume = volume * (!!(gb->io_registers[GB_IO_NR51] & 1) + !!(gb->io_registers[GB_IO_NR51] & 0x10));
     29             unsigned ch4_divisor = (gb->io_registers[GB_IO_NR43] & 0x07) << 1;
     30             if (!ch4_divisor) ch4_divisor = 1;
     31             unsigned ch4_sample_length = (ch4_divisor << (gb->io_registers[GB_IO_NR43] >> 4)) - 1;
     32         
     33             double ch4_rumble = (MIN(ch4_sample_length * (gb->apu.noise_channel.narrow? 8 : 1) , 4096) * ((signed) gb->apu.noise_channel.current_volume * gb->apu.noise_channel.current_volume * ch4_volume / 32.0 - 50) - 2048) / 2048.0;
     34             
     35             ch4_rumble = MIN(ch4_rumble, 1.0);
     36             ch4_rumble = MAX(ch4_rumble, 0.0);
     37             
     38             double ch1_rumble = 0;
     39             if ((gb->io_registers[GB_IO_NR10] & 0x7) && (gb->io_registers[GB_IO_NR10] & 0x70)) {
     40                 double sweep_speed = (gb->io_registers[GB_IO_NR10] & 7) / (double)((gb->io_registers[GB_IO_NR10] >> 4) & 7);
     41                 ch1_rumble = gb->apu.square_channels[GB_SQUARE_1].current_volume * ch1_volume / 32.0 * sweep_speed / 8.0 - 0.5;
     42                 ch1_rumble = MIN(ch1_rumble, 1.0);
     43                 ch1_rumble = MAX(ch1_rumble, 0.0);
     44             }
     45             
     46             if (!gb->apu.is_active[GB_NOISE]) {
     47                 ch4_rumble = 0;
     48             }
     49             
     50             if (!gb->apu.is_active[GB_SQUARE_1]) {
     51                 ch1_rumble = 0;
     52             }
     53             
     54             gb->rumble_callback(gb, MIN(MAX(ch1_rumble / 2 + ch4_rumble, 0.0), 1.0));
     55         }
     56     }
     57 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.