libretro.cpp 13.2 KB
Newer Older
LLeny's avatar
LLeny committed
1
#include "libretro.h"
jdgleaver's avatar
jdgleaver committed
2
3
#include "libretro_core_options.h"

4
5
#include <string.h>
#include <fstream>
jdgleaver's avatar
jdgleaver committed
6

LLeny's avatar
LLeny committed
7
8
#include "handy.h"

9
static retro_log_printf_t log_cb;
LLeny's avatar
LLeny committed
10
11
12
13
14
15
16
17
static retro_video_refresh_t video_cb;
static retro_audio_sample_batch_t audio_batch_cb;
static retro_environment_t environ_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;

static CSystem *lynx = NULL;

newsie-oss's avatar
newsie-oss committed
18
static int16_t *soundBuffer = NULL;
LLeny's avatar
LLeny committed
19

jdgleaver's avatar
jdgleaver committed
20
21
#define RETRO_LYNX_WIDTH  160
#define RETRO_LYNX_HEIGHT 102
newsie-oss's avatar
newsie-oss committed
22
23

// core options
jdgleaver's avatar
jdgleaver committed
24
25
26
static uint8_t lynx_rot    = MIKIE_NO_ROTATE;
static uint8_t lynx_width  = RETRO_LYNX_WIDTH;
static uint8_t lynx_height = RETRO_LYNX_HEIGHT;
Leny's avatar
Leny committed
27

28
static int RETRO_PIX_BYTES = 2;
jdgleaver's avatar
jdgleaver committed
29
30
31
#if defined(FRONTEND_SUPPORTS_RGB565)
static int RETRO_PIX_DEPTH = 16;
#else
32
static int RETRO_PIX_DEPTH = 15;
jdgleaver's avatar
jdgleaver committed
33
#endif
34

jdgleaver's avatar
jdgleaver committed
35
static uint8_t framebuffer[RETRO_LYNX_WIDTH*RETRO_LYNX_WIDTH*4];
LLeny's avatar
LLeny committed
36
37
38
39
40
41

static bool newFrame = false;
static bool initialized = false;

struct map { unsigned retro; unsigned lynx; };

Leny's avatar
Leny committed
42
static map btn_map_no_rot[] = {
Libretro-Admin's avatar
Libretro-Admin committed
43
44
45
46
47
48
49
50
51
   { RETRO_DEVICE_ID_JOYPAD_A, BUTTON_A },
   { RETRO_DEVICE_ID_JOYPAD_B, BUTTON_B },
   { RETRO_DEVICE_ID_JOYPAD_RIGHT, BUTTON_RIGHT },
   { RETRO_DEVICE_ID_JOYPAD_LEFT, BUTTON_LEFT },
   { RETRO_DEVICE_ID_JOYPAD_UP, BUTTON_UP },
   { RETRO_DEVICE_ID_JOYPAD_DOWN, BUTTON_DOWN },
   { RETRO_DEVICE_ID_JOYPAD_L, BUTTON_OPT1 },
   { RETRO_DEVICE_ID_JOYPAD_R, BUTTON_OPT2 },
   { RETRO_DEVICE_ID_JOYPAD_START, BUTTON_PAUSE },
LLeny's avatar
LLeny committed
52
53
};

54
static map btn_map_rot_270[] = {
Libretro-Admin's avatar
Libretro-Admin committed
55
56
57
58
59
60
61
62
63
   { RETRO_DEVICE_ID_JOYPAD_A, BUTTON_A },
   { RETRO_DEVICE_ID_JOYPAD_B, BUTTON_B },
   { RETRO_DEVICE_ID_JOYPAD_RIGHT, BUTTON_UP },
   { RETRO_DEVICE_ID_JOYPAD_LEFT, BUTTON_DOWN },
   { RETRO_DEVICE_ID_JOYPAD_UP, BUTTON_LEFT },
   { RETRO_DEVICE_ID_JOYPAD_DOWN, BUTTON_RIGHT },
   { RETRO_DEVICE_ID_JOYPAD_L, BUTTON_OPT1 },
   { RETRO_DEVICE_ID_JOYPAD_R, BUTTON_OPT2 },
   { RETRO_DEVICE_ID_JOYPAD_START, BUTTON_PAUSE },
Leny's avatar
Leny committed
64
65
66
};

