libretro.cpp 15.5 KB
Newer Older
Andre Leiradella's avatar
Andre Leiradella committed
1
2
#include <libretro.h>
#include <coreopt.h>
3
#include <keybovl.h>
Andre Leiradella's avatar
Andre Leiradella committed
4

Libretro-Admin's avatar
Libretro-Admin committed
5
#include <ctype.h>
Andre Leiradella's avatar
Andre Leiradella committed
6
#include <string.h>
7
#include <stdint.h>
Andre Leiradella's avatar
Andre Leiradella committed
8
9
10

#include <eo.h>
#include <types.h>
11
#include <keys.h>
Andre Leiradella's avatar
Andre Leiradella committed
12
13
#include <snap.h>
#include <zx81.h>
14
#include <tzx/TZXFILE.h>
Andre Leiradella's avatar
Andre Leiradella committed
15

16
17
18
19
20
extern "C"
{
#include <gamedb/sha1.h>
}

21
22
#define RETRO_DEVICE_SINCLAIR_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 0)
#define RETRO_DEVICE_CURSOR_JOYSTICK   RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
Andre Leiradella's avatar
Andre Leiradella committed
23
24

#ifdef LOG_PERFORMANCE
25
26
27
  #define RETRO_PERFORMANCE_INIT( name )  do { static struct retro_perf_counter name = { #name }; if ( !name.registered && perf_cb.perf_register ) perf_cb.perf_register( &( name ) ) } while ( 0 )
  #define RETRO_PERFORMANCE_START( name ) do { if ( perf_cb.perf_start ) perf_cb.perf_start( &( name ) ) } while ( 0 )
  #define RETRO_PERFORMANCE_STOP( name )  do { if ( perf_cb.perf_stop ) perf_cb.perf_stop( &( name ) ) } while ( 0 )
Andre Leiradella's avatar
Andre Leiradella committed
28
29
30
31
32
33
#else
  #define RETRO_PERFORMANCE_INIT( name )
  #define RETRO_PERFORMANCE_START( name )
  #define RETRO_PERFORMANCE_STOP( name )
#endif

34
35
typedef struct
{
36
37
38
  CONFIG   cfg;
  void*    data;
  size_t   size;
39
  int      scaled;
40
41
42
  int      transp;
  int      ms;
  unsigned devices[ 2 ];
43
  uint32_t sha1[ 5 ];
44
45
46
}
state_t;

47
48
49
// #include <stdio.h>
// #include <stdarg.h>

Andre Leiradella's avatar
Andre Leiradella committed
50
51
52
static void dummy_log( enum retro_log_level level, const char* fmt, ... )
{
  (void)level;
53
  (void)fmt;
54
  
55
56
57
58
59
  // va_list args;
  // va_start( args, fmt );
  // vfprintf( stderr, fmt, args );
  // va_end( args );
  // fflush( stderr );
Andre Leiradella's avatar
Andre Leiradella committed
60
61
62
63
64
}

static retro_video_refresh_t video_cb;
static retro_input_poll_t input_poll_cb;
static retro_environment_t env_cb;
65
retro_log_printf_t log_cb = dummy_log;
Andre Leiradella's avatar
Andre Leiradella committed
66
67
68
69
70
71
retro_audio_sample_batch_t audio_cb;
static retro_input_state_t input_state_cb;
struct retro_perf_callback perf_cb;

extern int WinR, WinL, WinT, WinB, TVP;
extern WORD* TVFB;
72
extern keybovl_t zx81ovl;
Andre Leiradella's avatar
Andre Leiradella committed
73

74
75
static state_t state;

76
#define ZX81KEYS "auto|default|new line|shift|space|.|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
77

