mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
Merge pull request #114 from Clownacy/master
Added SDL2 build, cleaned up original SDL build, and added 32MB ROM support to both
This commit is contained in:
commit
8feabd5eaf
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,5 +4,7 @@ psp2/*.velf
|
||||
psp2/build_vita/*
|
||||
psp2/*.a
|
||||
sdl/gen_sdl
|
||||
sdl/gen_sdl2
|
||||
sdl/build_sdl
|
||||
sdl/build_sdl2
|
||||
|
||||
|
@ -19,21 +19,21 @@
|
||||
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
|
||||
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
NAME = gen_sdl.exe
|
||||
else
|
||||
NAME = gen_sdl
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing -ansi -std=c99 -pedantic-errors
|
||||
#-g -ggdb -pg
|
||||
#-fomit-frame-pointer
|
||||
#LDFLAGS = -pg
|
||||
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DUSE_LIBTREMOR
|
||||
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DUSE_LIBTREMOR -DMAXROMSIZE=33554432
|
||||
|
||||
ifneq ($(OS),Windows_NT)
|
||||
DEFINES += -DHAVE_ALLOCA_H
|
||||
endif
|
||||
|
||||
SRCDIR = ../core
|
||||
INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/z80 -I$(SRCDIR)/m68k -I$(SRCDIR)/sound -I$(SRCDIR)/input_hw -I$(SRCDIR)/cart_hw -I$(SRCDIR)/cart_hw/svp -I$(SRCDIR)/cd_hw -I$(SRCDIR)/ntsc -I$(SRCDIR)/tremor -I$(SRCDIR)/../sdl
|
||||
INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/z80 -I$(SRCDIR)/m68k -I$(SRCDIR)/sound -I$(SRCDIR)/input_hw -I$(SRCDIR)/cart_hw -I$(SRCDIR)/cart_hw/svp -I$(SRCDIR)/cd_hw -I$(SRCDIR)/ntsc -I$(SRCDIR)/tremor -I$(SRCDIR)/../sdl -I$(SRCDIR)/../sdl/sdl1
|
||||
LIBS = `sdl-config --libs` -lz -lm
|
||||
|
||||
OBJDIR = ./build_sdl
|
||||
@ -169,6 +169,9 @@ $(OBJDIR)/%.o : $(SRCDIR)/tremor/%.c
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/../sdl/%.c $(SRCDIR)/../sdl/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/../sdl/sdl1/%.c $(SRCDIR)/../sdl/sdl1/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(OBJDIR)/icon.o :
|
||||
windres $(SRCDIR)/../sdl/icon.rc $@
|
185
sdl/Makefile.sdl2
Normal file
185
sdl/Makefile.sdl2
Normal file
@ -0,0 +1,185 @@
|
||||
|
||||
# Makefile for genplus SDL2
|
||||
#
|
||||
# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
||||
# modified by Eke-Eke <eke_eke31@yahoo.fr>
|
||||
#
|
||||
# Defines :
|
||||
# -DLSB_FIRST : for little endian systems.
|
||||
# -DLOGERROR : enable message logging
|
||||
# -DLOGVDP : enable VDP debug messages
|
||||
# -DLOGSOUND : enable AUDIO debug messages
|
||||
# -DLOG_SCD : enable SCD debug messages
|
||||
# -DLOG_CDD : enable CDD debug messages
|
||||
# -DLOG_CDC : enable CDC debug messages
|
||||
# -DLOG_PCM : enable PCM debug messages
|
||||
# -DLOGSOUND : enable AUDIO debug messages
|
||||
# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332)
|
||||
# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555)
|
||||
# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565)
|
||||
# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888)
|
||||
|
||||
NAME = gen_sdl2
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = `sdl2-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing -ansi -std=c99 -pedantic-errors
|
||||
#-g -ggdb -pg
|
||||
#-fomit-frame-pointer
|
||||
#LDFLAGS = -pg
|
||||
DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DUSE_LIBTREMOR -DMAXROMSIZE=33554432
|
||||
|
||||
ifneq ($(OS),Windows_NT)
|
||||
DEFINES += -DHAVE_ALLOCA_H
|
||||
endif
|
||||
|
||||
SRCDIR = ../core
|
||||
INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/z80 -I$(SRCDIR)/m68k -I$(SRCDIR)/sound -I$(SRCDIR)/input_hw -I$(SRCDIR)/cart_hw -I$(SRCDIR)/cart_hw/svp -I$(SRCDIR)/cd_hw -I$(SRCDIR)/ntsc -I$(SRCDIR)/tremor -I$(SRCDIR)/../sdl -I$(SRCDIR)/../sdl/sdl2
|
||||
LIBS = `sdl2-config --libs` -lz -lm
|
||||
|
||||
OBJDIR = ./build_sdl2
|
||||
|
||||
OBJECTS = $(OBJDIR)/z80.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/m68kcpu.o \
|
||||
$(OBJDIR)/s68kcpu.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/genesis.o \
|
||||
$(OBJDIR)/vdp_ctrl.o \
|
||||
$(OBJDIR)/vdp_render.o \
|
||||
$(OBJDIR)/system.o \
|
||||
$(OBJDIR)/io_ctrl.o \
|
||||
$(OBJDIR)/mem68k.o \
|
||||
$(OBJDIR)/memz80.o \
|
||||
$(OBJDIR)/membnk.o \
|
||||
$(OBJDIR)/state.o \
|
||||
$(OBJDIR)/loadrom.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/input.o \
|
||||
$(OBJDIR)/gamepad.o \
|
||||
$(OBJDIR)/lightgun.o \
|
||||
$(OBJDIR)/mouse.o \
|
||||
$(OBJDIR)/activator.o \
|
||||
$(OBJDIR)/xe_1ap.o \
|
||||
$(OBJDIR)/teamplayer.o \
|
||||
$(OBJDIR)/paddle.o \
|
||||
$(OBJDIR)/sportspad.o \
|
||||
$(OBJDIR)/terebi_oekaki.o \
|
||||
$(OBJDIR)/graphic_board.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/sound.o \
|
||||
$(OBJDIR)/sn76489.o \
|
||||
$(OBJDIR)/ym2413.o \
|
||||
$(OBJDIR)/ym2612.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/blip_buf.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/eq.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/sram.o \
|
||||
$(OBJDIR)/svp.o \
|
||||
$(OBJDIR)/ssp16.o \
|
||||
$(OBJDIR)/ggenie.o \
|
||||
$(OBJDIR)/areplay.o \
|
||||
$(OBJDIR)/eeprom_93c.o \
|
||||
$(OBJDIR)/eeprom_i2c.o \
|
||||
$(OBJDIR)/eeprom_spi.o \
|
||||
$(OBJDIR)/md_cart.o \
|
||||
$(OBJDIR)/sms_cart.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/scd.o \
|
||||
$(OBJDIR)/cdd.o \
|
||||
$(OBJDIR)/cdc.o \
|
||||
$(OBJDIR)/gfx.o \
|
||||
$(OBJDIR)/pcm.o \
|
||||
$(OBJDIR)/cd_cart.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/sms_ntsc.o \
|
||||
$(OBJDIR)/md_ntsc.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/main.o \
|
||||
$(OBJDIR)/config.o \
|
||||
$(OBJDIR)/error.o \
|
||||
$(OBJDIR)/unzip.o \
|
||||
$(OBJDIR)/fileio.o
|
||||
|
||||
OBJECTS += $(OBJDIR)/bitwise.o \
|
||||
$(OBJDIR)/block.o \
|
||||
$(OBJDIR)/codebook.o \
|
||||
$(OBJDIR)/floor0.o \
|
||||
$(OBJDIR)/floor1.o \
|
||||
$(OBJDIR)/framing.o \
|
||||
$(OBJDIR)/info.o \
|
||||
$(OBJDIR)/mapping0.o \
|
||||
$(OBJDIR)/mdct.o \
|
||||
$(OBJDIR)/registry.o \
|
||||
$(OBJDIR)/res012.o \
|
||||
$(OBJDIR)/sharedbook.o \
|
||||
$(OBJDIR)/synthesis.o \
|
||||
$(OBJDIR)/vorbisfile.o \
|
||||
$(OBJDIR)/window.o
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
OBJECTS += $(OBJDIR)/icon.o
|
||||
endif
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
$(NAME): $(OBJDIR) $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
||||
|
||||
$(OBJDIR) :
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/sound/%.c $(SRCDIR)/sound/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/input_hw/%.c $(SRCDIR)/input_hw/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/%.c $(SRCDIR)/cart_hw/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/svp/%.c
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/svp/%.c $(SRCDIR)/cart_hw/svp/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/cd_hw/%.c $(SRCDIR)/cd_hw/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/z80/%.c $(SRCDIR)/z80/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/m68k/%.c
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/ntsc/%.c $(SRCDIR)/ntsc/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/tremor/%.c $(SRCDIR)/tremor/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/tremor/%.c
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/../sdl/%.c $(SRCDIR)/../sdl/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o : $(SRCDIR)/../sdl/sdl2/%.c $(SRCDIR)/../sdl/sdl2/%.h
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
$(OBJDIR)/icon.o :
|
||||
windres $(SRCDIR)/../sdl/icon.rc $@
|
||||
endif
|
||||
|
||||
pack :
|
||||
strip $(NAME)
|
||||
upx -9 $(NAME)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(NAME)
|
@ -9,7 +9,7 @@ PLEASE DO NOT DISTRIBUTE WIN32 BINARIES WITHOUT THIS NOTICE.
|
||||
END USERS SHOULD PREFERABLY USE LIBRETRO PORT WITH RETROARCH.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Genesis Plus (Windows Port)
|
||||
Genesis Plus (SDL Port)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
based on the original version 1.3
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define SOUND_FREQUENCY 48000
|
||||
#define SOUND_SAMPLES_SIZE 2048
|
||||
|
||||
#define VIDEO_WIDTH 320
|
||||
#define VIDEO_WIDTH 320
|
||||
#define VIDEO_HEIGHT 240
|
||||
|
||||
int joynum = 0;
|
||||
@ -67,7 +67,7 @@ static int sdl_sound_init()
|
||||
{
|
||||
int n;
|
||||
SDL_AudioSpec as_desired, as_obtained;
|
||||
|
||||
|
||||
if(SDL_Init(SDL_INIT_AUDIO) < 0) {
|
||||
MessageBox(NULL, "SDL Audio initialization failed", "Error", 0);
|
||||
return 0;
|
||||
@ -104,7 +104,7 @@ static int sdl_sound_init()
|
||||
static void sdl_sound_update(int enabled)
|
||||
{
|
||||
int size = audio_update(soundframe) * 2;
|
||||
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
int i;
|
||||
@ -126,7 +126,7 @@ static void sdl_sound_close()
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
if (sdl_sound.buffer)
|
||||
if (sdl_sound.buffer)
|
||||
free(sdl_sound.buffer);
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ static void sdl_video_update()
|
||||
sdl_video.drect.h = sdl_video.srect.h;
|
||||
sdl_video.drect.x = (VIDEO_WIDTH - sdl_video.drect.w) / 2;
|
||||
sdl_video.drect.y = (VIDEO_HEIGHT - sdl_video.drect.h) / 2;
|
||||
|
||||
|
||||
/* clear destination surface */
|
||||
SDL_FillRect(sdl_video.surf_screen, 0, 0);
|
||||
|
||||
@ -304,7 +304,7 @@ static void sdl_sync_close()
|
||||
SDL_DestroySemaphore(sdl_sync.sem_sync);
|
||||
}
|
||||
|
||||
static const uint16 vc_table[4][2] =
|
||||
static const uint16 vc_table[4][2] =
|
||||
{
|
||||
/* NTSC, PAL */
|
||||
{0xDA , 0xF2}, /* Mode 4 (192 lines) */
|
||||
@ -332,8 +332,7 @@ static int sdl_control_update(SDLKey keystate)
|
||||
|
||||
case SDLK_F2:
|
||||
{
|
||||
if (fullscreen) fullscreen = 0;
|
||||
else fullscreen = SDL_FULLSCREEN;
|
||||
fullscreen = (fullscreen ? 0 : SDL_FULLSCREEN);
|
||||
sdl_video.surf_screen = SDL_SetVideoMode(VIDEO_WIDTH, VIDEO_HEIGHT, 16, SDL_SWSURFACE | fullscreen);
|
||||
break;
|
||||
}
|
||||
@ -497,7 +496,7 @@ int sdl_input_update(void)
|
||||
|
||||
/* reset input */
|
||||
input.pad[joynum] = 0;
|
||||
|
||||
|
||||
switch (input.dev[joynum])
|
||||
{
|
||||
case DEVICE_LIGHTGUN:
|
||||
@ -515,7 +514,7 @@ int sdl_input_update(void)
|
||||
/* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_A;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_B;
|
||||
if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_C;
|
||||
if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_C;
|
||||
if(keystate[SDLK_f]) input.pad[joynum] |= INPUT_START;
|
||||
break;
|
||||
}
|
||||
@ -586,7 +585,7 @@ int sdl_input_update(void)
|
||||
if(keystate[SDLK_x]) input.pad[joynum] |= INPUT_X;
|
||||
if(keystate[SDLK_c]) input.pad[joynum] |= INPUT_MODE;
|
||||
if(keystate[SDLK_v]) input.pad[joynum] |= INPUT_Z;
|
||||
|
||||
|
||||
/* Left Analog Stick (bidirectional) */
|
||||
if(keystate[SDLK_UP]) input.analog[joynum][1]-=2;
|
||||
else if(keystate[SDLK_DOWN]) input.analog[joynum][1]+=2;
|
||||
@ -624,7 +623,7 @@ int sdl_input_update(void)
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = 0x3c + (x * (0x17c-0x03c+1)) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = 0x1fc + (y * (0x2f7-0x1fc+1)) / VIDEO_HEIGHT;
|
||||
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_MMASK) pico_current = (pico_current + 1) & 7;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_PICO_RED;
|
||||
@ -642,7 +641,7 @@ int sdl_input_update(void)
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = (x * 250) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = (y * 250) / VIDEO_HEIGHT;
|
||||
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_B;
|
||||
|
||||
@ -658,7 +657,7 @@ int sdl_input_update(void)
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = (x * 255) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = (y * 255) / VIDEO_HEIGHT;
|
||||
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[0] |= INPUT_GRAPHIC_PEN;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_GRAPHIC_MENU;
|
||||
@ -711,7 +710,7 @@ int main (int argc, char **argv)
|
||||
char caption[256];
|
||||
sprintf(caption, "Genesis Plus GX\\SDL\nusage: %s gamename\n", argv[0]);
|
||||
MessageBox(NULL, caption, "Information", 0);
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set default config */
|
||||
@ -751,10 +750,8 @@ int main (int argc, char **argv)
|
||||
/* initialize SDL */
|
||||
if(SDL_Init(0) < 0)
|
||||
{
|
||||
char caption[256];
|
||||
sprintf(caption, "SDL initialization failed");
|
||||
MessageBox(NULL, caption, "Error", 0);
|
||||
exit(1);
|
||||
MessageBox(NULL, "SDL initialization failed", "Error", 0);
|
||||
return 1;
|
||||
}
|
||||
sdl_video_init();
|
||||
if (use_sound) sdl_sound_init();
|
||||
@ -784,7 +781,7 @@ int main (int argc, char **argv)
|
||||
char caption[256];
|
||||
sprintf(caption, "Error loading file `%s'.", argv[1]);
|
||||
MessageBox(NULL, caption, "Error", 0);
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* initialize system hardware */
|
||||
@ -866,13 +863,13 @@ int main (int argc, char **argv)
|
||||
while(running)
|
||||
{
|
||||
SDL_Event event;
|
||||
if (SDL_PollEvent(&event))
|
||||
if (SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_USEREVENT:
|
||||
{
|
||||
char caption[100];
|
||||
char caption[100];
|
||||
sprintf(caption,"Genesis Plus GX - %d fps - %s", event.user.code, (rominfo.international[0] != 0x20) ? rominfo.international : rominfo.domestic);
|
||||
SDL_WM_SetCaption(caption, NULL);
|
||||
break;
|
945
sdl/sdl2/main.c
Normal file
945
sdl/sdl2/main.c
Normal file
@ -0,0 +1,945 @@
|
||||
#include "SDL.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#include "shared.h"
|
||||
#include "sms_ntsc.h"
|
||||
#include "md_ntsc.h"
|
||||
|
||||
#define SOUND_FREQUENCY 48000
|
||||
#define SOUND_SAMPLES_SIZE 2048
|
||||
|
||||
#define VIDEO_WIDTH 320
|
||||
#define VIDEO_HEIGHT 240
|
||||
|
||||
int joynum = 0;
|
||||
|
||||
int log_error = 0;
|
||||
int debug_on = 0;
|
||||
int turbo_mode = 0;
|
||||
int use_sound = 1;
|
||||
int fullscreen = 0; /* SDL_WINDOW_FULLSCREEN */
|
||||
|
||||
struct {
|
||||
SDL_Window* window;
|
||||
SDL_Surface* surf_screen;
|
||||
SDL_Surface* surf_bitmap;
|
||||
SDL_Rect srect;
|
||||
SDL_Rect drect;
|
||||
Uint32 frames_rendered;
|
||||
} sdl_video;
|
||||
|
||||
/* sound */
|
||||
|
||||
struct {
|
||||
char* current_pos;
|
||||
char* buffer;
|
||||
int current_emulated_samples;
|
||||
} sdl_sound;
|
||||
|
||||
|
||||
static uint8 brm_format[0x40] =
|
||||
{
|
||||
0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00,
|
||||
0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f
|
||||
};
|
||||
|
||||
|
||||
static short soundframe[SOUND_SAMPLES_SIZE];
|
||||
|
||||
static void sdl_sound_callback(void *userdata, Uint8 *stream, int len)
|
||||
{
|
||||
if(sdl_sound.current_emulated_samples < len) {
|
||||
memset(stream, 0, len);
|
||||
}
|
||||
else {
|
||||
memcpy(stream, sdl_sound.buffer, len);
|
||||
/* loop to compensate desync */
|
||||
do {
|
||||
sdl_sound.current_emulated_samples -= len;
|
||||
} while(sdl_sound.current_emulated_samples > 2 * len);
|
||||
memcpy(sdl_sound.buffer,
|
||||
sdl_sound.current_pos - sdl_sound.current_emulated_samples,
|
||||
sdl_sound.current_emulated_samples);
|
||||
sdl_sound.current_pos = sdl_sound.buffer + sdl_sound.current_emulated_samples;
|
||||
}
|
||||
}
|
||||
|
||||
static int sdl_sound_init()
|
||||
{
|
||||
int n;
|
||||
SDL_AudioSpec as_desired, as_obtained;
|
||||
|
||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL Audio initialization failed", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
as_desired.freq = SOUND_FREQUENCY;
|
||||
as_desired.format = AUDIO_S16LSB;
|
||||
as_desired.channels = 2;
|
||||
as_desired.samples = SOUND_SAMPLES_SIZE;
|
||||
as_desired.callback = sdl_sound_callback;
|
||||
|
||||
if(SDL_OpenAudio(&as_desired, &as_obtained) == -1) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL Audio open failed", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(as_desired.samples != as_obtained.samples) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL Audio wrong setup", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdl_sound.current_emulated_samples = 0;
|
||||
n = SOUND_SAMPLES_SIZE * 2 * sizeof(short) * 20;
|
||||
sdl_sound.buffer = (char*)malloc(n);
|
||||
if(!sdl_sound.buffer) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can't allocate audio buffer", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
memset(sdl_sound.buffer, 0, n);
|
||||
sdl_sound.current_pos = sdl_sound.buffer;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sdl_sound_update(int enabled)
|
||||
{
|
||||
int size = audio_update(soundframe) * 2;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
int i;
|
||||
short *out;
|
||||
|
||||
SDL_LockAudio();
|
||||
out = (short*)sdl_sound.current_pos;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
*out++ = soundframe[i];
|
||||
}
|
||||
sdl_sound.current_pos = (char*)out;
|
||||
sdl_sound.current_emulated_samples += size * sizeof(short);
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
}
|
||||
|
||||
static void sdl_sound_close()
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
if (sdl_sound.buffer)
|
||||
free(sdl_sound.buffer);
|
||||
}
|
||||
|
||||
/* video */
|
||||
md_ntsc_t *md_ntsc;
|
||||
sms_ntsc_t *sms_ntsc;
|
||||
|
||||
static int sdl_video_init()
|
||||
{
|
||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL Video initialization failed", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
sdl_video.window = SDL_CreateWindow("Genesis Plus GX", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, VIDEO_WIDTH, VIDEO_HEIGHT, 0);
|
||||
sdl_video.surf_screen = SDL_GetWindowSurface(sdl_video.window);
|
||||
sdl_video.surf_bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, 720, 576, 16, 0, 0, 0, 0);
|
||||
sdl_video.frames_rendered = 0;
|
||||
SDL_ShowCursor(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sdl_video_update()
|
||||
{
|
||||
if (system_hw == SYSTEM_MCD)
|
||||
{
|
||||
system_frame_scd(0);
|
||||
}
|
||||
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
system_frame_gen(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
system_frame_sms(0);
|
||||
}
|
||||
|
||||
/* viewport size changed */
|
||||
if(bitmap.viewport.changed & 1)
|
||||
{
|
||||
bitmap.viewport.changed &= ~1;
|
||||
|
||||
/* source bitmap */
|
||||
sdl_video.srect.w = bitmap.viewport.w+2*bitmap.viewport.x;
|
||||
sdl_video.srect.h = bitmap.viewport.h+2*bitmap.viewport.y;
|
||||
sdl_video.srect.x = 0;
|
||||
sdl_video.srect.y = 0;
|
||||
if (sdl_video.srect.w > VIDEO_WIDTH)
|
||||
{
|
||||
sdl_video.srect.x = (sdl_video.srect.w - VIDEO_WIDTH) / 2;
|
||||
sdl_video.srect.w = VIDEO_WIDTH;
|
||||
}
|
||||
if (sdl_video.srect.h > VIDEO_HEIGHT)
|
||||
{
|
||||
sdl_video.srect.y = (sdl_video.srect.h - VIDEO_HEIGHT) / 2;
|
||||
sdl_video.srect.h = VIDEO_HEIGHT;
|
||||
}
|
||||
|
||||
/* destination bitmap */
|
||||
sdl_video.drect.w = sdl_video.srect.w;
|
||||
sdl_video.drect.h = sdl_video.srect.h;
|
||||
sdl_video.drect.x = (VIDEO_WIDTH - sdl_video.drect.w) / 2;
|
||||
sdl_video.drect.y = (VIDEO_HEIGHT - sdl_video.drect.h) / 2;
|
||||
|
||||
/* clear destination surface */
|
||||
SDL_FillRect(sdl_video.surf_screen, 0, 0);
|
||||
|
||||
#if 0
|
||||
if (config.render && (interlaced || config.ntsc)) rect.h *= 2;
|
||||
if (config.ntsc) rect.w = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(rect.w) : SMS_NTSC_OUT_WIDTH(rect.w);
|
||||
if (config.ntsc)
|
||||
{
|
||||
sms_ntsc = (sms_ntsc_t *)malloc(sizeof(sms_ntsc_t));
|
||||
md_ntsc = (md_ntsc_t *)malloc(sizeof(md_ntsc_t));
|
||||
|
||||
switch (config.ntsc)
|
||||
{
|
||||
case 1:
|
||||
sms_ntsc_init(sms_ntsc, &sms_ntsc_composite);
|
||||
md_ntsc_init(md_ntsc, &md_ntsc_composite);
|
||||
break;
|
||||
case 2:
|
||||
sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo);
|
||||
md_ntsc_init(md_ntsc, &md_ntsc_svideo);
|
||||
break;
|
||||
case 3:
|
||||
sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb);
|
||||
md_ntsc_init(md_ntsc, &md_ntsc_rgb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sms_ntsc)
|
||||
{
|
||||
free(sms_ntsc);
|
||||
sms_ntsc = NULL;
|
||||
}
|
||||
|
||||
if (md_ntsc)
|
||||
{
|
||||
free(md_ntsc);
|
||||
md_ntsc = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_BlitSurface(sdl_video.surf_bitmap, &sdl_video.srect, sdl_video.surf_screen, &sdl_video.drect);
|
||||
SDL_UpdateWindowSurface(sdl_video.window);
|
||||
|
||||
++sdl_video.frames_rendered;
|
||||
}
|
||||
|
||||
static void sdl_video_close()
|
||||
{
|
||||
if (sdl_video.surf_bitmap)
|
||||
SDL_FreeSurface(sdl_video.surf_bitmap);
|
||||
if (sdl_video.surf_screen)
|
||||
SDL_FreeSurface(sdl_video.surf_screen);
|
||||
}
|
||||
|
||||
/* Timer Sync */
|
||||
|
||||
struct {
|
||||
SDL_sem* sem_sync;
|
||||
unsigned ticks;
|
||||
} sdl_sync;
|
||||
|
||||
static Uint32 sdl_sync_timer_callback(Uint32 interval, void *param)
|
||||
{
|
||||
SDL_SemPost(sdl_sync.sem_sync);
|
||||
sdl_sync.ticks++;
|
||||
if (sdl_sync.ticks == (vdp_pal ? 50 : 20))
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_UserEvent userevent;
|
||||
|
||||
userevent.type = SDL_USEREVENT;
|
||||
userevent.code = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
|
||||
userevent.data1 = NULL;
|
||||
userevent.data2 = NULL;
|
||||
sdl_sync.ticks = sdl_video.frames_rendered = 0;
|
||||
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user = userevent;
|
||||
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
return interval;
|
||||
}
|
||||
|
||||
static int sdl_sync_init()
|
||||
{
|
||||
if(SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_EVENTS) < 0)
|
||||
{
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL Timer initialization failed", sdl_video.window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdl_sync.sem_sync = SDL_CreateSemaphore(0);
|
||||
sdl_sync.ticks = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sdl_sync_close()
|
||||
{
|
||||
if(sdl_sync.sem_sync)
|
||||
SDL_DestroySemaphore(sdl_sync.sem_sync);
|
||||
}
|
||||
|
||||
static const uint16 vc_table[4][2] =
|
||||
{
|
||||
/* NTSC, PAL */
|
||||
{0xDA , 0xF2}, /* Mode 4 (192 lines) */
|
||||
{0xEA , 0x102}, /* Mode 5 (224 lines) */
|
||||
{0xDA , 0xF2}, /* Mode 4 (192 lines) */
|
||||
{0x106, 0x10A} /* Mode 5 (240 lines) */
|
||||
};
|
||||
|
||||
static int sdl_control_update(SDL_Keycode keystate)
|
||||
{
|
||||
switch (keystate)
|
||||
{
|
||||
case SDLK_TAB:
|
||||
{
|
||||
system_reset();
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F1:
|
||||
{
|
||||
if (SDL_ShowCursor(-1)) SDL_ShowCursor(0);
|
||||
else SDL_ShowCursor(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F2:
|
||||
{
|
||||
fullscreen = (fullscreen ? 0 : SDL_WINDOW_FULLSCREEN);
|
||||
SDL_SetWindowFullscreen(sdl_video.window, fullscreen);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F3:
|
||||
{
|
||||
if (config.bios == 0) config.bios = 3;
|
||||
else if (config.bios == 3) config.bios = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F4:
|
||||
{
|
||||
if (!turbo_mode) use_sound ^= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F5:
|
||||
{
|
||||
log_error ^= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F6:
|
||||
{
|
||||
if (!use_sound)
|
||||
{
|
||||
turbo_mode ^=1;
|
||||
sdl_sync.ticks = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F7:
|
||||
{
|
||||
FILE *f = fopen("game.gp0","rb");
|
||||
if (f)
|
||||
{
|
||||
uint8 buf[STATE_SIZE];
|
||||
fread(&buf, STATE_SIZE, 1, f);
|
||||
state_load(buf);
|
||||
fclose(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F8:
|
||||
{
|
||||
FILE *f = fopen("game.gp0","wb");
|
||||
if (f)
|
||||
{
|
||||
uint8 buf[STATE_SIZE];
|
||||
int len = state_save(buf);
|
||||
fwrite(&buf, len, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F9:
|
||||
{
|
||||
config.region_detect = (config.region_detect + 1) % 5;
|
||||
get_region(0);
|
||||
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
audio_init(snd.sample_rate, 0);
|
||||
|
||||
/* system with region BIOS should be reinitialized */
|
||||
if ((system_hw == SYSTEM_MCD) || ((system_hw & SYSTEM_SMS) && (config.bios & 1)))
|
||||
{
|
||||
system_init();
|
||||
system_reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reinitialize I/O region register */
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
io_reg[0x00] = 0x80 | (region_code >> 1);
|
||||
}
|
||||
|
||||
/* reinitialize VDP */
|
||||
if (vdp_pal)
|
||||
{
|
||||
status |= 1;
|
||||
lines_per_frame = 313;
|
||||
}
|
||||
else
|
||||
{
|
||||
status &= ~1;
|
||||
lines_per_frame = 262;
|
||||
}
|
||||
|
||||
/* reinitialize VC max value */
|
||||
switch (bitmap.viewport.h)
|
||||
{
|
||||
case 192:
|
||||
vc_max = vc_table[0][vdp_pal];
|
||||
break;
|
||||
case 224:
|
||||
vc_max = vc_table[1][vdp_pal];
|
||||
break;
|
||||
case 240:
|
||||
vc_max = vc_table[3][vdp_pal];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F10:
|
||||
{
|
||||
gen_reset(0);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F11:
|
||||
{
|
||||
config.overscan = (config.overscan + 1) & 3;
|
||||
if ((system_hw == SYSTEM_GG) && !config.gg_extra)
|
||||
{
|
||||
bitmap.viewport.x = (config.overscan & 2) ? 14 : -48;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap.viewport.x = (config.overscan & 2) * 7;
|
||||
}
|
||||
bitmap.viewport.changed = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F12:
|
||||
{
|
||||
joynum = (joynum + 1) % MAX_DEVICES;
|
||||
while (input.dev[joynum] == NO_DEVICE)
|
||||
{
|
||||
joynum = (joynum + 1) % MAX_DEVICES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sdl_input_update(void)
|
||||
{
|
||||
const uint8 *keystate = SDL_GetKeyboardState(NULL);
|
||||
|
||||
/* reset input */
|
||||
input.pad[joynum] = 0;
|
||||
|
||||
switch (input.dev[joynum])
|
||||
{
|
||||
case DEVICE_LIGHTGUN:
|
||||
{
|
||||
/* get mouse coordinates (absolute values) */
|
||||
int x,y;
|
||||
int state = SDL_GetMouseState(&x,&y);
|
||||
|
||||
/* X axis */
|
||||
input.analog[joynum][0] = x - (VIDEO_WIDTH-bitmap.viewport.w)/2;
|
||||
|
||||
/* Y axis */
|
||||
input.analog[joynum][1] = y - (VIDEO_HEIGHT-bitmap.viewport.h)/2;
|
||||
|
||||
/* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_A;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_B;
|
||||
if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_C;
|
||||
if(keystate[SDL_SCANCODE_F]) input.pad[joynum] |= INPUT_START;
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_PADDLE:
|
||||
{
|
||||
/* get mouse (absolute values) */
|
||||
int x;
|
||||
int state = SDL_GetMouseState(&x, NULL);
|
||||
|
||||
/* Range is [0;256], 128 being middle position */
|
||||
input.analog[joynum][0] = x * 256 /VIDEO_WIDTH;
|
||||
|
||||
/* Button I -> 0 0 0 0 0 0 0 I*/
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_SPORTSPAD:
|
||||
{
|
||||
/* get mouse (relative values) */
|
||||
int x,y;
|
||||
int state = SDL_GetRelativeMouseState(&x,&y);
|
||||
|
||||
/* Range is [0;256] */
|
||||
input.analog[joynum][0] = (unsigned char)(-x & 0xFF);
|
||||
input.analog[joynum][1] = (unsigned char)(-y & 0xFF);
|
||||
|
||||
/* Buttons I & II -> 0 0 0 0 0 0 II I*/
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_C;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_MOUSE:
|
||||
{
|
||||
/* get mouse (relative values) */
|
||||
int x,y;
|
||||
int state = SDL_GetRelativeMouseState(&x,&y);
|
||||
|
||||
/* Sega Mouse range is [-256;+256] */
|
||||
input.analog[joynum][0] = x * 2;
|
||||
input.analog[joynum][1] = y * 2;
|
||||
|
||||
/* Vertical movement is upsidedown */
|
||||
if (!config.invert_mouse)
|
||||
input.analog[joynum][1] = 0 - input.analog[joynum][1];
|
||||
|
||||
/* Start,Left,Right,Middle buttons -> 0 0 0 0 START MIDDLE RIGHT LEFT */
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_C;
|
||||
if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_A;
|
||||
if(keystate[SDL_SCANCODE_F]) input.pad[joynum] |= INPUT_START;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_XE_1AP:
|
||||
{
|
||||
/* A,B,C,D,Select,START,E1,E2 buttons -> E1(?) E2(?) START SELECT(?) A B C D */
|
||||
if(keystate[SDL_SCANCODE_A]) input.pad[joynum] |= INPUT_START;
|
||||
if(keystate[SDL_SCANCODE_S]) input.pad[joynum] |= INPUT_A;
|
||||
if(keystate[SDL_SCANCODE_D]) input.pad[joynum] |= INPUT_C;
|
||||
if(keystate[SDL_SCANCODE_F]) input.pad[joynum] |= INPUT_Y;
|
||||
if(keystate[SDL_SCANCODE_Z]) input.pad[joynum] |= INPUT_B;
|
||||
if(keystate[SDL_SCANCODE_X]) input.pad[joynum] |= INPUT_X;
|
||||
if(keystate[SDL_SCANCODE_C]) input.pad[joynum] |= INPUT_MODE;
|
||||
if(keystate[SDL_SCANCODE_V]) input.pad[joynum] |= INPUT_Z;
|
||||
|
||||
/* Left Analog Stick (bidirectional) */
|
||||
if(keystate[SDL_SCANCODE_UP]) input.analog[joynum][1]-=2;
|
||||
else if(keystate[SDL_SCANCODE_DOWN]) input.analog[joynum][1]+=2;
|
||||
else input.analog[joynum][1] = 128;
|
||||
if(keystate[SDL_SCANCODE_LEFT]) input.analog[joynum][0]-=2;
|
||||
else if(keystate[SDL_SCANCODE_RIGHT]) input.analog[joynum][0]+=2;
|
||||
else input.analog[joynum][0] = 128;
|
||||
|
||||
/* Right Analog Stick (unidirectional) */
|
||||
if(keystate[SDL_SCANCODE_KP_8]) input.analog[joynum+1][0]-=2;
|
||||
else if(keystate[SDL_SCANCODE_KP_2]) input.analog[joynum+1][0]+=2;
|
||||
else if(keystate[SDL_SCANCODE_KP_4]) input.analog[joynum+1][0]-=2;
|
||||
else if(keystate[SDL_SCANCODE_KP_6]) input.analog[joynum+1][0]+=2;
|
||||
else input.analog[joynum+1][0] = 128;
|
||||
|
||||
/* Limiters */
|
||||
if (input.analog[joynum][0] > 0xFF) input.analog[joynum][0] = 0xFF;
|
||||
else if (input.analog[joynum][0] < 0) input.analog[joynum][0] = 0;
|
||||
if (input.analog[joynum][1] > 0xFF) input.analog[joynum][1] = 0xFF;
|
||||
else if (input.analog[joynum][1] < 0) input.analog[joynum][1] = 0;
|
||||
if (input.analog[joynum+1][0] > 0xFF) input.analog[joynum+1][0] = 0xFF;
|
||||
else if (input.analog[joynum+1][0] < 0) input.analog[joynum+1][0] = 0;
|
||||
if (input.analog[joynum+1][1] > 0xFF) input.analog[joynum+1][1] = 0xFF;
|
||||
else if (input.analog[joynum+1][1] < 0) input.analog[joynum+1][1] = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_PICO:
|
||||
{
|
||||
/* get mouse (absolute values) */
|
||||
int x,y;
|
||||
int state = SDL_GetMouseState(&x,&y);
|
||||
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = 0x3c + (x * (0x17c-0x03c+1)) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = 0x1fc + (y * (0x2f7-0x1fc+1)) / VIDEO_HEIGHT;
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_MMASK) pico_current = (pico_current + 1) & 7;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_PICO_RED;
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[0] |= INPUT_PICO_PEN;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_TEREBI:
|
||||
{
|
||||
/* get mouse (absolute values) */
|
||||
int x,y;
|
||||
int state = SDL_GetMouseState(&x,&y);
|
||||
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = (x * 250) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = (y * 250) / VIDEO_HEIGHT;
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_B;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_GRAPHIC_BOARD:
|
||||
{
|
||||
/* get mouse (absolute values) */
|
||||
int x,y;
|
||||
int state = SDL_GetMouseState(&x,&y);
|
||||
|
||||
/* Calculate X Y axis values */
|
||||
input.analog[0][0] = (x * 255) / VIDEO_WIDTH;
|
||||
input.analog[0][1] = (y * 255) / VIDEO_HEIGHT;
|
||||
|
||||
/* Map mouse buttons to player #1 inputs */
|
||||
if(state & SDL_BUTTON_LMASK) input.pad[0] |= INPUT_GRAPHIC_PEN;
|
||||
if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_GRAPHIC_MENU;
|
||||
if(state & SDL_BUTTON_MMASK) input.pad[0] |= INPUT_GRAPHIC_DO;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_ACTIVATOR:
|
||||
{
|
||||
if(keystate[SDL_SCANCODE_G]) input.pad[joynum] |= INPUT_ACTIVATOR_7L;
|
||||
if(keystate[SDL_SCANCODE_H]) input.pad[joynum] |= INPUT_ACTIVATOR_7U;
|
||||
if(keystate[SDL_SCANCODE_J]) input.pad[joynum] |= INPUT_ACTIVATOR_8L;
|
||||
if(keystate[SDL_SCANCODE_K]) input.pad[joynum] |= INPUT_ACTIVATOR_8U;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if(keystate[SDL_SCANCODE_A]) input.pad[joynum] |= INPUT_A;
|
||||
if(keystate[SDL_SCANCODE_S]) input.pad[joynum] |= INPUT_B;
|
||||
if(keystate[SDL_SCANCODE_D]) input.pad[joynum] |= INPUT_C;
|
||||
if(keystate[SDL_SCANCODE_F]) input.pad[joynum] |= INPUT_START;
|
||||
if(keystate[SDL_SCANCODE_Z]) input.pad[joynum] |= INPUT_X;
|
||||
if(keystate[SDL_SCANCODE_X]) input.pad[joynum] |= INPUT_Y;
|
||||
if(keystate[SDL_SCANCODE_C]) input.pad[joynum] |= INPUT_Z;
|
||||
if(keystate[SDL_SCANCODE_V]) input.pad[joynum] |= INPUT_MODE;
|
||||
|
||||
if(keystate[SDL_SCANCODE_UP]) input.pad[joynum] |= INPUT_UP;
|
||||
else
|
||||
if(keystate[SDL_SCANCODE_DOWN]) input.pad[joynum] |= INPUT_DOWN;
|
||||
if(keystate[SDL_SCANCODE_LEFT]) input.pad[joynum] |= INPUT_LEFT;
|
||||
else
|
||||
if(keystate[SDL_SCANCODE_RIGHT]) input.pad[joynum] |= INPUT_RIGHT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
int running = 1;
|
||||
|
||||
/* Print help if no game specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
char caption[256];
|
||||
sprintf(caption, "Genesis Plus GX\\SDL\nusage: %s gamename\n", argv[0]);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Information", caption, sdl_video.window);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set default config */
|
||||
error_init();
|
||||
set_config_defaults();
|
||||
|
||||
/* mark all BIOS as unloaded */
|
||||
system_bios = 0;
|
||||
|
||||
/* Genesis BOOT ROM support (2KB max) */
|
||||
memset(boot_rom, 0xFF, 0x800);
|
||||
fp = fopen(MD_BIOS, "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* read BOOT ROM */
|
||||
fread(boot_rom, 1, 0x800, fp);
|
||||
fclose(fp);
|
||||
|
||||
/* check BOOT ROM */
|
||||
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
|
||||
{
|
||||
/* mark Genesis BIOS as loaded */
|
||||
system_bios = SYSTEM_MD;
|
||||
}
|
||||
|
||||
/* Byteswap ROM */
|
||||
for (i=0; i<0x800; i+=2)
|
||||
{
|
||||
uint8 temp = boot_rom[i];
|
||||
boot_rom[i] = boot_rom[i+1];
|
||||
boot_rom[i+1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize SDL */
|
||||
if(SDL_Init(0) < 0)
|
||||
{
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "SDL initialization failed", sdl_video.window);
|
||||
return 1;
|
||||
}
|
||||
sdl_video_init();
|
||||
if (use_sound) sdl_sound_init();
|
||||
sdl_sync_init();
|
||||
|
||||
/* initialize Genesis virtual system */
|
||||
SDL_LockSurface(sdl_video.surf_bitmap);
|
||||
memset(&bitmap, 0, sizeof(t_bitmap));
|
||||
bitmap.width = 720;
|
||||
bitmap.height = 576;
|
||||
#if defined(USE_8BPP_RENDERING)
|
||||
bitmap.pitch = (bitmap.width * 1);
|
||||
#elif defined(USE_15BPP_RENDERING)
|
||||
bitmap.pitch = (bitmap.width * 2);
|
||||
#elif defined(USE_16BPP_RENDERING)
|
||||
bitmap.pitch = (bitmap.width * 2);
|
||||
#elif defined(USE_32BPP_RENDERING)
|
||||
bitmap.pitch = (bitmap.width * 4);
|
||||
#endif
|
||||
bitmap.data = sdl_video.surf_bitmap->pixels;
|
||||
SDL_UnlockSurface(sdl_video.surf_bitmap);
|
||||
bitmap.viewport.changed = 3;
|
||||
|
||||
/* Load game file */
|
||||
if(!load_rom(argv[1]))
|
||||
{
|
||||
char caption[256];
|
||||
sprintf(caption, "Error loading file `%s'.", argv[1]);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", caption, sdl_video.window);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* initialize system hardware */
|
||||
audio_init(SOUND_FREQUENCY, 0);
|
||||
system_init();
|
||||
|
||||
/* Mega CD specific */
|
||||
if (system_hw == SYSTEM_MCD)
|
||||
{
|
||||
/* load internal backup RAM */
|
||||
fp = fopen("./scd.brm", "rb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fread(scd.bram, 0x2000, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* check if internal backup RAM is formatted */
|
||||
if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20))
|
||||
{
|
||||
/* clear internal backup RAM */
|
||||
memset(scd.bram, 0x00, 0x200);
|
||||
|
||||
/* Internal Backup RAM size fields */
|
||||
brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00;
|
||||
brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3;
|
||||
|
||||
/* format internal backup RAM */
|
||||
memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40);
|
||||
}
|
||||
|
||||
/* load cartridge backup RAM */
|
||||
if (scd.cartridge.id)
|
||||
{
|
||||
fp = fopen("./cart.brm", "rb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fread(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* check if cartridge backup RAM is formatted */
|
||||
if (memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20))
|
||||
{
|
||||
/* clear cartridge backup RAM */
|
||||
memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1);
|
||||
|
||||
/* Cartridge Backup RAM size fields */
|
||||
brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8;
|
||||
brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff;
|
||||
|
||||
/* format cartridge backup RAM */
|
||||
memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - sizeof(brm_format), brm_format, sizeof(brm_format));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sram.on)
|
||||
{
|
||||
/* load SRAM */
|
||||
fp = fopen("./game.srm", "rb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fread(sram.sram,0x10000,1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset system hardware */
|
||||
system_reset();
|
||||
|
||||
if(use_sound) SDL_PauseAudio(0);
|
||||
|
||||
/* 3 frames = 50 ms (60hz) or 60 ms (50hz) */
|
||||
if(sdl_sync.sem_sync)
|
||||
SDL_AddTimer(vdp_pal ? 60 : 50, sdl_sync_timer_callback, NULL);
|
||||
|
||||
/* emulation loop */
|
||||
while(running)
|
||||
{
|
||||
SDL_Event event;
|
||||
if (SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_USEREVENT:
|
||||
{
|
||||
char caption[100];
|
||||
sprintf(caption,"Genesis Plus GX - %d fps - %s", event.user.code, (rominfo.international[0] != 0x20) ? rominfo.international : rominfo.domestic);
|
||||
SDL_SetWindowTitle(sdl_video.window, caption);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_QUIT:
|
||||
{
|
||||
running = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
running = sdl_control_update(event.key.keysym.sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdl_video_update();
|
||||
sdl_sound_update(use_sound);
|
||||
|
||||
if(!turbo_mode && sdl_sync.sem_sync && sdl_video.frames_rendered % 3 == 0)
|
||||
{
|
||||
SDL_SemWait(sdl_sync.sem_sync);
|
||||
}
|
||||
}
|
||||
|
||||
if (system_hw == SYSTEM_MCD)
|
||||
{
|
||||
/* save internal backup RAM (if formatted) */
|
||||
if (!memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20))
|
||||
{
|
||||
fp = fopen("./scd.brm", "wb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fwrite(scd.bram, 0x2000, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* save cartridge backup RAM (if formatted) */
|
||||
if (scd.cartridge.id)
|
||||
{
|
||||
if (!memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20))
|
||||
{
|
||||
fp = fopen("./cart.brm", "wb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fwrite(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sram.on)
|
||||
{
|
||||
/* save SRAM */
|
||||
fp = fopen("./game.srm", "wb");
|
||||
if (fp!=NULL)
|
||||
{
|
||||
fwrite(sram.sram,0x10000,1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
audio_shutdown();
|
||||
error_shutdown();
|
||||
|
||||
sdl_video_close();
|
||||
sdl_sound_close();
|
||||
sdl_sync_close();
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
11
sdl/sdl2/main.h
Normal file
11
sdl/sdl2/main.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
#ifndef _MAIN_H_
|
||||
#define _MAIN_H_
|
||||
|
||||
#define MAX_INPUTS 8
|
||||
|
||||
extern int debug_on;
|
||||
extern int log_error;
|
||||
extern int sdl_input_update(void);
|
||||
|
||||
#endif /* _MAIN_H_ */
|
Loading…
Reference in New Issue
Block a user