static map btn_map_rot_90[] = {
Libretro-Admin's avatar
Libretro-Admin committed
67
68
69
70
71
72
73
74
75
   { RETRO_DEVICE_ID_JOYPAD_A, BUTTON_A },
   { RETRO_DEVICE_ID_JOYPAD_B, BUTTON_B },
   { RETRO_DEVICE_ID_JOYPAD_RIGHT, BUTTON_DOWN },
   { RETRO_DEVICE_ID_JOYPAD_LEFT, BUTTON_UP },
   { RETRO_DEVICE_ID_JOYPAD_UP, BUTTON_RIGHT },
   { RETRO_DEVICE_ID_JOYPAD_DOWN, BUTTON_LEFT },
   { RETRO_DEVICE_ID_JOYPAD_L, BUTTON_OPT1 },
   { RETRO_DEVICE_ID_JOYPAD_R, BUTTON_OPT2 },
   { RETRO_DEVICE_ID_JOYPAD_START, BUTTON_PAUSE },
Leny's avatar
Leny committed
76
77
78
79
};

static map* btn_map;

trioan's avatar
trioan committed
80
81
static bool libretro_supports_input_bitmasks;
static bool select_button;
82
83
84
85
86

static void check_color_depth(void)
{
   if (RETRO_PIX_DEPTH == 24)
   {
jdgleaver's avatar
jdgleaver committed
87
88
89
      /* If XRGB8888 support is compiled in, attempt to
       * set 24 bit colour depth */
#if defined(FRONTEND_SUPPORTS_XRGB8888)
90
91
92
93
94
95
96
      enum retro_pixel_format rgb888 = RETRO_PIXEL_FORMAT_XRGB8888;

      if(!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb888))
      {
         if(log_cb) log_cb(RETRO_LOG_ERROR, "Pixel format XRGB8888 not supported by platform.\n");

         RETRO_PIX_BYTES = 2;
jdgleaver's avatar
jdgleaver committed
97
98
99
#if defined(FRONTEND_SUPPORTS_RGB565)
         RETRO_PIX_DEPTH = 16;
#else
100
         RETRO_PIX_DEPTH = 15;
jdgleaver's avatar
jdgleaver committed
101
#endif
102
      }
jdgleaver's avatar
jdgleaver committed
103
104
105
106
107
108
109
110
111
112
113
114
#else
      /* XRGB8888 support is *not* compiled in.
       * If we reach this point, then unforeseen
       * errors have occurred - just 'reset' colour
       * depth to 16 bit */
      RETRO_PIX_BYTES = 2;
#if defined(FRONTEND_SUPPORTS_RGB565)
      RETRO_PIX_DEPTH = 16;
#else
      RETRO_PIX_DEPTH = 15;
#endif
#endif
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
   }

   if (RETRO_PIX_BYTES == 2)
   {
#if defined(FRONTEND_SUPPORTS_RGB565)
      enum retro_pixel_format rgb565 = RETRO_PIXEL_FORMAT_RGB565;

      if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565))
      {
         if(log_cb) log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n");

         RETRO_PIX_DEPTH = 16;
      }
#else
      enum retro_pixel_format rgb555 = RETRO_PIXEL_FORMAT_0RGB1555;

      if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb555))
      {
         if(log_cb) log_cb(RETRO_LOG_INFO, "Using default 0RGB1555 pixel format.\n");

         RETRO_PIX_DEPTH = 15;
      }
#endif
   }
}

Libretro-Admin's avatar
Libretro-Admin committed
141
unsigned retro_api_version(void)
LLeny's avatar
LLeny committed
142
{
Libretro-Admin's avatar
Libretro-Admin committed
143
   return RETRO_API_VERSION;
LLeny's avatar
LLeny committed
144
145
}

