Exemple #1
0
//Hanlde "all" requests to/from server, pass off to child funcs in
// rcon-handlers.c for specific API hooking
int root_handler(struct mg_connection *conn, json_t* jreq, json_t* jrsp){
    //Get current "action" request
    json_t* action = json_object_get(jreq,"action");
    if (!action){
        //no action found, set error handling
        json_object_set_new(jrsp,"error",json_string("no 'action' key in request (please POST)"));
        return 400;
    }

    //test handler, echos back some basic data about the request
    if(cmpjstr(action,"version")){
        return handle_version(conn,jreq,jrsp);
    }
    else if(cmpjstr(action,"api/hotkey")){
        return handle_hotkey(jreq,jrsp);
    }
    else if(cmpjstr(action,"api/output")){
        return handle_output(jreq,jrsp);
    }
    else if(cmpjstr(action,"plugin")){
        for (size_t i=0; i < rcon_data.plugin_handlers.num; i++){
            struct rcon_handler hndl = rcon_data.plugin_handlers.array[i];
            if (cmpjstr(json_object_get(jreq,"plugin_action"),hndl.action)){
                return hndl.handle_func(conn,jreq,jrsp);
            }
        }
        json_object_set_new(jrsp,"error",json_string("no matching 'plugin_action' found for request."));
        return 400;
    }
    else {
        json_object_set_new(jrsp,"error",json_string("no matching 'action' found for request."));

        if (jreq){
            json_object_set(jrsp, "requestJSON", jreq);
        }
        else{
            json_object_set_new(jrsp,"requestJSON", json_null());
        }
        return 400;
    }
}
Exemple #2
0
/****** Force the core to sleep ******/
void AGB_core::sleep()
{
	//White out LCD
	core_cpu.controllers.video.clear_screen_buffer(0xFFFFFFFF);
	core_cpu.controllers.video.update();

	//Wait for L+R+Select input
	bool l_r_select = false;

	while(!l_r_select)
	{
		SDL_PollEvent(&event);

		if((event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP) 
		|| (event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP)
		|| (event.type == SDL_JOYAXISMOTION) || (event.type == SDL_JOYHATMOTION)) { core_pad.handle_input(event); handle_hotkey(event); }

		if(((core_pad.key_input & 0x4) == 0) && ((core_pad.key_input & 0x100) == 0) && ((core_pad.key_input & 0x200) == 0)) { l_r_select = true; }

		SDL_Delay(50);
		core_cpu.controllers.video.update();
	}

	core_cpu.sleep = false;
	core_cpu.running = true;
}
Exemple #3
0
/****** Run the core in a loop until exit ******/
void AGB_core::run_core()
{
	//Begin running the core
	while(running)
	{
		//Handle SDL Events
		if((core_cpu.controllers.video.current_scanline == 160) && SDL_PollEvent(&event))
		{
			//X out of a window
			if(event.type == SDL_QUIT) { stop(); SDL_Quit(); }

			//Process gamepad or hotkey
			else if((event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP) 
			|| (event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP)
			|| (event.type == SDL_JOYAXISMOTION) || (event.type == SDL_JOYHATMOTION)) { core_pad.handle_input(event); handle_hotkey(event); }
		}

		//Run the CPU
		if(core_cpu.running)
		{	
			if(db_unit.debug_mode) { debug_step(); }

			core_cpu.fetch();
			core_cpu.decode();
			core_cpu.execute();

			core_cpu.handle_interrupt();
		
			//Flush pipeline if necessary
			if(core_cpu.needs_flush) { core_cpu.flush_pipeline(); }

			//Else update the pipeline and PC
			else 
			{ 
				core_cpu.pipeline_pointer = (core_cpu.pipeline_pointer + 1) % 3;
				core_cpu.update_pc(); 
			}
		}

		//Stop emulation
		else { stop(); }
	}

	//Shutdown core
	shutdown();
}
Exemple #4
0
/****** Feeds key input from an external source (useful for TAS) ******/
void AGB_core::feed_key_input(int sdl_key, bool pressed)
{
	core_pad.process_keyboard(sdl_key, pressed);
	handle_hotkey(sdl_key, pressed);
}
Exemple #5
0
/****** Run the core in a loop until exit ******/
void AGB_core::run_core()
{
	//Begin running the core
	while(running)
	{
		//Handle SDL Events
		if((core_cpu.controllers.video.current_scanline == 160) && SDL_PollEvent(&event))
		{
			//X out of a window
			if(event.type == SDL_QUIT) { stop(); SDL_Quit(); }

			//Process gamepad or hotkey
			else if((event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP) 
			|| (event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP)
			|| (event.type == SDL_JOYAXISMOTION) || (event.type == SDL_JOYHATMOTION))
			{
				core_pad.handle_input(event);
				handle_hotkey(event);

				//Trigger Joypad Interrupt if necessary
				if(core_pad.joypad_irq) { core_mmu.memory_map[REG_IF] |= 0x1000; }
			}
		}

		//Run the CPU
		if(core_cpu.running)
		{	
			//Receive byte from another instance of GBE+ via netplay - Manage sync
			if(core_cpu.controllers.serial_io.sio_stat.connected)
			{
				//Perform syncing operations when hard sync is enabled
				if(config::netplay_hard_sync) { hard_sync(); }

				//Receive bytes normally
				core_cpu.controllers.serial_io.receive_byte();

				//Clock SIO
				//core_cpu.clock_sio();
			}

			//Otherwise, try to run any emulate SIO devices attached to GBE+
			else if(core_cpu.controllers.serial_io.sio_stat.emu_device_ready) { core_cpu.clock_emulated_sio_device(); }

			//Reset system cycles for next instruction
			core_cpu.system_cycles = 0;

			if(db_unit.debug_mode) { debug_step(); }

			core_cpu.fetch();
			core_cpu.decode();
			core_cpu.execute();

			core_cpu.handle_interrupt();
		
			//Flush pipeline if necessary
			if(core_cpu.needs_flush) { core_cpu.flush_pipeline(); }

			//Else update the pipeline and PC
			else 
			{ 
				core_cpu.pipeline_pointer = (core_cpu.pipeline_pointer + 1) % 3;
				core_cpu.update_pc(); 
			}
		}

		//Stop emulation
		else { stop(); }
	}

	//Shutdown core
	shutdown();
}
Exemple #6
0
/****** Run the core in a loop until exit ******/
void SGB_core::run_core()
{
	if(config::gb_type == 2) { core_cpu.reg.a = 0x11; }

	//Begin running the core
	while(running)
	{
		//Handle SDL Events
		if((core_cpu.controllers.video.lcd_stat.current_scanline == 144) && SDL_PollEvent(&event))
		{
			//X out of a window
			if(event.type == SDL_QUIT) { stop(); SDL_Quit(); }

			//Process gamepad or hotkey
			else if((event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP) 
			|| (event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP)
			|| (event.type == SDL_JOYAXISMOTION) || (event.type == SDL_JOYHATMOTION))
			{
				core_pad.handle_input(event);
				handle_hotkey(event);

				//Trigger Joypad Interrupt if necessary
				if(core_pad.joypad_irq) { core_mmu.memory_map[IF_FLAG] |= 0x10; }
			}
		}

		//Run the CPU
		if(core_cpu.running)
		{
			//Receive byte from another instance of GBE+ via netplay
			if(core_cpu.controllers.serial_io.sio_stat.connected)
			{
				//Perform syncing operations when hard sync is enabled
				if(config::netplay_hard_sync)
				{
					core_cpu.controllers.serial_io.sio_stat.sync_counter += core_cpu.cycles;

					//Once this Game Boy has reached a specified amount of cycles, freeze until the other Game Boy finished that many cycles
					if(core_cpu.controllers.serial_io.sio_stat.sync_counter >= core_cpu.controllers.serial_io.sio_stat.sync_clock)
					{
						core_cpu.controllers.serial_io.request_sync();
						u32 current_time = SDL_GetTicks();
						u32 timeout = 0;

						while(core_cpu.controllers.serial_io.sio_stat.sync)
						{
							core_cpu.controllers.serial_io.receive_byte();

							//Timeout if 10 seconds passes
							timeout = SDL_GetTicks();
							
							if((timeout - current_time) >= 10000)
							{
								core_cpu.controllers.serial_io.reset();
							}						
						}
					}
				}

				//Receive bytes normally
				core_cpu.controllers.serial_io.receive_byte();
			}

			core_cpu.debug_cycles += core_cpu.cycles;
			core_cpu.cycles = 0;

			//Handle Interrupts
			core_cpu.handle_interrupts();

			if(db_unit.debug_mode) { debug_step(); }
	
			//Halt CPU if necessary
			if(core_cpu.halt == true)
			{
				//Normal HALT mode
				if(core_cpu.interrupt || !core_cpu.skip_instruction) { core_cpu.cycles += 4; }

				//HALT bug
				else if(core_cpu.skip_instruction)
				{
					//Exit HALT mode
					core_cpu.halt = false;
					core_cpu.skip_instruction = false;

					//Execute next opcode, but do not increment PC
					core_cpu.opcode = core_mmu.read_u8(core_cpu.reg.pc);
					core_cpu.exec_op(core_cpu.opcode);
				}
			}

			//Process Opcodes
			else 
			{
				core_cpu.opcode = core_mmu.read_u8(core_cpu.reg.pc++);
				core_cpu.exec_op(core_cpu.opcode);
			}

			//Update LCD
			if(core_cpu.double_speed) { core_cpu.controllers.video.step(core_cpu.cycles >> 1); }
			else { core_cpu.controllers.video.step(core_cpu.cycles); }

			//Update DIV timer - Every 4 M clocks
			core_cpu.div_counter += core_cpu.cycles;
		
			if(core_cpu.div_counter >= 256) 
			{
				core_cpu.div_counter -= 256;
				core_mmu.memory_map[REG_DIV]++;
			}

			//Update TIMA timer
			if(core_mmu.memory_map[REG_TAC] & 0x4) 
			{	
				core_cpu.tima_counter += core_cpu.cycles;

				switch(core_mmu.memory_map[REG_TAC] & 0x3)
				{
					case 0x00: core_cpu.tima_speed = 1024; break;
					case 0x01: core_cpu.tima_speed = 16; break;
					case 0x02: core_cpu.tima_speed = 64; break;
					case 0x03: core_cpu.tima_speed = 256; break;
				}
	
				if(core_cpu.tima_counter >= core_cpu.tima_speed)
				{
					core_mmu.memory_map[REG_TIMA]++;
					core_cpu.tima_counter -= core_cpu.tima_speed;

					if(core_mmu.memory_map[REG_TIMA] == 0)
					{
						core_mmu.memory_map[IF_FLAG] |= 0x04;
						core_mmu.memory_map[REG_TIMA] = core_mmu.memory_map[REG_TMA];
					}	

				}
			}

			//Update serial input-output operations
			if(core_cpu.controllers.serial_io.sio_stat.shifts_left != 0)
			{
				core_cpu.controllers.serial_io.sio_stat.shift_counter += core_cpu.cycles;

				//After SIO clocks, perform SIO operations now
				if(core_cpu.controllers.serial_io.sio_stat.shift_counter >= core_cpu.controllers.serial_io.sio_stat.shift_clock)
				{
					//Shift bit out from SB, transfer it
					core_mmu.memory_map[REG_SB] <<= 1;

					core_cpu.controllers.serial_io.sio_stat.shift_counter -= core_cpu.controllers.serial_io.sio_stat.shift_clock;
					core_cpu.controllers.serial_io.sio_stat.shifts_left--;

					//Complete the transfer
					if(core_cpu.controllers.serial_io.sio_stat.shifts_left == 0)
					{
						//Reset Bit 7 in SC
						core_mmu.memory_map[REG_SC] &= ~0x80;

						core_cpu.controllers.serial_io.sio_stat.active_transfer = false;

						switch(core_cpu.controllers.serial_io.sio_stat.sio_type)
						{
							//Process normal SIO communications
							case NO_GB_DEVICE:
							case GB_LINK:
								//Emulate disconnected link cable (on an internal clock) with no netplay
								if((core_cpu.controllers.serial_io.sio_stat.internal_clock)
								&& (!config::use_netplay || !core_cpu.controllers.serial_io.sio_stat.connected))
								{
									core_mmu.memory_map[REG_SB] = 0xFF;
									core_mmu.memory_map[IF_FLAG] |= 0x08;
								}

								//Send byte to another instance of GBE+ via netplay
								if(core_cpu.controllers.serial_io.sio_stat.connected) { core_cpu.controllers.serial_io.send_byte(); }
						
								break;

							//Process GB Printer communications
							case GB_PRINTER:
								core_cpu.controllers.serial_io.printer_process();
								break;

							//Process Barcode Boy communications
							case GB_BARCODE_BOY:
								core_cpu.controllers.serial_io.barcode_boy_process();

								if(core_cpu.controllers.serial_io.barcode_boy.send_data)
								{
									core_mmu.memory_map[REG_SB] = core_cpu.controllers.serial_io.barcode_boy.byte;
									core_mmu.memory_map[IF_FLAG] |= 0x08;
								}
									
								break;

							//Process Bardigun card scanner communications
							case GB_BARDIGUN_SCANNER:
								core_cpu.controllers.serial_io.bardigun_process();
								break;
						}
					}
				}
			}
		}