Andre Leiradella's avatar
Andre Leiradella committed
78
79
static const struct retro_variable core_vars[] =
{
80
  { "81_fast_load",      "Tape Fast Load; enabled|disabled" },
81
  { "81_8_16_contents",  "8K-16K Contents; auto|ROM shadow|RAM|dK'tronics 4K Graphics ROM + 4K RAM" },
82
83
  { "81_highres",        "High Resolution; auto|none|WRX" },
  { "81_chroma_81",      "Emulate Chroma 81; auto|disabled|enabled" },
84
  { "81_video_presets",  "Video Presets; clean|tv|noisy" },
85
  { "81_sound",          "Sound emulation; auto|none|Zon X-81" },
86
87
  { "81_joypad_left",    "Joypad Left mapping; " ZX81KEYS },
  { "81_joypad_right",   "Joypad Right mapping; " ZX81KEYS },
88
89
90
91
92
93
94
95
96
97
  { "81_joypad_up",      "Joypad Up mapping; " ZX81KEYS },
  { "81_joypad_down",    "Joypad Down mapping; " ZX81KEYS },
  { "81_joypad_a",       "Joypad A button mapping; " ZX81KEYS },
  { "81_joypad_b",       "Joypad B button mapping; " ZX81KEYS },
  { "81_joypad_x",       "Joypad X button mapping; " ZX81KEYS },
  { "81_joypad_y",       "Joypad Y button mapping; " ZX81KEYS },
  { "81_joypad_l",       "Joypad L button mapping; " ZX81KEYS },
  { "81_joypad_r",       "Joypad R button mapping; " ZX81KEYS },
  { "81_joypad_l2",      "Joypad L2 button mapping; " ZX81KEYS },
  { "81_joypad_r2",      "Joypad R2 button mapping; " ZX81KEYS },
98
  { "81_keybovl_transp", "Transparent Keyboard Overlay; enabled|disabled" },
99
  { "81_key_hold_time",  "Time to Release Key in ms; 100|300|500|1000" },
Andre Leiradella's avatar
Andre Leiradella committed
100
101
  { NULL, NULL },
};
102
103
104

#define UPDATE_RESET 1
#define UPDATE_AV    2
Andre Leiradella's avatar
Andre Leiradella committed
105
 