newsie-oss's avatar
newsie-oss committed
146
147
148
149
150
151
152
153
154
155
156
157
158
static void update_geometry()
{
   struct retro_system_av_info info;

   retro_get_system_av_info(&info);
   environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info);
}

static UBYTE* lynx_display_callback(ULONG objref)
{
   if(!initialized)
      return (UBYTE*)framebuffer;

jdgleaver's avatar
jdgleaver committed
159
   video_cb(framebuffer, lynx_width, lynx_height, RETRO_LYNX_WIDTH*RETRO_PIX_BYTES);
newsie-oss's avatar
newsie-oss committed
160
161
162
163
164
165
166

   for(int total = 0; total < gAudioBufferPointer/4; )
      total += audio_batch_cb(soundBuffer + total*2, (gAudioBufferPointer/4) - total);
   gAudioBufferPointer = 0;


   newFrame = true;
jdgleaver's avatar
jdgleaver committed
167

jdgleaver's avatar
jdgleaver committed
168
   return (UBYTE*)framebuffer;
newsie-oss's avatar
newsie-oss committed
169
170
171
172
}

static void lynx_rotate()
{
trioan's avatar
trioan committed
173
174
   if(!lynx) return;

newsie-oss's avatar
newsie-oss committed
175
176
177
178
179
180
181
   switch(lynx_rot)
   {
   default:
      lynx_rot = MIKIE_NO_ROTATE;
      // intentional fall-through

   case MIKIE_NO_ROTATE:
jdgleaver's avatar
jdgleaver committed
182
183
184
      lynx_width  = RETRO_LYNX_WIDTH;
      lynx_height = RETRO_LYNX_HEIGHT;
      btn_map     = btn_map_no_rot;
newsie-oss's avatar
newsie-oss committed
185
186
187
      break;

   case MIKIE_ROTATE_R:
jdgleaver's avatar
jdgleaver committed
188
189
190
      lynx_width  = RETRO_LYNX_HEIGHT;
      lynx_height = RETRO_LYNX_WIDTH;
      btn_map     = btn_map_rot_90;
newsie-oss's avatar
newsie-oss committed
191
192
193
      break;

   case MIKIE_ROTATE_L:
jdgleaver's avatar
jdgleaver committed
194
195
196
      lynx_width  = RETRO_LYNX_HEIGHT;
      lynx_height = RETRO_LYNX_WIDTH;
      btn_map     = btn_map_rot_270;
newsie-oss's avatar
newsie-oss committed
197
198
199
      break;
   }

200
201
   switch (RETRO_PIX_DEPTH)
   {
jdgleaver's avatar
jdgleaver committed
202
203
204
205
      case 15: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_16BPP_555, RETRO_LYNX_WIDTH*2, lynx_display_callback, (ULONG)0); break;
      case 16: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_16BPP_565, RETRO_LYNX_WIDTH*2, lynx_display_callback, (ULONG)0); break;
      case 24: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP,     RETRO_LYNX_WIDTH*4, lynx_display_callback, (ULONG)0); break;
      default: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP,     RETRO_LYNX_WIDTH*4, lynx_display_callback, (ULONG)0); break;
newsie-oss's avatar
newsie-oss committed
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
   }

   update_geometry();
}

static void check_variables(void)
{
   struct retro_variable var = {0};

   var.key = "handy_rot";
   var.value = NULL;

   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
      unsigned old_rotate = lynx_rot;

      if (strcmp(var.value, "None") == 0)
         lynx_rot = MIKIE_NO_ROTATE;
      else if (strcmp(var.value, "90") == 0)
         lynx_rot = MIKIE_ROTATE_R; 
      else if (strcmp(var.value, "270") == 0)
         lynx_rot = MIKIE_ROTATE_L;

      if (old_rotate != lynx_rot)
         lynx_rotate();
   }

jdgleaver's avatar
jdgleaver committed
232
233
234
#if defined(FRONTEND_SUPPORTS_XRGB8888)
   /* Only read colour depth setting on first run */
   if (!initialized)
