pizza: start removing parts i don't like
This commit is contained in:
parent
a82d3bc540
commit
7d6b4611dc
|
@ -172,14 +172,6 @@ char cartridge_load(char *file_gb)
|
|||
/* save base name of the rom */
|
||||
strncpy(global_rom_name, basename(file_gb), 256);
|
||||
|
||||
/* build file.sav */
|
||||
snprintf(file_sav, sizeof(file_sav), "%s/%s.sav",
|
||||
global_save_folder, global_rom_name);
|
||||
|
||||
/* build file.rtc */
|
||||
snprintf(file_rtc, sizeof(file_rtc), "%s/%s.rtc",
|
||||
global_save_folder, global_rom_name);
|
||||
|
||||
/* restore saved RAM if it's the case */
|
||||
mmu_restore_ram(file_sav);
|
||||
|
||||
|
|
|
@ -96,34 +96,6 @@ void cycles_set_speed(char dbl)
|
|||
cycles_change_emulation_speed();
|
||||
}
|
||||
|
||||
/* set emulation speed */
|
||||
void cycles_change_emulation_speed()
|
||||
{
|
||||
switch (global_emulation_speed)
|
||||
{
|
||||
case GLOBAL_EMULATION_SPEED_QUARTER:
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES) / 4
|
||||
<< global_cpu_double_speed);
|
||||
break;
|
||||
case GLOBAL_EMULATION_SPEED_HALF:
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES) / 2
|
||||
<< global_cpu_double_speed);
|
||||
break;
|
||||
case GLOBAL_EMULATION_SPEED_NORMAL:
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES)
|
||||
<< global_cpu_double_speed);
|
||||
break;
|
||||
case GLOBAL_EMULATION_SPEED_DOUBLE:
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES) * 2
|
||||
<< global_cpu_double_speed);
|
||||
break;
|
||||
case GLOBAL_EMULATION_SPEED_4X:
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES) * 4
|
||||
<< global_cpu_double_speed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cycles_closest_next()
|
||||
{
|
||||
int_fast32_t diff = cycles.cnt - cycles.next;
|
||||
|
@ -393,17 +365,3 @@ void cycles_stop_timer()
|
|||
void cycles_term()
|
||||
{
|
||||
}
|
||||
|
||||
void cycles_save_stat(FILE *fp)
|
||||
{
|
||||
fwrite(&cycles, 1, sizeof(cycles_t), fp);
|
||||
}
|
||||
|
||||
void cycles_restore_stat(FILE *fp)
|
||||
{
|
||||
fread(&cycles, 1, sizeof(cycles_t), fp);
|
||||
|
||||
/* recalc speed stuff */
|
||||
cycles_change_emulation_speed();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ typedef void (*cycles_send_cb_t) (uint32_t v);
|
|||
void cycles_change_emulation_speed();
|
||||
void cycles_hdma();
|
||||
char cycles_init();
|
||||
void cycles_restore_stat(FILE *fp);
|
||||
void cycles_save_stat(FILE *fp);
|
||||
void cycles_set_speed(char dbl);
|
||||
void cycles_start_hs();
|
||||
char cycles_start_timer();
|
||||
|
|
|
@ -315,101 +315,3 @@ void gameboy_stop()
|
|||
/* shutdown semaphore limitator */
|
||||
cycles_term();
|
||||
}
|
||||
|
||||
char gameboy_restore_stat(int idx)
|
||||
{
|
||||
char path[256];
|
||||
char buf[6];
|
||||
|
||||
/* ensure i'm in pause */
|
||||
gameboy_set_pause(1);
|
||||
|
||||
/* build output file name */
|
||||
snprintf(path, sizeof(path), "%s/%s.%d.stat", global_save_folder,
|
||||
global_rom_name, idx);
|
||||
|
||||
FILE *fp = fopen(path, "r+");
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
utils_log("Cannot open stat file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* read version */
|
||||
fread(buf, 1, 6, fp);
|
||||
|
||||
if (memcmp(buf, "000001", 6))
|
||||
{
|
||||
utils_log("Version of stat file doesnt match\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* restore CPU status */
|
||||
fread(&state, 1, sizeof(z80_state_t), fp);
|
||||
|
||||
state.f = (uint8_t *) &state.flags;
|
||||
state.bc = (uint16_t *) &state.c;
|
||||
state.de = (uint16_t *) &state.e;
|
||||
state.hl = (uint16_t *) &state.l;
|
||||
|
||||
/* dump every module */
|
||||
cycles_restore_stat(fp);
|
||||
sound_restore_stat(fp);
|
||||
gpu_restore_stat(fp);
|
||||
serial_restore_stat(fp);
|
||||
mmu_restore_stat(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char gameboy_save_stat(int idx)
|
||||
{
|
||||
char path[256];
|
||||
|
||||
/* ensure i'm in pause */
|
||||
gameboy_set_pause(1);
|
||||
|
||||
/* build output file name */
|
||||
snprintf(path, sizeof(path), "%s/%s.%d.stat", global_save_folder,
|
||||
global_rom_name, idx);
|
||||
|
||||
FILE *fp = fopen(path, "w+");
|
||||
|
||||
if (fp == NULL)
|
||||
return 1;
|
||||
|
||||
/* dump current version */
|
||||
fwrite("000001", 1, 6, fp);
|
||||
|
||||
/* dump cpu status */
|
||||
fwrite(&state, 1, sizeof(z80_state_t), fp);
|
||||
|
||||
/* dump every module */
|
||||
cycles_save_stat(fp);
|
||||
sound_save_stat(fp);
|
||||
gpu_save_stat(fp);
|
||||
serial_save_stat(fp);
|
||||
mmu_save_stat(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* now dump raw data of frame buffer */
|
||||
snprintf(path, sizeof(path), "%s/%s.%d.fb", global_save_folder,
|
||||
global_rom_name, idx);
|
||||
|
||||
fp = fopen(path, "w+");
|
||||
|
||||
if (fp == NULL)
|
||||
return 1;
|
||||
|
||||
/* dump frame buffer pixels */
|
||||
gpu_save_fb(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
/* prototypes */
|
||||
void gameboy_init();
|
||||
void gameboy_run();
|
||||
char gameboy_restore_stat(int idx);
|
||||
char gameboy_save_stat(int idx);
|
||||
void gameboy_set_pause(char pause);
|
||||
void gameboy_stop();
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ char global_cart_name[256];
|
|||
char global_cgb;
|
||||
char global_cpu_double_speed;
|
||||
char global_debug;
|
||||
char global_emulation_speed;
|
||||
char global_next_frame;
|
||||
char global_pause;
|
||||
char global_quit;
|
||||
|
@ -34,7 +33,6 @@ char global_record_audio;
|
|||
char global_rom_name[256];
|
||||
char global_rumble;
|
||||
char global_slow_down;
|
||||
char global_save_folder[256];
|
||||
char global_window;
|
||||
|
||||
void global_init()
|
||||
|
@ -49,8 +47,6 @@ void global_init()
|
|||
global_record_audio = 0;
|
||||
global_next_frame = 0;
|
||||
global_rumble = 0;
|
||||
global_emulation_speed = GLOBAL_EMULATION_SPEED_NORMAL;
|
||||
// bzero(global_save_folder, 256);
|
||||
bzero(global_rom_name, 256);
|
||||
sprintf(global_cart_name, "NOCARTIRDGE");
|
||||
}
|
||||
|
|
|
@ -20,15 +20,6 @@
|
|||
#ifndef __GLOBAL__
|
||||
#define __GLOBAL__
|
||||
|
||||
/* defines */
|
||||
enum {
|
||||
GLOBAL_EMULATION_SPEED_QUARTER,
|
||||
GLOBAL_EMULATION_SPEED_HALF,
|
||||
GLOBAL_EMULATION_SPEED_NORMAL,
|
||||
GLOBAL_EMULATION_SPEED_DOUBLE,
|
||||
GLOBAL_EMULATION_SPEED_4X
|
||||
};
|
||||
|
||||
extern char global_quit;
|
||||
extern char global_pause;
|
||||
extern char global_window;
|
||||
|
@ -39,9 +30,7 @@ extern char global_next_frame;
|
|||
extern char global_cpu_double_speed;
|
||||
extern char global_slow_down;
|
||||
extern char global_record_audio;
|
||||
extern char global_emulation_speed;
|
||||
extern char global_rumble;
|
||||
extern char global_save_folder[256];
|
||||
extern char global_rom_name[256];
|
||||
extern char global_cart_name[256];
|
||||
|
||||
|
|
|
@ -181,11 +181,11 @@ void gpu_draw_frame()
|
|||
gpu.frame_counter++;
|
||||
|
||||
/* is it the case to push samples? */
|
||||
if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
/*if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
(gpu.frame_counter & 0x0001) != 0) ||
|
||||
(global_emulation_speed == GLOBAL_EMULATION_SPEED_4X &&
|
||||
(gpu.frame_counter & 0x0003) != 0))
|
||||
return;
|
||||
return;*/
|
||||
|
||||
uint_fast32_t i,r,g,b,r2,g2,b2,res;
|
||||
|
||||
|
@ -257,11 +257,11 @@ void gpu_draw_line(uint8_t line)
|
|||
return;
|
||||
|
||||
/* is it the case to push samples? */
|
||||
if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
/*if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
(gpu.frame_counter & 0x0001) != 0) ||
|
||||
(global_emulation_speed == GLOBAL_EMULATION_SPEED_4X &&
|
||||
(gpu.frame_counter & 0x0003) != 0))
|
||||
return;
|
||||
return;*/
|
||||
|
||||
int i, t, y, px_start, px_drawn;
|
||||
uint8_t *tiles_map, tile_subline, palette_idx, x_flip, priority;
|
||||
|
@ -689,14 +689,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
|||
int16_t tile_ptr;
|
||||
uint16_t *palette;
|
||||
uint8_t *tiles;
|
||||
|
||||
/* is it the case to push samples? */
|
||||
/* if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
(gpu.frame_counter & 0x01) != 0) ||
|
||||
(global_emulation_speed == GLOBAL_EMULATION_SPEED_4X &&
|
||||
(gpu.frame_counter & 0x03) != 0))
|
||||
return; */
|
||||
|
||||
|
||||
/* REMEMBER! position of sprites is relative to the visible screen area */
|
||||
/* ... and y is shifted by 16 pixels, x by 8 */
|
||||
y = oam->y - 16;
|
||||
|
@ -1159,21 +1152,3 @@ void gpu_set_speed(char speed)
|
|||
else
|
||||
gpu.step = 4;
|
||||
}
|
||||
|
||||
void gpu_save_fb(FILE *fp)
|
||||
{
|
||||
fwrite(&gpu.frame_buffer, 1, sizeof(int16_t) * 144 * 160, fp);
|
||||
}
|
||||
|
||||
void gpu_save_stat(FILE *fp)
|
||||
{
|
||||
fwrite(&gpu, 1, sizeof(gpu_t), fp);
|
||||
}
|
||||
|
||||
void gpu_restore_stat(FILE *fp)
|
||||
{
|
||||
fread(&gpu, 1, sizeof(gpu_t), fp);
|
||||
|
||||
gpu_init_pointers();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,6 @@ void gpu_dump_oam();
|
|||
uint16_t *gpu_get_frame_buffer();
|
||||
void gpu_init(gpu_frame_ready_cb_t cb);
|
||||
void gpu_reset();
|
||||
void gpu_restore_stat(FILE *fp);
|
||||
void gpu_save_stat(FILE *fp);
|
||||
void gpu_save_fb(FILE *fp);
|
||||
void gpu_set_speed(char speed);
|
||||
void gpu_step();
|
||||
void gpu_toggle(uint8_t state);
|
||||
|
|
|
@ -99,4 +99,3 @@ void input_set_key_a(char state) { input_key_a = state; }
|
|||
void input_set_key_b(char state) { input_key_b = state; }
|
||||
void input_set_key_select(char state) { input_key_select = state; }
|
||||
void input_set_key_start(char state) { input_key_start = state; }
|
||||
|
||||
|
|
|
@ -82,70 +82,6 @@ void *mmu_addr_vram1()
|
|||
return (void *) &mmu.vram1;
|
||||
}
|
||||
|
||||
/* modify rom in case of Gamegenie cheat */
|
||||
void mmu_apply_gg()
|
||||
{
|
||||
return;
|
||||
|
||||
/* a wild cheat can occour */
|
||||
if (mmu.gg_count == 0)
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0; i<mmu.gg_count; i++)
|
||||
{
|
||||
if (mmu.memory[mmu.gg_array[i].address] == mmu.gg_array[i].old_value)
|
||||
mmu.memory[mmu.gg_array[i].address] = mmu.gg_array[i].new_value;
|
||||
}
|
||||
}
|
||||
|
||||
/* modify rom in case of Gameshark cheat */
|
||||
void mmu_apply_gs()
|
||||
{
|
||||
return;
|
||||
|
||||
/* a wild cheat can occour */
|
||||
if (mmu.gs_count == 0)
|
||||
return;
|
||||
|
||||
int i;
|
||||
uint16_t address;
|
||||
|
||||
for (i=0; i<mmu.gs_count; i++)
|
||||
{
|
||||
address = mmu.gs_array[i].address;
|
||||
|
||||
if (address < 0xA000)
|
||||
continue;
|
||||
|
||||
/* working ram */
|
||||
if (address < 0xC000)
|
||||
{
|
||||
if (mmu.gs_array[i].ram_bank == mmu.ram_current_bank)
|
||||
mmu.memory[address] = mmu.gs_array[i].new_value;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* fixed working ram */
|
||||
if (address < 0xD000)
|
||||
{
|
||||
if (mmu.gs_array[i].ram_bank == 0)
|
||||
mmu.memory[address] = mmu.gs_array[i].new_value;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* switchable working ram */
|
||||
if (address < 0xE000)
|
||||
{
|
||||
if (mmu.gs_array[i].ram_bank == mmu.wram_current_bank)
|
||||
mmu.memory[address] = mmu.gs_array[i].new_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* debug purposes */
|
||||
void mmu_dump_all()
|
||||
{
|
||||
|
@ -425,14 +361,6 @@ void mmu_restore_rtc(char *fn)
|
|||
}
|
||||
}
|
||||
|
||||
void mmu_restore_stat(FILE *fp)
|
||||
{
|
||||
fread(&mmu, 1, sizeof(mmu_t), fp);
|
||||
|
||||
if (ram_sz)
|
||||
fread(ram, 1, ram_sz, fp);
|
||||
}
|
||||
|
||||
void mmu_save_ram(char *fn)
|
||||
{
|
||||
/* save only if cartridge got a battery */
|
||||
|
@ -501,124 +429,6 @@ void mmu_save_rtc(char *fn)
|
|||
}
|
||||
}
|
||||
|
||||
void mmu_save_stat(FILE *fp)
|
||||
{
|
||||
fwrite(&mmu, 1, sizeof(mmu_t), fp);
|
||||
|
||||
if (ram_sz)
|
||||
fwrite(ram, 1, ram_sz, fp);
|
||||
}
|
||||
|
||||
char mmu_set_cheat(char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 1;
|
||||
|
||||
size_t len = strlen(str);
|
||||
|
||||
/* gamegenie is 9 char long, gameshark is 8 char long */
|
||||
if (len < 8 || len > 9)
|
||||
return 1;
|
||||
|
||||
unsigned int new_value, address, old_value;
|
||||
|
||||
/* gamegenie branch */
|
||||
if (len == 9)
|
||||
{
|
||||
if (mmu.gg_count == MMU_GAMEGENIE_MAX)
|
||||
{
|
||||
utils_log("Max Gamegenie cheats reached");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char tmp[5];
|
||||
|
||||
/* parse it (must be cleaned by - before) */
|
||||
if (sscanf(str, "%02x", &new_value) < 1)
|
||||
return 1;
|
||||
|
||||
/* build memory address */
|
||||
tmp[0] = str[5];
|
||||
tmp[1] = str[2];
|
||||
tmp[2] = str[3];
|
||||
tmp[3] = str[4];
|
||||
tmp[4] = '\0';
|
||||
|
||||
if (sscanf(tmp, "%04x", &address) < 1)
|
||||
return 1;
|
||||
|
||||
/* build old value */
|
||||
tmp[0] = str[6];
|
||||
tmp[1] = str[7];
|
||||
tmp[2] = str[8];
|
||||
tmp[3] = '\0';
|
||||
|
||||
if (sscanf(tmp, "%03x", &old_value) < 1)
|
||||
return 1;
|
||||
|
||||
/* XOR data according do GameGenie specifications */
|
||||
address ^= 0xF000;
|
||||
|
||||
if ((((old_value >> 8) ^ (old_value >> 4)) & 0x0F) != 0x08)
|
||||
{
|
||||
utils_log("Gamegenie cloak error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
old_value = ((((old_value >> 2) & 0x03) |
|
||||
((old_value >> 6) & 0x3C) |
|
||||
((old_value << 6) & 0xC0)) ^ 0xBA);
|
||||
|
||||
/* save it into current array slot */
|
||||
mmu.gg_array[mmu.gg_count].address = (uint16_t) address;
|
||||
mmu.gg_array[mmu.gg_count].new_value = (uint8_t) new_value;
|
||||
mmu.gg_array[mmu.gg_count].old_value = (uint8_t) old_value;
|
||||
|
||||
/* looks legit! activate it */
|
||||
mmu.gg_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int ram_bank, mem_low, mem_high;
|
||||
|
||||
/* it must be a game shark cheat */
|
||||
if (sscanf(str, "%02x%02x%02x%02x", &ram_bank, &new_value,
|
||||
&mem_low, &mem_high) < 4)
|
||||
{
|
||||
utils_log("Wrong Gameshark format");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mmu.gs_count == MMU_GAMESHARK_MAX)
|
||||
{
|
||||
utils_log("Max Gameshark cheats reached");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save it */
|
||||
mmu.gs_array[mmu.gs_count].address = (uint16_t)
|
||||
(mem_low | (mem_high << 8));
|
||||
mmu.gs_array[mmu.gs_count].ram_bank = ram_bank & 0x7F;
|
||||
mmu.gs_array[mmu.gs_count].new_value = new_value;
|
||||
|
||||
/* utils_log("Gameshark address %04x - bank %02x - value %02x\n",
|
||||
mmu.gs_array[mmu.gs_count].address,
|
||||
mmu.gs_array[mmu.gs_count].ram_bank,
|
||||
mmu.gs_array[mmu.gs_count].new_value);*/
|
||||
|
||||
/* looks legit! activate it */
|
||||
mmu.gs_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
utils_log("Unknown cheat format");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mmu_set_rumble_cb(mmu_rumble_cb_t cb)
|
||||
{
|
||||
mmu_rumble_cb = cb;
|
||||
|
|
|
@ -124,8 +124,6 @@ typedef void (*mmu_rumble_cb_t) (uint8_t onoff);
|
|||
void *mmu_addr(uint16_t a);
|
||||
void *mmu_addr_vram0();
|
||||
void *mmu_addr_vram1();
|
||||
void mmu_apply_gg();
|
||||
void mmu_apply_gs();
|
||||
void mmu_dump_all();
|
||||
void mmu_init(uint8_t c, uint8_t rn);
|
||||
void mmu_init_ram(uint32_t c);
|
||||
|
@ -137,11 +135,8 @@ uint8_t mmu_read(uint16_t a);
|
|||
unsigned int mmu_read_16(uint16_t a);
|
||||
void mmu_restore_ram(char *fn);
|
||||
void mmu_restore_rtc(char *fn);
|
||||
void mmu_restore_stat(FILE *fp);
|
||||
void mmu_save_ram(char *fn);
|
||||
void mmu_save_rtc(char *fn);
|
||||
void mmu_save_stat(FILE *fp);
|
||||
char mmu_set_cheat(char *cheat);
|
||||
void mmu_set_rumble_cb(mmu_rumble_cb_t cb);
|
||||
void mmu_step();
|
||||
void mmu_term();
|
||||
|
|
|
@ -1,409 +0,0 @@
|
|||
/*
|
||||
|
||||
This file is part of Emu-Pizza
|
||||
|
||||
Emu-Pizza is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Emu-Pizza is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Emu-Pizza. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cycles.h"
|
||||
#include "global.h"
|
||||
#include "network.h"
|
||||
#include "serial.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/* network special binary semaphore */
|
||||
/* typedef struct network_sem_s {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cvar;
|
||||
int v;
|
||||
} network_sem_t; */
|
||||
|
||||
/* network sockets */
|
||||
int network_sock_broad = -1;
|
||||
int network_sock_bound = -1;
|
||||
|
||||
/* peer addr */
|
||||
struct sockaddr_in network_peer_addr;
|
||||
|
||||
/* uuid to identify myself */
|
||||
unsigned int network_uuid;
|
||||
|
||||
/* uuid to identify peer */
|
||||
unsigned int network_peer_uuid;
|
||||
|
||||
/* progressive number (debug purposes) */
|
||||
uint8_t network_prog_recv = 0;
|
||||
uint8_t network_prog_sent = 0;
|
||||
|
||||
/* track that network is running */
|
||||
unsigned char network_running = 0;
|
||||
|
||||
/* broadcast address */
|
||||
char network_broadcast_addr[16];
|
||||
|
||||
/* network thread */
|
||||
pthread_t network_thread;
|
||||
|
||||
/* semaphorone */
|
||||
// network_sem_t network_sem;
|
||||
|
||||
/* function to call when connected to another Pizza Boy */
|
||||
network_cb_t network_connected_cb;
|
||||
network_cb_t network_disconnected_cb;
|
||||
|
||||
/* timeout to declare peer disconnected */
|
||||
uint8_t network_timeout = 10;
|
||||
|
||||
uint8_t prot = 0, pret = 0;
|
||||
|
||||
/* prototypes */
|
||||
void network_send_data(uint8_t v, uint8_t clock, uint8_t transfer_start);
|
||||
void *network_start_thread(void *args);
|
||||
|
||||
/* is network running? */
|
||||
char network_is_running()
|
||||
{
|
||||
return network_running;
|
||||
}
|
||||
|
||||
/* start network thread */
|
||||
void network_start(network_cb_t connected_cb, network_cb_t disconnected_cb,
|
||||
char *broadcast_addr)
|
||||
{
|
||||
/* init semaphore */
|
||||
// network_sem_init(&network_sem);
|
||||
|
||||
/* reset bool */
|
||||
network_running = 0;
|
||||
|
||||
/* set callback */
|
||||
network_connected_cb = connected_cb;
|
||||
network_disconnected_cb = disconnected_cb;
|
||||
|
||||
/* save broadcast addr */
|
||||
strncpy(network_broadcast_addr, broadcast_addr, 16);
|
||||
|
||||
/* start thread! */
|
||||
pthread_create(&network_thread, NULL, network_start_thread, NULL);
|
||||
}
|
||||
|
||||
/* stop network thread */
|
||||
void network_stop()
|
||||
{
|
||||
/* already stopped? */
|
||||
if (network_running == 0)
|
||||
return;
|
||||
|
||||
/* tell thread to stop */
|
||||
network_running = 0;
|
||||
|
||||
/* wait for it to exit */
|
||||
pthread_join(network_thread, NULL);
|
||||
}
|
||||
|
||||
void *network_start_thread(void *args)
|
||||
{
|
||||
utils_log("Starting network thread\n");
|
||||
|
||||
/* open socket sending broadcast messages */
|
||||
network_sock_broad = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
/* exit on error */
|
||||
if (network_sock_broad < 1)
|
||||
{
|
||||
utils_log("Error opening broadcast socket");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open socket sending/receiving serial cable data */
|
||||
network_sock_bound = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
/* exit on error */
|
||||
if (network_sock_bound < 1)
|
||||
{
|
||||
utils_log("Error opening serial-link socket");
|
||||
close (network_sock_broad);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* enable to broadcast */
|
||||
int enable=1;
|
||||
setsockopt(network_sock_broad, SOL_SOCKET, SO_BROADCAST,
|
||||
&enable, sizeof(enable));
|
||||
|
||||
/* prepare dest stuff */
|
||||
struct sockaddr_in broadcast_addr;
|
||||
struct sockaddr_in bound_addr;
|
||||
struct sockaddr_in addr_from;
|
||||
socklen_t addr_from_len = sizeof(addr_from);
|
||||
|
||||
memset(&broadcast_addr, 0, sizeof(broadcast_addr));
|
||||
broadcast_addr.sin_family = AF_INET;
|
||||
// broadcast_addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
// inet_aton("239.255.0.37",
|
||||
// (struct in_addr *) &broadcast_addr.sin_addr.s_addr);
|
||||
// inet_aton("192.168.100.255",
|
||||
inet_aton(network_broadcast_addr,
|
||||
(struct in_addr *) &broadcast_addr.sin_addr.s_addr);
|
||||
broadcast_addr.sin_port = htons(64333);
|
||||
|
||||
/* setup listening socket */
|
||||
memset(&bound_addr, 0, sizeof(bound_addr));
|
||||
bound_addr.sin_family = AF_INET;
|
||||
bound_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
bound_addr.sin_port = htons(64333);
|
||||
|
||||
/* bind to selected port */
|
||||
if (bind(network_sock_bound, (struct sockaddr *) &bound_addr,
|
||||
sizeof(bound_addr)))
|
||||
{
|
||||
utils_log("Error binding to port 64333");
|
||||
|
||||
/* close sockets and exit */
|
||||
close(network_sock_broad);
|
||||
close(network_sock_bound);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* assign it to our multicast group */
|
||||
/* struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr=inet_addr("239.255.0.37");
|
||||
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if (setsockopt(network_sock_bound, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
&mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
utils_log("Error joining multicast network");
|
||||
|
||||
close(network_sock_broad);
|
||||
close(network_sock_bound);
|
||||
|
||||
return NULL;
|
||||
}*/
|
||||
|
||||
fd_set rfds;
|
||||
char buf[64];
|
||||
int ret;
|
||||
ssize_t recv_ret;
|
||||
struct timeval tv;
|
||||
int timeouts = 4;
|
||||
// unsigned int v, clock, prog;
|
||||
|
||||
/* message parts */
|
||||
char msg_type;
|
||||
unsigned int msg_uuid;
|
||||
char msg_content[64];
|
||||
|
||||
/* generate a random uuid */
|
||||
srand(time(NULL));
|
||||
network_uuid = rand() & 0xFFFFFFFF;
|
||||
|
||||
/* set callback in case of data to send */
|
||||
serial_set_send_cb(&network_send_data);
|
||||
|
||||
/* declare network is running */
|
||||
network_running = 1;
|
||||
|
||||
utils_log("Network thread started\n");
|
||||
|
||||
/* loop forever */
|
||||
while (network_running)
|
||||
{
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(network_sock_bound, &rfds);
|
||||
|
||||
/* wait one second */
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/* one second timeout OR something received */
|
||||
ret = select(network_sock_bound + 1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
/* error! */
|
||||
if (ret == -1)
|
||||
break;
|
||||
|
||||
/* ret 0 = timeout */
|
||||
if (ret == 0)
|
||||
{
|
||||
if (++timeouts == 3)
|
||||
{
|
||||
/* build output message */
|
||||
sprintf(buf, "B%08x%s", network_uuid, global_cart_name);
|
||||
|
||||
/* send broadcast message */
|
||||
sendto(network_sock_broad, buf, strlen(buf), 0,
|
||||
(struct sockaddr *) &broadcast_addr,
|
||||
sizeof(broadcast_addr));
|
||||
|
||||
utils_log("Sending broadcast message %s\n", buf);
|
||||
|
||||
timeouts = 0;
|
||||
}
|
||||
|
||||
if (serial.peer_connected)
|
||||
{
|
||||
if (--network_timeout == 0)
|
||||
{
|
||||
/* notify serial module */
|
||||
serial.peer_connected = 0;
|
||||
|
||||
/* stop Hard Sync mode */
|
||||
cycles_stop_hs();
|
||||
|
||||
/* notify by the cb */
|
||||
if (network_disconnected_cb)
|
||||
(*network_disconnected_cb) ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reset message content */
|
||||
bzero(buf, sizeof(buf));
|
||||
bzero(msg_content, sizeof(msg_content));
|
||||
|
||||
/* exit if an error occour */
|
||||
if ((recv_ret = recvfrom(network_sock_bound, buf, 64, 0,
|
||||
(struct sockaddr *) &addr_from,
|
||||
(socklen_t *) &addr_from_len)) < 1)
|
||||
break;
|
||||
|
||||
/* extract message type (1st byte) */
|
||||
msg_type = buf[0];
|
||||
|
||||
/* is it broadcast? */
|
||||
//if (sscanf(buf, "%c%08x%s",
|
||||
// &msg_type, &msg_uuid, msg_content) == 3)
|
||||
// {
|
||||
/* was it send by myself? */
|
||||
// if (msg_uuid != network_uuid)
|
||||
// {
|
||||
|
||||
/* is it a serial data message? */
|
||||
if (msg_type == 'M')
|
||||
{
|
||||
network_prog_recv = (uint8_t) buf[3];
|
||||
|
||||
/* buf[1] contains value - buf[2] contains serial clock */
|
||||
/* tell serial module something has arrived */
|
||||
serial_recv_byte((uint8_t) buf[1], (uint8_t) buf[2], buf[4]);
|
||||
}
|
||||
else if (msg_type == 'B')
|
||||
{
|
||||
/* extract parts from broadcast message */
|
||||
sscanf(buf, "%c%08x%s", &msg_type, &msg_uuid, msg_content);
|
||||
|
||||
/* myself? */
|
||||
if (network_uuid == msg_uuid)
|
||||
continue;
|
||||
|
||||
/* not the same game? */
|
||||
if (strcmp(msg_content, global_cart_name) != 0)
|
||||
continue;
|
||||
|
||||
/* someone is claiming is playing with the same game? */
|
||||
if (serial.peer_connected == 0)
|
||||
{
|
||||
/* save peer uuid */
|
||||
network_peer_uuid = msg_uuid;
|
||||
|
||||
/* refresh timeout */
|
||||
network_timeout = 10;
|
||||
|
||||
/* save sender */
|
||||
memcpy(&network_peer_addr, &addr_from,
|
||||
sizeof(struct sockaddr_in));
|
||||
|
||||
/* just change dst port */
|
||||
network_peer_addr.sin_port = htons(64333);
|
||||
|
||||
/* notify the other peer by sending a b message */
|
||||
sprintf(buf, "B%08x%s", network_uuid,
|
||||
global_cart_name);
|
||||
|
||||
/* send broadcast message */
|
||||
sendto(network_sock_broad, buf, strlen(buf), 0,
|
||||
(struct sockaddr *) &network_peer_addr,
|
||||
sizeof(network_peer_addr));
|
||||
|
||||
/* log that peer is connected */
|
||||
utils_log("Peer connected: %s\n",
|
||||
inet_ntoa(network_peer_addr.sin_addr));
|
||||
|
||||
/* YEAH */
|
||||
serial.peer_connected = 1;
|
||||
|
||||
/* notify by the cb */
|
||||
if (network_connected_cb)
|
||||
(*network_connected_cb) ();
|
||||
|
||||
/* start hard sync */
|
||||
cycles_start_hs();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* refresh timeout */
|
||||
if (network_peer_uuid == msg_uuid)
|
||||
network_timeout = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free serial */
|
||||
serial.peer_connected = 0;
|
||||
|
||||
/* stop hard sync mode */
|
||||
cycles_stop_hs();
|
||||
|
||||
/* close sockets */
|
||||
close(network_sock_broad);
|
||||
close(network_sock_bound);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void network_send_data(uint8_t v, uint8_t clock, uint8_t transfer_start)
|
||||
{
|
||||
char msg[5];
|
||||
|
||||
/* format message */
|
||||
network_prog_sent = ((network_prog_sent + 1) & 0xff);
|
||||
|
||||
msg[0] = 'M';
|
||||
msg[1] = v;
|
||||
msg[2] = clock;
|
||||
msg[3] = network_prog_sent;
|
||||
msg[4] = transfer_start;
|
||||
|
||||
if (network_prog_sent != network_prog_recv &&
|
||||
network_prog_sent != (uint8_t) (network_prog_recv + 1))
|
||||
global_quit = 1;
|
||||
|
||||
/* send */
|
||||
sendto(network_sock_bound, msg, 5, 0,
|
||||
(struct sockaddr *) &network_peer_addr, sizeof(network_peer_addr));
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
|
||||
This file is part of Emu-Pizza
|
||||
|
||||
Emu-Pizza is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Emu-Pizza is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Emu-Pizza. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NETWORK_HDR__
|
||||
#define __NETWORK_HDR__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* callback function */
|
||||
typedef void (*network_cb_t) ();
|
||||
|
||||
/* prototypes */
|
||||
char network_is_running();
|
||||
void network_start(network_cb_t connected_cb,
|
||||
network_cb_t disconnected_cb,
|
||||
char *broadcast_addr);
|
||||
void network_stop();
|
||||
|
||||
#endif
|
|
@ -92,16 +92,6 @@ void serial_init()
|
|||
pthread_cond_init(&serial_cond, NULL);
|
||||
}
|
||||
|
||||
void serial_save_stat(FILE *fp)
|
||||
{
|
||||
fwrite(&serial, 1, sizeof(serial_t), fp);
|
||||
}
|
||||
|
||||
void serial_restore_stat(FILE *fp)
|
||||
{
|
||||
fread(&serial, 1, sizeof(serial_t), fp);
|
||||
}
|
||||
|
||||
void serial_write_reg(uint16_t a, uint8_t v)
|
||||
{
|
||||
/* lock the serial */
|
||||
|
|
|
@ -88,10 +88,8 @@ void serial_verify_intr();
|
|||
uint8_t serial_read_reg(uint16_t a);
|
||||
void serial_recv_byte(uint8_t v, uint8_t clock, uint8_t transfer_start);
|
||||
void serial_recv_clock();
|
||||
void serial_save_stat(FILE *fp);
|
||||
void serial_send_byte();
|
||||
void serial_set_send_cb(serial_data_send_cb_t cb);
|
||||
void serial_restore_stat(FILE *fp);
|
||||
void serial_unlock();
|
||||
void serial_wait_data();
|
||||
|
||||
|
|
|
@ -25,16 +25,10 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* semaphore for audio sync */
|
||||
pthread_cond_t sound_cond;
|
||||
pthread_mutex_t sound_mutex;
|
||||
|
||||
/* super variable for audio controller */
|
||||
sound_t sound;
|
||||
|
||||
|
@ -109,10 +103,6 @@ void sound_init()
|
|||
sound.buf_rd = 0;
|
||||
sound.buf_available = 0;
|
||||
|
||||
/* init semaphore for sync */
|
||||
pthread_mutex_init(&sound_mutex, NULL);
|
||||
pthread_cond_init(&sound_cond, NULL);
|
||||
|
||||
/* how many cpu cycles we need to emit a 512hz clock (frame sequencer) */
|
||||
sound.fs_cycles = 4194304 / 512;
|
||||
|
||||
|
@ -125,9 +115,6 @@ void sound_init()
|
|||
|
||||
sound.sample_cycles_next = sound.sample_cycles / 1000;
|
||||
sound.sample_cycles_next_rounded = sound.sample_cycles_next & 0xFFFFFFFC;
|
||||
|
||||
/* init multiplier */
|
||||
sound.frame_multiplier = 1;
|
||||
|
||||
/* no, i'm not empty */
|
||||
sound.buf_empty = 0;
|
||||
|
@ -149,16 +136,6 @@ void sound_set_speed(char dbl)
|
|||
}
|
||||
}
|
||||
|
||||
void sound_change_emulation_speed()
|
||||
{
|
||||
if (global_emulation_speed == GLOBAL_EMULATION_SPEED_HALF)
|
||||
sound.frame_multiplier = 2;
|
||||
else if (global_emulation_speed == GLOBAL_EMULATION_SPEED_QUARTER)
|
||||
sound.frame_multiplier = 4;
|
||||
else
|
||||
sound.frame_multiplier = 1;
|
||||
}
|
||||
|
||||
/* update sound internal state given CPU T-states */
|
||||
void sound_step_fs()
|
||||
{
|
||||
|
@ -276,13 +253,6 @@ void sound_step_sample()
|
|||
/* update output frame counter */
|
||||
sound.frame_counter++;
|
||||
|
||||
/* is it the case to push samples? */
|
||||
if (((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE &&
|
||||
(sound.frame_counter & 0x0001) != 0) ||
|
||||
(global_emulation_speed == GLOBAL_EMULATION_SPEED_4X &&
|
||||
(sound.frame_counter & 0x0003) != 0)))
|
||||
return;
|
||||
|
||||
/* DAC turned off? */
|
||||
if (sound.nr30->dac == 0 &&
|
||||
sound.channel_one.active == 0 &&
|
||||
|
@ -369,13 +339,8 @@ void sound_step_sample()
|
|||
sample_left += sound.channel_four.sample;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0; i<sound.frame_multiplier; i++)
|
||||
{
|
||||
/* push the sum of all channels samples */
|
||||
sound_push_samples(sample_left, sample_right);
|
||||
}
|
||||
}
|
||||
|
||||
/* update length of channel1 */
|
||||
|
@ -1470,15 +1435,3 @@ void sound_term()
|
|||
pthread_cond_signal(&sound_cond);
|
||||
}
|
||||
}
|
||||
|
||||
void sound_save_stat(FILE *fp)
|
||||
{
|
||||
fwrite(&sound, 1, sizeof(sound_t), fp);
|
||||
}
|
||||
|
||||
void sound_restore_stat(FILE *fp)
|
||||
{
|
||||
fread(&sound, 1, sizeof(sound_t), fp);
|
||||
|
||||
sound_init_pointers();
|
||||
}
|
||||
|
|
|
@ -277,7 +277,6 @@ typedef struct sound_s
|
|||
|
||||
/* emulation speed stuff */
|
||||
uint_fast16_t frame_counter;
|
||||
uint_fast16_t frame_multiplier;
|
||||
|
||||
/* circular audio buffer stuff */
|
||||
uint_fast16_t buf_rd;
|
||||
|
@ -318,8 +317,6 @@ int sound_get_samples();
|
|||
void sound_init();
|
||||
void sound_read_buffer(void *userdata, uint8_t *stream, int snd_len);
|
||||
uint8_t sound_read_reg(uint16_t a, uint8_t v);
|
||||
void sound_restore_stat(FILE *fp);
|
||||
void sound_save_stat(FILE *fp);
|
||||
void sound_set_speed(char dbl);
|
||||
void sound_set_output_rate(int freq);
|
||||
void sound_step_fs();
|
||||
|
|
|
@ -106,34 +106,3 @@ void utils_ts_log(const char *format, ...)
|
|||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void utils_binary_sem_init(utils_binary_sem_t *p)
|
||||
{
|
||||
pthread_mutex_init(&p->mutex, NULL);
|
||||
pthread_cond_init(&p->cvar, NULL);
|
||||
p->v = 0;
|
||||
}
|
||||
|
||||
void utils_binary_sem_post(utils_binary_sem_t *p)
|
||||
{
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
p->v = 1;
|
||||
pthread_cond_signal(&p->cvar);
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
}
|
||||
|
||||
void utils_binary_sem_wait(utils_binary_sem_t *p, unsigned int nanosecs)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = time(NULL) + nanosecs / 1000000000;
|
||||
ts.tv_nsec = nanosecs % 1000000000;
|
||||
|
||||
pthread_mutex_lock(&p->mutex);
|
||||
while (!p->v)
|
||||
if (pthread_cond_timedwait(&p->cvar, &p->mutex, &ts) == ETIMEDOUT)
|
||||
break;
|
||||
p->v = 0;
|
||||
pthread_mutex_unlock(&p->mutex);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,21 +20,6 @@
|
|||
#ifndef __UTILS_HDR__
|
||||
#define __UTILS_HDR__
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/* binary semaphore */
|
||||
typedef struct utils_binary_sem_s
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cvar;
|
||||
int v;
|
||||
|
||||
} utils_binary_sem_t;
|
||||
|
||||
/* prototypes */
|
||||
void utils_binary_sem_init(utils_binary_sem_t *p);
|
||||
void utils_binary_sem_post(utils_binary_sem_t *p);
|
||||
void utils_binary_sem_wait(utils_binary_sem_t *p, unsigned int nanosecs);
|
||||
void utils_log(const char *format, ...);
|
||||
void utils_log_urgent(const char *format, ...);
|
||||
void utils_ts_log(const char *format, ...);
|
||||
|
|
Loading…
Reference in New Issue