106
static int update_variables()
Andre Leiradella's avatar
Andre Leiradella committed
107
{
108
  int reset = 0;
109
  int old_scaled = state.scaled;
110

111
  TZXFile.FlashLoad = coreopt( env_cb, core_vars, state.sha1, "81_fast_load", NULL ) != 1;
112
113
  
  {
114
    static int lowram[] = { LOWRAM_ROMSHADOW, LOWRAM_8KRAM, LOWRAM_DK };
115
    int option = coreopt( env_cb, core_vars, state.sha1, "81_8_16_contents", NULL );
116
    option += option < 0;
117
118
    reset = reset || state.cfg.LowRAMContents != lowram[ option ];
    state.cfg.LowRAMContents = lowram[ option ];
119
  }
120

Andre Leiradella's avatar
Andre Leiradella committed
121
  {
122
    int option = coreopt( env_cb, core_vars, state.sha1, "81_video_presets", NULL );
Andre Leiradella's avatar
Andre Leiradella committed
123
124
125
126
127
    option += option < 0;
    
    switch ( option )
    {
    case 0: // clean
128
129
130
      state.cfg.Brightness = 128;
      state.cfg.Contrast = 0;
      state.cfg.Colour = 0;
131
132
133
      state.cfg.Vibrant = 0;
      state.cfg.AdvancedEffects = 0;
      state.cfg.DotCrawl = 0;
134
      state.cfg.Interlaced = 0;
Andre Leiradella's avatar
Andre Leiradella committed
135
      
136
      state.cfg.Artifacts = 0;
137
138
139
140
      state.cfg.Noise = 0;
      state.cfg.Ghosting = 0;
      state.cfg.ScanLines = 0;
      state.cfg.SimpleGhosting = 0;
Andre Leiradella's avatar
Andre Leiradella committed
141
142
143
144
      
      break;
      
    case 1: // tv
145
146
147
148
149
150
151
      state.cfg.Brightness = 206;
      state.cfg.Contrast = 117;
      state.cfg.Colour = 0;
      state.cfg.Vibrant = 1;
      state.cfg.AdvancedEffects = 1;
      state.cfg.DotCrawl = 1;
      state.cfg.Interlaced = 0;
Andre Leiradella's avatar
Andre Leiradella committed
152
      
153
154
155
156
157
      state.cfg.Artifacts = 1;
      state.cfg.Noise = -3;
      state.cfg.Ghosting = -40;
      state.cfg.ScanLines = 40;
      state.cfg.SimpleGhosting = 1;
Andre Leiradella's avatar
Andre Leiradella committed
158
159
160
161
      
      break;
      
    case 2: // noisy
162
163
164
165
166
167
168
      state.cfg.Brightness = 174;
      state.cfg.Contrast = 193;
      state.cfg.Colour = 0;
      state.cfg.Vibrant = 1;
      state.cfg.AdvancedEffects = 1;
      state.cfg.DotCrawl = 1;
      state.cfg.Interlaced = 0;
Andre Leiradella's avatar
Andre Leiradella committed
169
      
170
171
172
173
174
      state.cfg.Artifacts = 1;
      state.cfg.Noise = -6;
      state.cfg.Ghosting = 40;
      state.cfg.ScanLines = 40;
      state.cfg.SimpleGhosting = 1;
Andre Leiradella's avatar
Andre Leiradella committed
175
176
177
178
      
      break;
    }
    
179
    eo_settv( &state.cfg );
Andre Leiradella's avatar
Andre Leiradella committed
180
  }
181

182
  {
183
    int option = coreopt( env_cb, core_vars, state.sha1, "81_chroma_81", NULL );
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    option += option < 0;
    
    if ( option )
    {
      state.cfg.Brightness = 128;
      state.cfg.Contrast = 0;
      state.cfg.Colour = 0;
      state.cfg.Vibrant = 0;
      state.cfg.AdvancedEffects = 0;
      state.cfg.DotCrawl = 0;
      state.cfg.Interlaced = 0;
      
      state.cfg.Artifacts = 0;
      state.cfg.Noise = 0;
      state.cfg.Ghosting = 0;
      state.cfg.ScanLines = 0;
      state.cfg.SimpleGhosting = 0;
      
      eo_settv( &state.cfg );
    }
    
205
206
    reset = reset || state.cfg.Chroma81 != option;
    state.cfg.Chroma81 = option;
207
208
  }
  
209
210
  {
    static int hires[] = { HIRESDISABLED, HIRESWRX };
211
    int option = coreopt( env_cb, core_vars, state.sha1, "81_highres", NULL );
212
    option += option < 0;
213
    reset = reset || state.cfg.HiRes != hires[ option ];
214
215
216
    state.cfg.HiRes = hires[ option ];
  }
  
217
218
  {
    static int sound[] = { AY_TYPE_DISABLED, AY_TYPE_ZONX };
219
    int option = coreopt( env_cb, core_vars, state.sha1, "81_sound", NULL );
220
221
222
223
224
    option += option < 0;
    reset = reset || state.cfg.SoundCard != sound[ option ];
    state.cfg.SoundCard = sound[ option ];
  }
  
225
  state.transp = coreopt( env_cb, core_vars, state.sha1, "81_keybovl_transp", NULL ) != 1;
226
227
228

  {
    const char* value;
229
    int option = coreopt( env_cb, core_vars, state.sha1, "81_key_hold_time", &value );
230
231
    state.ms = option >= 0 ? strtoll( value, NULL, 10 ) : 500LL;
  }
232
  
233
  {
234
    const int keys[] = { 0, 0, VK_RETURN, VK_SHIFT, VK_SPACE, VK_DECIMAL };
235
236
    const char* value;
    
237
238
239
240
241
    int option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_up", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_UP ] = option < 0 || option == 1 ? '7' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_down", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_DOWN ] = option < 0 || option == 1 ? '6' : option < 6 ? keys[ option ] : toupper( *value );
242
    
243
244
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_left", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_LEFT ] = option < 0 || option == 1 ? '5' : option < 6 ? keys[ option ] : toupper( *value );
245
    
246
247
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_right", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_RIGHT ] = option < 0 || option == 1 ? '8' : option < 6 ? keys[ option ] : toupper( *value );
248
    
249
250
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_a", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_A ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
251
    
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_b", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_B ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_x", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_X ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_y", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_Y ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_l", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_L ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_r", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_R ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_l2", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_L2 ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
    
    option = coreopt( env_cb, core_vars, state.sha1, "81_joypad_r2", &value );
    zx81ovl.joymap[ RETRO_DEVICE_ID_JOYPAD_R2 ] = option < 0 || option == 1 ? '0' : option < 6 ? keys[ option ] : toupper( *value );
272
273
  }
  