jdgleaver's avatar
jdgleaver committed
235
   {
jdgleaver's avatar
jdgleaver committed
236
237
238
239
      var.key = "handy_gfx_colors";
      var.value = NULL;

      /* Set 16bpp by default */
jdgleaver's avatar
jdgleaver committed
240
241
242
      RETRO_PIX_BYTES = 2;
      RETRO_PIX_DEPTH = 16;

jdgleaver's avatar
jdgleaver committed
243
244
245
246
247
248
      if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
         if (strcmp(var.value, "24bit") == 0)
         {
            RETRO_PIX_BYTES = 4;
            RETRO_PIX_DEPTH = 24;
         }
newsie-oss's avatar
newsie-oss committed
249
   }
jdgleaver's avatar
jdgleaver committed
250
#endif
newsie-oss's avatar
newsie-oss committed
251
252
}

LLeny's avatar
LLeny committed
253
254
void retro_init(void)
{
255
256
257
258
   struct retro_log_callback log;
   environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log);
   if (log.log)
      log_cb = log.log;
Leny's avatar
Leny committed
259

260
261
   uint64_t serialization_quirks = RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION;
   environ_cb(RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS, &serialization_quirks);
trioan's avatar
trioan committed
262
263
264

   if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
      libretro_supports_input_bitmasks = true;
LLeny's avatar
LLeny committed
265
266
267
268
}

void retro_reset(void)
{
269
   if(lynx){
snes2600's avatar
snes2600 committed
270
      lynx->SaveEEPROM();
Libretro-Admin's avatar
Libretro-Admin committed
271
      lynx->Reset();
272
   }
LLeny's avatar
LLeny committed
273
274
275
276
}

void retro_deinit(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
277
   initialized = false;
LLeny's avatar
LLeny committed
278

279
   if(lynx){
snes2600's avatar
snes2600 committed
280
      lynx->SaveEEPROM();
Libretro-Admin's avatar
Libretro-Admin committed
281
      delete lynx;
snes2600's avatar
snes2600 committed
282
      lynx=0;
283
   }
trioan's avatar
trioan committed
284
285

   libretro_supports_input_bitmasks = false;
LLeny's avatar
LLeny committed
286
287
288
289
290
}

void retro_set_environment(retro_environment_t cb)
{
   environ_cb = cb;
jdgleaver's avatar
jdgleaver committed
291
292

   libretro_set_core_options(environ_cb);
LLeny's avatar
LLeny committed
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
}

void retro_set_audio_sample(retro_audio_sample_t cb)
{
}

void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
{
   audio_batch_cb = cb;
}

void retro_set_input_poll(retro_input_poll_t cb)
{
   input_poll_cb = cb;
}

void retro_set_input_state(retro_input_state_t cb)
{
   input_state_cb = cb;
}

void retro_set_video_refresh(retro_video_refresh_t cb)
{
   video_cb = cb;
}

Libretro-Admin's avatar
Libretro-Admin committed
319
static unsigned get_lynx_input(void)
LLeny's avatar
LLeny committed
320
{
Libretro-Admin's avatar
Libretro-Admin committed
321
   unsigned i, res = 0;
trioan's avatar
trioan committed
322
323
324
325
326
327
328
329
330
331
332
333
334
   if (libretro_supports_input_bitmasks)
   {
      int16_t ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
      for (unsigned i = 0; i < sizeof(btn_map_no_rot) / sizeof(map); i++)
         res |= ret & (1 << btn_map[i].retro) ? (btn_map[i].lynx) : 0;
      select_button = ret & (1 << RETRO_DEVICE_ID_JOYPAD_SELECT);
   }
   else
   {
      for (i = 0; i < sizeof(btn_map_no_rot) / sizeof(map); ++i)
         res |= input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, btn_map[i].retro) ? btn_map[i].lynx : 0;
      select_button = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT);
   }
Libretro-Admin's avatar
Libretro-Admin committed
335
   return res;
LLeny's avatar
LLeny committed
336
337
}

