Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ int getControllerState(int joypad[], int player)
state |= keypadDirections[norm & 0x07];
}

// Thumbsticks for Keypad 0/5
if(joypad[18]!=0) { state |= K_0; } // 0x48 - Keypad 0
if(joypad[19]!=0) { state |= K_5; } // 0x42 - Keypad 5

// L/R triggers for Keypad Enter/Clear
if(joypad[12]!=0) { state |= K_C; } // 0x88 - Keypad Clear
if(joypad[13]!=0) { state |= K_E; } // 0x28 - Keypad Enter

return state;
}

Expand Down
190 changes: 119 additions & 71 deletions src/libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,51 @@ void retro_init(void)
// setup controller swap
controllerInit();

// controller descriptors
struct retro_input_descriptor desc[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Disc Left" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Disc Up" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Disc Down" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Disc Right" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Left Action Button" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Right Action Button" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Top Action Button" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Last Selected Keypad Button" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Swap Left/Right Controllers" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Console Pause" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Show Keypad" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Show Keypad" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Keypad Clear" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Keypad Enter" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Keypad 0" },
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Keypad 5" },
{ 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Keypad [1-9]" },
{ 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Keypad [1-9]" },

{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Disc Left" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Disc Up" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Disc Down" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Disc Right" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Left Action Button" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Right Action Button" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Top Action Button" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Last Selected Keypad Button" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Swap Left/Right Controllers" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Console Pause" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Show Keypad" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Show Keypad" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Keypad Clear" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Keypad Enter" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Keypad 0" },
{ 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Keypad 5" },
{ 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Keypad [1-9]" },
{ 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Keypad [1-9]" },

{ 0 },
};

Environ(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);

// reset console
Init();
Reset();
Expand Down Expand Up @@ -169,7 +214,6 @@ void retro_run(void)
}

/* JoyPad 0 */

joypad0[0] = InputState(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
joypad0[1] = InputState(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
joypad0[2] = InputState(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
Expand All @@ -192,9 +236,10 @@ void retro_run(void)
joypad0[15] = InputState(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
joypad0[16] = InputState(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
joypad0[17] = InputState(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
joypad0[18] = InputState(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3);
joypad0[19] = InputState(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3);

/* JoyPad 1 */

joypad1[0] = InputState(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
joypad1[1] = InputState(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
joypad1[2] = InputState(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
Expand All @@ -217,6 +262,8 @@ void retro_run(void)
joypad1[15] = InputState(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
joypad1[16] = InputState(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
joypad1[17] = InputState(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
joypad1[18] = InputState(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3);
joypad1[18] = InputState(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3);

// Pause
if((joypad0[8]==1 && joypre0[8]==0) || (joypad1[8]==1 && joypre1[8]==0))
Expand All @@ -242,12 +289,13 @@ void retro_run(void)
OSD_drawTextBG(3, 9, " Y - TOP ACTION BUTTON ");
OSD_drawTextBG(3, 10, " X - LAST SELECTED KEYPAD BUTTON ");
OSD_drawTextBG(3, 11, " L/R - SHOW KEYPAD ");
OSD_drawTextBG(3, 12, " ");
OSD_drawTextBG(3, 13, " START - PAUSE GAME ");
OSD_drawTextBG(3, 14, " SELECT - SWAP LEFT/RIGHT CONTROLLERS ");
OSD_drawTextBG(3, 15, " ");
OSD_drawTextBG(3, 16, " FREEINTV 1.2 LICENSE GPL V3 ");
OSD_drawTextBG(3, 17, " ");
OSD_drawTextBG(3, 12, " LT/RT - KEYPAD CLEAR/ENTER ");
OSD_drawTextBG(3, 13, " ");
OSD_drawTextBG(3, 14, " START - PAUSE GAME ");
OSD_drawTextBG(3, 15, " SELECT - SWAP LEFT/RIGHT CONTROLLERS ");
OSD_drawTextBG(3, 16, " ");
OSD_drawTextBG(3, 17, " FREEINTV 1.2 LICENSE GPL V3 ");
OSD_drawTextBG(3, 18, " ");
}
}
else
Expand Down Expand Up @@ -289,41 +337,41 @@ void retro_run(void)

// sample audio from buffer
audioInc = 3733.5 / audioSamples;
ivoiceInc = 1.0;
ivoiceInc = 1.0;

j = 0;
j = 0;
for(i=0; i<audioSamples; i++)
{
// Sound interpolator:
// The PSG module generates audio at 224010 hz (3733.5 samples per frame)
// Very high frequencies like 0x0001 would generate chirps on output
// (For example, Lock&Chase) so this code interpolates audio, making
// these silent as in real hardware.
audioBufferPos += audioInc;
k = audioBufferPos;
l = k - j;
c = 0;
while (j < k)
c += PSGBuffer[j++];
c = c / l;
// Finally it adds the Intellivoice output (properly generated at the
// same frequency as output)
c = (c + ivoiceBuffer[(int) ivoiceBufferPos]) / 2;
// Sound interpolator:
// The PSG module generates audio at 224010 hz (3733.5 samples per frame)
// Very high frequencies like 0x0001 would generate chirps on output
// (For example, Lock&Chase) so this code interpolates audio, making
// these silent as in real hardware.
audioBufferPos += audioInc;
k = audioBufferPos;
l = k - j;

c = 0;
while (j < k)
c += PSGBuffer[j++];
c = c / l;
// Finally it adds the Intellivoice output (properly generated at the
// same frequency as output)
c = (c + ivoiceBuffer[(int) ivoiceBufferPos]) / 2;

Audio(c, c); // Audio(left, right)

ivoiceBufferPos += ivoiceInc;
if (ivoiceBufferPos >= ivoiceBufferSize)
ivoiceBufferPos = 0.0;
ivoiceBufferPos += ivoiceInc;

if (ivoiceBufferPos >= ivoiceBufferSize)
ivoiceBufferPos = 0.0;

audioBufferPos = audioBufferPos * (audioBufferPos<(PSGBufferSize-1));
}
audioBufferPos = 0.0;
PSGFrame();
ivoiceBufferPos = 0.0;
ivoice_frame();
ivoiceBufferPos = 0.0;
ivoice_frame();
}

// Swap Left/Right Controller
Expand All @@ -343,8 +391,8 @@ void retro_run(void)
}
}

if (intv_halt)
OSD_drawTextBG(3, 5, "INTELLIVISION HALTED");
if (intv_halt)
OSD_drawTextBG(3, 5, "INTELLIVISION HALTED");
// send frame to libretro
Video(frame, frameWidth, frameHeight, sizeof(unsigned int) * frameWidth);

Expand All @@ -366,7 +414,7 @@ void retro_get_system_info(struct retro_system_info *info)

void retro_get_system_av_info(struct retro_system_av_info *info)
{
int pixelformat = RETRO_PIXEL_FORMAT_XRGB8888;
int pixelformat = RETRO_PIXEL_FORMAT_XRGB8888;

memset(info, 0, sizeof(*info));
info->geometry.base_width = MaxWidth;
Expand Down Expand Up @@ -414,53 +462,53 @@ RETRO_API size_t retro_get_memory_size(unsigned id)
#define SERIALIZED_VERSION 0x4f544702

struct serialized {
int version;
struct CP1610serialized CP1610;
struct STICserialized STIC;
struct PSGserialized PSG;
struct ivoiceSerialized ivoice;
unsigned int Memory[0x10000]; // Should be equal to Memory.c
// Extra variables from intv.c
int SR1;
int intv_halt;
int version;
struct CP1610serialized CP1610;
struct STICserialized STIC;
struct PSGserialized PSG;
struct ivoiceSerialized ivoice;
unsigned int Memory[0x10000]; // Should be equal to Memory.c
// Extra variables from intv.c
int SR1;
int intv_halt;
};

size_t retro_serialize_size(void)
{
return sizeof(struct serialized);
return sizeof(struct serialized);
}

bool retro_serialize(void *data, size_t size)
{
struct serialized *all;
all = (struct serialized *) data;
all->version = SERIALIZED_VERSION;
CP1610Serialize(&all->CP1610);
STICSerialize(&all->STIC);
PSGSerialize(&all->PSG);
ivoiceSerialize(&all->ivoice);
memcpy(all->Memory, Memory, sizeof(Memory));
all->SR1 = SR1;
all->intv_halt = intv_halt;
return true;
struct serialized *all;

all = (struct serialized *) data;
all->version = SERIALIZED_VERSION;
CP1610Serialize(&all->CP1610);
STICSerialize(&all->STIC);
PSGSerialize(&all->PSG);
ivoiceSerialize(&all->ivoice);
memcpy(all->Memory, Memory, sizeof(Memory));
all->SR1 = SR1;
all->intv_halt = intv_halt;
return true;
}

bool retro_unserialize(const void *data, size_t size)
{
const struct serialized *all;
all = (const struct serialized *) data;
if (all->version != SERIALIZED_VERSION)
return false;
CP1610Unserialize(&all->CP1610);
STICUnserialize(&all->STIC);
PSGUnserialize(&all->PSG);
ivoiceUnserialize(&all->ivoice);
memcpy(Memory, all->Memory, sizeof(Memory));
SR1 = all->SR1;
intv_halt = all->intv_halt;
return true;
const struct serialized *all;

all = (const struct serialized *) data;
if (all->version != SERIALIZED_VERSION)
return false;
CP1610Unserialize(&all->CP1610);
STICUnserialize(&all->STIC);
PSGUnserialize(&all->PSG);
ivoiceUnserialize(&all->ivoice);
memcpy(Memory, all->Memory, sizeof(Memory));
SR1 = all->SR1;
intv_halt = all->intv_halt;
return true;
}

/* Stubs */
Expand Down