274
  state.scaled = ( WinR - WinL ) == 640;
275
  return ( reset ? UPDATE_RESET : 0 ) | ( old_scaled != state.scaled ? UPDATE_AV : 0 );
Andre Leiradella's avatar
Andre Leiradella committed
276
277
}

278
#define VERSION "1.0a"
Steel01's avatar
Steel01 committed
279
280
281
#ifdef GIT_VERSION
static char version[] = VERSION " " GIT_VERSION;
#else
282
static char version[] = VERSION " .......";
Steel01's avatar
Steel01 committed
283
#endif
284

Andre Leiradella's avatar
Andre Leiradella committed
285
286
void retro_get_system_info( struct retro_system_info* info )
{
Steel01's avatar
Steel01 committed
287
#ifndef GIT_VERSION
288
  memcpy(version + sizeof(VERSION), eo_githash, 7);
Steel01's avatar
Steel01 committed
289
#endif
290

Andre Leiradella's avatar
Andre Leiradella committed
291
  info->library_name = "EightyOne";
292
  info->library_version = version;
Andre Leiradella's avatar
Andre Leiradella committed
293
294
  info->need_fullpath = false;
  info->block_extract = false;
295
  info->valid_extensions = "p|tzx|t81";
Andre Leiradella's avatar
Andre Leiradella committed
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
}

void retro_set_environment( retro_environment_t cb )
{
  env_cb = cb;

  static const struct retro_controller_description controllers[] = {
    { "Cursor Joystick", RETRO_DEVICE_CURSOR_JOYSTICK },
  };

  static const struct retro_controller_description keyboards[] = {
    { "Sinclair Keyboard", RETRO_DEVICE_SINCLAIR_KEYBOARD },
  };

  static const struct retro_controller_info ports[] = {
    { controllers, sizeof( controllers ) / sizeof( controllers[ 0 ] ) }, // port 1
    { keyboards,   sizeof( keyboards )   / sizeof( keyboards[ 0 ] )   }, // port 2
    { NULL, 0 }
  };

  // This seem to be broken right now, as info is NULL in retro_load_game
  // even when we load a game via the frontend after booting to BASIC.
  //bool yes = true;
  //cb( RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, (void*)&yes );

  cb( RETRO_ENVIRONMENT_SET_VARIABLES, (void*)core_vars );
  cb( RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports );
}

325
unsigned retro_api_version( void )
Andre Leiradella's avatar
Andre Leiradella committed
326
327
328
329
{
  return RETRO_API_VERSION;
}

330
void retro_init( void )
Andre Leiradella's avatar
Andre Leiradella committed
331
332
333
334
{
  struct retro_log_callback log;

  if ( env_cb( RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log ) )
335
    log_cb = log.log;
Andre Leiradella's avatar
Andre Leiradella committed
336
337
  
  if ( !env_cb( RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb ) )
338
  {
Andre Leiradella's avatar
Andre Leiradella committed
339
    perf_cb.get_time_usec = NULL;
340
341
342
343
344
345
  }
  else
  {
    memset( (void*)&perf_cb, 0, sizeof( struct retro_perf_callback ) );
  }

346
  memset( (void*)&state, 0, sizeof( state ) );
Andre Leiradella's avatar
Andre Leiradella committed
347
348
349
350
351
}