Libretro-Admin's avatar
Libretro-Admin committed
338
339
static void lynx_input(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
340
341
   input_poll_cb();
   lynx->SetButtonData(get_lynx_input());
tryal-star's avatar
tryal-star committed
342
343
344
345
346
347
348
349
350
351
352


   static bool select_pressed_last_frame = false;
   if(select_button && !select_pressed_last_frame)
   {
      lynx_rot++;

      lynx_rotate();
   }
   
   select_pressed_last_frame = select_button;
Libretro-Admin's avatar
Libretro-Admin committed
353
354
}

Libretro-Admin's avatar
Libretro-Admin committed
355
static bool lynx_initialize_sound(void)
Libretro-Admin's avatar
Libretro-Admin committed
356
{
Libretro-Admin's avatar
Libretro-Admin committed
357
   gAudioEnabled = true;
newsie-oss's avatar
newsie-oss committed
358
   soundBuffer = (int16_t *) (&gAudioBuffer);
Libretro-Admin's avatar
Libretro-Admin committed
359
   return true;
Libretro-Admin's avatar
Libretro-Admin committed
360
361
}

Libretro-Admin's avatar
Libretro-Admin committed
362
363
364
365
366
367
368
369
370
371
372
static int file_exists(const char *path)
{
   FILE *dummy = fopen(path, "rb");

   if (!dummy)
      return 0;

   fclose(dummy);
   return 1;
}

Libretro-Admin's avatar
Libretro-Admin committed
373
374
375
376
377
378
379
static bool lynx_romfilename(char *dest)
{
   const char *dir = 0;
   environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir);

   sprintf(dest, "%s%c%s", dir, SLASH_STR, ROM_FILE);

Libretro-Admin's avatar
Libretro-Admin committed
380
   if (!file_exists(dest))
Libretro-Admin's avatar
Libretro-Admin committed
381
382
383
384
385
386
387
388
389
   {
      if (log_cb)
         log_cb(RETRO_LOG_ERROR, "[handy] ROM not found %s\n", dest);
      return false;
   }

   return true;
}

funbars's avatar
funbars committed
390
391
392
393
394
395
396
397
398
399
400
401
402
static bool lynx_initialize_system(const char* gamepath)
{
   char romfilename[1024];

   if(lynx){
      lynx->SaveEEPROM();
      delete lynx;
      lynx=0;
   }

   lynx_romfilename(romfilename);

   lynx = new CSystem(gamepath, romfilename, true);
Libretro-Admin's avatar
Libretro-Admin committed
403

Libretro-Admin's avatar
Libretro-Admin committed
404
   return true;
Libretro-Admin's avatar
Libretro-Admin committed
405
406
}

funbars's avatar
funbars committed
407
408
409
410
411
412
413
414
415
416
417
418
419
void retro_set_controller_port_device(unsigned, unsigned)
{
}

void retro_get_system_info(struct retro_system_info *info)
{
   memset(info, 0, sizeof(*info));
   info->library_name     = "Handy";
#ifndef GIT_VERSION
#define GIT_VERSION ""
#endif
   info->library_version  = HANDYVER GIT_VERSION;
   info->need_fullpath    = true;
tryal-star's avatar
tryal-star committed
420
   info->valid_extensions = "lnx|o";
funbars's avatar
funbars committed
421
422
423
424
425
   info->block_extract = 0;
}

void retro_get_system_av_info(struct retro_system_av_info *info)
{
jdgleaver's avatar
jdgleaver committed
426
   struct retro_game_geometry geom = { lynx_width, lynx_height, RETRO_LYNX_WIDTH, RETRO_LYNX_WIDTH, (float) lynx_width / (float) lynx_height };
tryal-star's avatar
tryal-star committed
427
   struct retro_system_timing timing = { 75.0, (float) HANDY_AUDIO_SAMPLE_FREQ };
funbars's avatar
funbars committed
428
429
430
431
432
433
434
435

   memset(info, 0, sizeof(*info));
   info->geometry = geom;
   info->timing   = timing;
}

void retro_run(void)
{
436
437
438
439
   bool updated = false;
   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
      check_variables();

funbars's avatar
funbars committed
440
441
   lynx_input();

trioan's avatar
trioan committed
442
443
   gAudioLastUpdateCycle = gSystemCycleCount;

funbars's avatar
funbars committed
444
445
446
447
448
449
450
451
452
453
454
   while (!newFrame)
      lynx->Update();

   newFrame = false;
}