bool retro_load_game( const struct retro_game_info* info )
{
  enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
Libretro-Admin's avatar
Libretro-Admin committed
352
353
354

  if (!info)
     return false;
Andre Leiradella's avatar
Andre Leiradella committed
355
356
357
358
359
360
  
  if ( !env_cb( RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt ) )
  {
    log_cb( RETRO_LOG_ERROR, "EightyOne needs RGB565\n" );
    return false;
  }
Libretro-Admin's avatar
Libretro-Admin committed
361

Steel01's avatar
Steel01 committed
362
#ifndef GIT_VERSION
Libretro-Admin's avatar
Libretro-Admin committed
363
  log_cb( RETRO_LOG_INFO, "\n%s", eo_gitstamp );
Steel01's avatar
Steel01 committed
364
#endif
Andre Leiradella's avatar
Andre Leiradella committed
365
  
366
  memset( (void*)&state, 0, sizeof( state ) );
367
  state.size = info->size;
368
  state.data = malloc( info->size );
369
  
370
  if ( !state.data )
371
372
373
374
375
  {
    log_cb( RETRO_LOG_ERROR, "Error allocating memory for game data\n" );
    return false;
  }
  
376
  memcpy( state.data, info->data, state.size );
377
  
378
379
  state.cfg.machine = MACHINEZX81;
  state.cfg.LambdaColour = COLOURDISABLED;
380
  state.cfg.LowRAMContents = LOWRAM_ROMSHADOW;
381
382
383
384
385
386
387
388
389
  state.cfg.ProtectROM = 1;
  state.cfg.ZXPrinter = 0;
  state.cfg.NTSC = 0;
  state.cfg.M1Not = 0;
  state.cfg.TS2050 = 0;
  state.cfg.ChrGen = CHRGENSINCLAIR;
  state.cfg.RamPack = RAMPACK16;
  state.cfg.HiRes = HIRESDISABLED;
  state.cfg.SoundCard = AY_TYPE_DISABLED;
390
391
392
  state.cfg.Chroma81 = 0;
  
  state.scaled = -1;
393
  TZXFile.AddTextBlock( "" ); // prevent a crash if the user does a LOAD ""
394
  TZXFile.FlashLoad = true;
Andre Leiradella's avatar
Andre Leiradella committed
395
  
396
397
398
399
400
401
  SHA1Context sha1;
  SHA1Reset( &sha1 );
  SHA1Input( &sha1, (const unsigned char*)info->data, info->size );
  SHA1Result( &sha1 );
  memcpy( state.sha1, sha1.Message_Digest, sizeof(state.sha1) );
  
Andre Leiradella's avatar
Andre Leiradella committed
402
  update_variables();
403
  retro_reset();
404
  keybovl_set( &zx81ovl );
405
  return true;
Andre Leiradella's avatar
Andre Leiradella committed
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
}

size_t retro_get_memory_size( unsigned id )
{
  return 0;
}

void* retro_get_memory_data( unsigned id )
{
  return NULL;
}

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

void retro_set_audio_sample( retro_audio_sample_t cb )
{
  (void)cb;
}

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

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

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

void retro_get_system_av_info( struct retro_system_av_info* info )
{
  info->geometry.base_width = WinR - WinL;
  info->geometry.base_height = WinB - WinT;
  info->geometry.max_width = WinR - WinL;
  info->geometry.max_height = WinB - WinT;
  info->geometry.aspect_ratio = 0.0f;
  info->timing.fps = 50.0;
  info->timing.sample_rate = 44100.0;
}

454
void retro_run( void )
Andre Leiradella's avatar
Andre Leiradella committed
455
456
457
458
459
{
  bool updated = false;

  if ( env_cb( RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated ) && updated )
  {
460
461
462
463
464
465
466
467
    int res = update_variables();
    
    if ( res & UPDATE_RESET )
    {
      retro_reset();
    }
    
    if ( res & UPDATE_AV )
468
469
470
471
472
    {
      struct retro_system_av_info info;
      retro_get_system_av_info( &info );
      env_cb( RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info );
    }
Andre Leiradella's avatar
Andre Leiradella committed
473
474
475
  }
  
  input_poll_cb();
476
477
  
  uint16_t* fb = TVFB + WinL + WinT * TVP / 2;
Andre Leiradella's avatar
Andre Leiradella committed
478
479

  eo_tick();
480
  keybovl_update( input_state_cb, state.devices, fb, TVP / 2, state.transp, state.scaled, state.ms, 20 );
481
  video_cb( (void*)fb, WinR - WinL, WinB - WinT, TVP );
Andre Leiradella's avatar
Andre Leiradella committed
482
483
}

484
void retro_deinit( void )
Andre Leiradella's avatar
Andre Leiradella committed
485
486
{
  eo_deinit();
487

Andre Leiradella's avatar
Andre Leiradella committed
488
#ifdef LOG_PERFORMANCE
489
490
  if ( perf_cb.perf_log )
    perf_cb.perf_log();
Andre Leiradella's avatar
Andre Leiradella committed
491
492
493
494
495
#endif
}

void retro_set_controller_port_device( unsigned port, unsigned device )
{
496
497
498
499
  if ( port < 2 )
  {
    state.devices[ port ] = device;
  }
Andre Leiradella's avatar
Andre Leiradella committed
500
501
}

502
void retro_reset( void )
Andre Leiradella's avatar
Andre Leiradella committed
503
{
504
  eo_init( &state.cfg );
505
  
Andre Leiradella's avatar
Andre Leiradella committed
506
  if ( state.size )
507
  {
508
    load_snap( "zx81_16k.z81" );
Andre Leiradella's avatar
Andre Leiradella committed
509
510
511
512
    
    zx81.TZXin = 1;
    TZXFile.LoadFile( state.data, state.size, false );
    TZXFile.Start();
513
514
    
    //eo_loadp( state.data, state.size );
515
  }
Andre Leiradella's avatar
Andre Leiradella committed
516
517
}

518
size_t retro_serialize_size( void )
Andre Leiradella's avatar
Andre Leiradella committed
519
{
520
  return eo_snapsize();
Andre Leiradella's avatar
Andre Leiradella committed
521
522
523
524
}

bool retro_serialize( void* data, size_t size )
{
525
526
  eo_snapsave( data );
  return true;
Andre Leiradella's avatar
Andre Leiradella committed
527
528
529
530
}

bool retro_unserialize( const void* data, size_t size )
{
531
532
  eo_snapload( data, size );
  return true;
Andre Leiradella's avatar
Andre Leiradella committed
533
534
}

535
void retro_cheat_reset( void )
Andre Leiradella's avatar
Andre Leiradella committed
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
{
}

void retro_cheat_set( unsigned a, bool b, const char* c )
{
  (void)a;
  (void)b;
  (void)c;
}

bool retro_load_game_special( unsigned a, const struct retro_game_info* b, size_t c )
{
  (void)a;
  (void)b;
  (void)c;
  return false;
}

554
void retro_unload_game( void )
Andre Leiradella's avatar
Andre Leiradella committed
555
{
556
557
  free( state.data );
  state.data = NULL;
Andre Leiradella's avatar
Andre Leiradella committed
558
559
}

560
unsigned retro_get_region( void )
Andre Leiradella's avatar
Andre Leiradella committed
561
562
563
{
  return RETRO_REGION_PAL;
}