size_t retro_serialize_size(void)
{
   if(!lynx)
      return 0;

snes2600's avatar
snes2600 committed
455
   return lynx->ContextSize();
funbars's avatar
funbars committed
456
457
458
459
460
461
462
}

bool retro_serialize(void *data, size_t size)
{
   if(!lynx)
      return false;

snes2600's avatar
snes2600 committed
463
464
465
466
467
468
   LSS_FILE fp;
   fp.memptr = (UBYTE *) data;
   fp.index = 0;
   fp.index_limit = size;

   return lynx->ContextSave(&fp);
funbars's avatar
funbars committed
469
470
471
472
473
474
475
}

bool retro_unserialize(const void *data, size_t size)
{
   if(!lynx)
      return false;

snes2600's avatar
snes2600 committed
476
477
478
479
480
481
   LSS_FILE fp;
   fp.memptr = (UBYTE *) data;
   fp.index = 0;
   fp.index_limit = size;

   return lynx->ContextLoad(&fp);
funbars's avatar
funbars committed
482
483
}

LLeny's avatar
LLeny committed
484
485
bool retro_load_game(const struct retro_game_info *info)
{
funbars's avatar
funbars committed
486
   static struct retro_input_descriptor desc[] = {
Libretro-Admin's avatar
Libretro-Admin committed
487
488
489
490
491
492
493
494
495
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT,  "D-Pad Left" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP,    "D-Pad Up" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN,  "D-Pad Down" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B,     "B" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A,     "A" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L,     "Option 1" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R,     "Option 2" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Pause" },
tryal-star's avatar
tryal-star committed
496
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Rotate screen" },
Libretro-Admin's avatar
Libretro-Admin committed
497
498
499
500

      { 0 },
   };

Libretro-Admin's avatar
Libretro-Admin committed
501
502
503
   if (!info)
      return false;

Libretro-Admin's avatar
Libretro-Admin committed
504
505
   environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);

506
507
508
   check_variables();
   check_color_depth();

Libretro-Admin's avatar
Libretro-Admin committed
509
   if (!lynx_initialize_system(info->path))
RobLoach's avatar
RobLoach committed
510
      return false;
Libretro-Admin's avatar
Libretro-Admin committed
511
512

   if (!lynx_initialize_sound())
RobLoach's avatar
RobLoach committed
513
      return false;
LLeny's avatar
LLeny committed
514

515
516
517
   btn_map = btn_map_no_rot;
   lynx_rotate();

Libretro-Admin's avatar
Libretro-Admin committed
518
   initialized = true;
519

Libretro-Admin's avatar
Libretro-Admin committed
520
   return true;
LLeny's avatar
LLeny committed
521
522
523
524
}

bool retro_load_game_special(unsigned, const struct retro_game_info*, size_t)
{
Libretro-Admin's avatar
Libretro-Admin committed
525
   return false;
LLeny's avatar
LLeny committed
526
527
528
529
}

void retro_unload_game(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
530
   initialized = false;
LLeny's avatar
LLeny committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
}

void retro_cheat_reset(void)
{
}

void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
}

unsigned retro_get_region()
{
   return RETRO_REGION_NTSC;
}

Libretro-Admin's avatar
Libretro-Admin committed
546
void *retro_get_memory_data(unsigned type)
LLeny's avatar
LLeny committed
547
{
leiradel's avatar
leiradel committed
548
   if (lynx && type == RETRO_MEMORY_SYSTEM_RAM)
Libretro-Admin's avatar
Libretro-Admin committed
549
550
      return lynx->GetRamPointer();
   return NULL;
LLeny's avatar
LLeny committed
551
552
553
554
}

size_t retro_get_memory_size(unsigned type)
{
leiradel's avatar
leiradel committed
555
556
   if (type == RETRO_MEMORY_SYSTEM_RAM)
      return 1024 * 64;
557
   return 0;
LLeny's avatar
LLeny committed
558
}