libretro.c 37.5 KB
Newer Older
twinaphex's avatar
twinaphex committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "libretro.h"
22
#include "libretro_core_options.h"
Libretro-Admin's avatar
Libretro-Admin committed
23
#include <retro_miscellaneous.h>
Libretro-Admin's avatar
Libretro-Admin committed
24
#include <retro_timers.h>
Libretro-Admin's avatar
Libretro-Admin committed
25
#include <file/file_path.h>
twinaphex's avatar
twinaphex committed
26

27
#if defined(_WIN32) && !defined(_XBOX)
ToadKing's avatar
ToadKing committed
28
#include <windows.h>
twinaphex's avatar
twinaphex committed
29
30
#elif defined(_WIN32) && defined(_XBOX)
#include <xtl.h>
ToadKing's avatar
ToadKing committed
31
#endif
twinaphex's avatar
twinaphex committed
32
#include <stdlib.h>
Adriano Moura's avatar
Adriano Moura committed
33
#include <ctype.h>
twinaphex's avatar
twinaphex committed
34
35
36
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
37
38
39
40
#ifdef _WIN32
#include <direct.h>
#else
#include <sys/time.h>
twinaphex's avatar
twinaphex committed
41
#include <unistd.h>
42
#endif
twinaphex's avatar
twinaphex committed
43

44
#include "cmd.h"
twinaphex's avatar
twinaphex committed
45
46
47
48
49
#include "common.h"
#include "quakedef.h"
#include "d_local.h"
#include "sys.h"

50
#include "qtypes.h"
twinaphex's avatar
twinaphex committed
51
#include "sound.h"
52
#include "bgmusic.h"
twinaphex's avatar
twinaphex committed
53
54
55
56
57
58
59
60
61
62
#include "keys.h"
#include "cdaudio_driver.h"

#ifdef NQ_HACK
#include "client.h"
#include "host.h"

qboolean isDedicated;
#endif

ToadKing's avatar
ToadKing committed
63
64
65
66
#ifdef GEKKO
#include <ogc/lwp_watchdog.h>
#endif

twinaphex's avatar
twinaphex committed
67
68
69
70
71
#ifdef __CELLOS_LV2__
#include <sys/sys_time.h>
#include <sys/timer.h>
#endif

frangarcj's avatar
frangarcj committed
72
73
#define SURFCACHE_SIZE 10485760

74
#define RETRO_DEVICE_MODERN  RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 2)
75
#define RETRO_DEVICE_JOYPAD_ALT  RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
76

twinaphex's avatar
twinaphex committed
77
78
extern void CDAudio_Update(void);

Libretro-Admin's avatar
Libretro-Admin committed
79
80
unsigned width       = 320;
unsigned height      = 200;
81
unsigned device_type = 0;
82

83
84
unsigned MEMSIZE_MB;

Libretro-Admin's avatar
Libretro-Admin committed
85
static struct retro_rumble_interface rumble;
86
static bool libretro_supports_bitmasks = false;
Libretro-Admin's avatar
Libretro-Admin committed
87

88
#if defined(HW_DOL)
89
#define DEFAULT_MEMSIZE_MB 8
Libretro-Admin's avatar
Libretro-Admin committed
90
91
#elif defined(WIIU)
#define DEFAULT_MEMSIZE_MB 32
frangarcj's avatar
frangarcj committed
92
#elif defined(HW_RVL) || defined(_XBOX1) 
93
#define DEFAULT_MEMSIZE_MB 24
94
#else
95
#define DEFAULT_MEMSIZE_MB 32
96
#endif
twinaphex's avatar
twinaphex committed
97

98
#define SAMPLERATE 48000
99
100
101
102
103

// System analog stick range is -0x8000 to 0x8000
#define ANALOG_RANGE 0x8000
// Default deadzone: 15%
static int analog_deadzone = (int)(0.15f * ANALOG_RANGE);
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#define GP_MAXBINDS 32

typedef struct {
   struct retro_input_descriptor desc[GP_MAXBINDS];
   struct {
      char *key;
      char *com;
   } bind[GP_MAXBINDS];
} gp_layout_t;

gp_layout_t modern = {
   {
      { 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" },
radius's avatar
radius committed
121
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B,     "Swim Down" },
122
123
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A,     "Strafe Right" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X,     "Strafe Left" },
radius's avatar
radius committed
124
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y,     "Swim Up" },
125
126
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L,     "Previous Weapon" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R,     "Next Weapon" },
127
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2,    "Jump" },
radius's avatar
radius committed
128
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "Fire" },
129
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Show Scores" },
130
131
132
133
134
135
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Menu" },
      { 0 },
   },
   {
      {"JOY_LEFT",  "+moveleft"},     {"JOY_RIGHT", "+moveright"},
      {"JOY_DOWN",  "+back"},         {"JOY_UP",    "+forward"},
136
137
      {"JOY_B",     "+movedown"},     {"JOY_A",     "+moveright"},
      {"JOY_X",     "+moveup"},       {"JOY_Y",     "+moveleft"},
138
139
      {"JOY_L",     "impulse 12"},    {"JOY_R",     "impulse 10"},
      {"JOY_L2",    "+jump"},         {"JOY_R2",    "+attack"},
140
      {"JOY_SELECT","+showscores"},   {"JOY_START", "togglemenu"},
141
142
143
144
145
146
147
148
149
150
151
152
153
      { 0 },
   },
};
gp_layout_t classic = {

   {
      { 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,     "Jump" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A,     "Cycle Weapon" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X,     "Freelook" },
radius's avatar
radius committed
154
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y,     "Fire" },
155
156
157
158
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L,     "Strafe Left" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R,     "Strafe Right" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2,    "Look Up" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "Look Down" },
radius's avatar
radius committed
159
160
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3,    "Move Down" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3,    "Swim Up" },
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Toggle Run Mode" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Menu" },
      { 0 },
   },
   {
      {"JOY_LEFT",  "+left"},         {"JOY_RIGHT", "+right"},
      {"JOY_DOWN",  "+back"},         {"JOY_UP",    "+forward"},
      {"JOY_B",     "+jump"} ,        {"JOY_A",     "impulse 10"},
      {"JOY_X",     "+klook"},        {"JOY_Y",     "+attack"},
      {"JOY_L",     "+moveleft"},     {"JOY_R",     "+moveright"},
      {"JOY_L2",    "+lookup"},       {"JOY_R2",    "+lookdown"},
      {"JOY_L3",    "+movedown"},     {"JOY_R3",    "+moveup"},
      {"JOY_SELECT","+togglewalk"},   {"JOY_START", "togglemenu"},
      { 0 },
   },
};
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
gp_layout_t classic_alt = {

   {
      { 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,     "Look Down" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A,     "Look Right" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X,     "Look Up" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y,     "Look Left" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L,     "Jump" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R,     "Fire" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2,    "Run" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2,    "Next Weapon" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3,    "Move Down" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3,    "Previous Weapon" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT,"Toggle Run Mode" },
      { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Menu" },
      { 0 },
   },
   {
      {"JOY_LEFT",  "+moveleft"},     {"JOY_RIGHT", "+moveright"},
      {"JOY_DOWN",  "+back"},         {"JOY_UP",    "+forward"},
      {"JOY_B",     "+lookdown"},     {"JOY_A",     "+right"},
      {"JOY_X",     "+lookup"},       {"JOY_Y",     "+left"},
      {"JOY_L",     "+jump"},         {"JOY_R",     "+attack"},
      {"JOY_L2",    "+speed"},          {"JOY_R2",    "impulse 10"},
      {"JOY_L3",    "+movedown"},     {"JOY_R3",    "impulse 12"},
      {"JOY_SELECT","+togglewalk"},   {"JOY_START", "togglemenu"},
      { 0 },
   },
};
twinaphex's avatar
twinaphex committed
210

211
gp_layout_t *gp_layoutp = NULL;
212

213
float framerate = 60.0f;
Libretro-Admin's avatar
Libretro-Admin committed
214
static bool initial_resolution_set = false;
215
static int invert_y_axis = 1;
twinaphex's avatar
twinaphex committed
216
217
218

unsigned char *heap;

219
220
221
#define MAX_PADS 1
static unsigned quake_devices[1];

222
223
static void extract_basename(char *buf, const char *path, size_t size)
{
Libretro-Admin's avatar
Libretro-Admin committed
224
   char *ext        = NULL;
225
226
227
228
229
230
231
232
233
234
235
236
   const char *base = strrchr(path, '/');
   if (!base)
      base = strrchr(path, '\\');
   if (!base)
      base = path;

   if (*base == '\\' || *base == '/')
      base++;

   strncpy(buf, base, size - 1);
   buf[size - 1] = '\0';

Libretro-Admin's avatar
Libretro-Admin committed
237
   ext = strrchr(buf, '.');
238
239
240
241
   if (ext)
      *ext = '\0';
}

twinaphex's avatar
twinaphex committed
242
243
244
// =======================================================================
// General routines
// =======================================================================
245
//
246
247
248
249
250
251
252
static retro_log_printf_t log_cb;
static retro_video_refresh_t video_cb;
static retro_audio_sample_t audio_cb;
static retro_audio_sample_batch_t audio_batch_cb;
retro_environment_t environ_cb;
static retro_input_poll_t poll_cb;
static retro_input_state_t input_cb;
twinaphex's avatar
twinaphex committed
253
254
255

void Sys_Printf(const char *fmt, ...)
{
Libretro-Admin's avatar
Libretro-Admin committed
256
257
258
259
260
#if 0
   char buffer[256];
   va_list ap;
   va_start(ap, fmt);
   vsprintf(buffer, fmt, ap);
261
   if (log_cb)
Libretro-Admin's avatar
Libretro-Admin committed
262
      log_cb(RETRO_LOG_INFO, "%s\n", buffer);
Libretro-Admin's avatar
Libretro-Admin committed
263
264
   va_end(ap);
#endif
twinaphex's avatar
twinaphex committed
265
266
267
268
269
270
271
272
273
}

void Sys_Quit(void)
{
   Host_Shutdown();
}

void Sys_Init(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
274
275
276
277
278
279
   enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
   if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
   {
      if (log_cb)
         log_cb(RETRO_LOG_ERROR, "RGB565 is not supported.\n");
   }
twinaphex's avatar
twinaphex committed
280
281
}

Libretro-Admin's avatar
Libretro-Admin committed
282
bool Sys_Error(const char *error, ...)
twinaphex's avatar
twinaphex committed
283
{
Libretro-Admin's avatar
Libretro-Admin committed
284
285
   char buffer[256];
   va_list ap;
Libretro-Admin's avatar
Libretro-Admin committed
286

Libretro-Admin's avatar
Libretro-Admin committed
287
288
   va_start(ap, error);
   vsprintf(buffer, error, ap);
289
   if (log_cb)
Libretro-Admin's avatar
Libretro-Admin committed
290
      log_cb(RETRO_LOG_ERROR, "%s\n", buffer);
Libretro-Admin's avatar
Libretro-Admin committed
291
   va_end(ap);
twinaphex's avatar
twinaphex committed
292

Libretro-Admin's avatar
Libretro-Admin committed
293
   return false;
twinaphex's avatar
twinaphex committed
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
}

/*
   ============
   Sys_FileTime

   returns -1 if not present
   ============
   */
int Sys_FileTime(const char *path)
{
   struct stat buf;

   if (stat(path, &buf) == -1)
      return -1;

   return buf.st_mtime;
}

313
314
315
316
317
void Sys_mkdir(const char *path)
{
   path_mkdir(path);
}

twinaphex's avatar
twinaphex committed
318
319
320
321
322
323
void Sys_DebugLog(const char *file, const char *fmt, ...)
{
}

double Sys_DoubleTime(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
324
325
326
   static int first = true;
   static double oldtime = 0.0, curtime = 0.0;
   double newtime;
Libretro-Admin's avatar
Libretro-Admin committed
327
328
#if defined(WIIU)
   uint64_t OSGetSystemTime();
Libretro-Admin's avatar
Libretro-Admin committed
329
   newtime = (OSGetSystemTime() / 62156250.f);
Libretro-Admin's avatar
Libretro-Admin committed
330
#elif defined(GEKKO)
Libretro-Admin's avatar
Libretro-Admin committed
331
   newtime = ticks_to_microsecs(gettime()) / 1000000.0;
twinaphex's avatar
twinaphex committed
332
#elif defined(__CELLOS_LV2__)
Libretro-Admin's avatar
Libretro-Admin committed
333
   newtime = sys_time_get_system_time() / 1000000.0;
twinaphex's avatar
twinaphex committed
334
335
336
337
338
339
340
341
#elif defined(_WIN32)
   static double pfreq;
   static __int64 startcount;
   __int64 pcount;

   if (!pfreq)
   {
      __int64 freq;
Libretro-Admin's avatar
Libretro-Admin committed
342
343
344
345
346
347
      if (QueryPerformanceFrequency((LARGE_INTEGER*)&freq) && freq > 0)
      {
         //hardware timer available
         pfreq = (double)freq;
         QueryPerformanceCounter((LARGE_INTEGER*)&startcount);
      }
twinaphex's avatar
twinaphex committed
348
349
350
351
   }

   QueryPerformanceCounter((LARGE_INTEGER*)&pcount);
   /* TODO -check for wrapping - is it necessary? */
Libretro-Admin's avatar
Libretro-Admin committed
352
   newtime = (pcount - startcount) / pfreq;
ToadKing's avatar
ToadKing committed
353
#else
twinaphex's avatar
twinaphex committed
354
   struct timeval tp;
Libretro-Admin's avatar
Libretro-Admin committed
355
356
357
   gettimeofday(&tp, NULL);
   newtime = (double)tp.tv_sec + tp.tv_usec / 1000000.0;
#endif
twinaphex's avatar
twinaphex committed
358

Libretro-Admin's avatar
Libretro-Admin committed
359
360
361
362
363
   if (first)
   {
      first = false;
      oldtime = newtime;
   }
twinaphex's avatar
twinaphex committed
364

Libretro-Admin's avatar
Libretro-Admin committed
365
366
   if (newtime < oldtime)
   {
Libretro-Admin's avatar
Libretro-Admin committed
367
#if 0
Libretro-Admin's avatar
Libretro-Admin committed
368
369
370
      // warn if it's significant
      if (newtime - oldtime < -0.01)
         Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
Libretro-Admin's avatar
Libretro-Admin committed
371
#endif
twinaphex's avatar
twinaphex committed
372
   }
Libretro-Admin's avatar
Libretro-Admin committed
373
374
375
   else
      curtime += newtime - oldtime;
   oldtime = newtime;
twinaphex's avatar
twinaphex committed
376

Libretro-Admin's avatar
Libretro-Admin committed
377
   return curtime;
twinaphex's avatar
twinaphex committed
378
379
380
381
382
383
}

// =======================================================================
// Sleeps for microseconds
// =======================================================================

twinaphex's avatar
twinaphex committed
384
385
386
void
IN_Accumulate(void)
{}
ToadKing's avatar
ToadKing committed
387

twinaphex's avatar
twinaphex committed
388
389
390
char * Sys_ConsoleInput(void)
{
   return NULL;
ToadKing's avatar
ToadKing committed
391
392
393
394
395
396
397
398
}

qboolean
window_visible(void)
{
    return true;
}

twinaphex's avatar
twinaphex committed
399
400
401
402
403
404
405
406
407
408
409
410
void Sys_HighFPPrecision(void)
{
}

void Sys_LowFPPrecision(void)
{
}

viddef_t vid;			// global video state

void retro_init(void)
{
411
412
   struct retro_log_callback log;

Libretro-Admin's avatar
Libretro-Admin committed
413
   if(environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
414
      log_cb = log.log;
Libretro-Admin's avatar
Libretro-Admin committed
415
416
   else
      log_cb = NULL;
Libretro-Admin's avatar
Libretro-Admin committed
417

418
419
420
   if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
      libretro_supports_bitmasks = true;

Libretro-Admin's avatar
Libretro-Admin committed
421
   Sys_Init();
twinaphex's avatar
twinaphex committed
422
423
424
425
}

void retro_deinit(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
426
   Sys_Quit();
jdgleaver's avatar
jdgleaver committed
427
428
   if (heap)
      free(heap);
429
430

   libretro_supports_bitmasks = false;
twinaphex's avatar
twinaphex committed
431
432
433
434
435
436
437
}

unsigned retro_api_version(void)
{
   return RETRO_API_VERSION;
}

438
439
440
441
442
443
444
445
446
447
448
449
450
void gp_layout_set_bind(gp_layout_t gp_layout)
{
   char buf[100];
   unsigned i;
   for (i=0; gp_layout.bind[i].key; ++i)
   {
      snprintf(buf, sizeof(buf), "bind %s \"%s\"", gp_layout.bind[i].key,
                                                   gp_layout.bind[i].com);
      Cmd_ExecuteString(buf, src_command);
   }
}


twinaphex's avatar
twinaphex committed
451
452
void retro_set_controller_port_device(unsigned port, unsigned device)
{
453
   if (port == 0)
454
   {
455
456
457
      switch (device)
      {
         case RETRO_DEVICE_JOYPAD:
radius's avatar
radius committed
458
            quake_devices[port] = RETRO_DEVICE_JOYPAD;
459
460
461
            environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, classic.desc);
            gp_layout_set_bind(classic);
            break;
462
463
464
465
466
         case RETRO_DEVICE_JOYPAD_ALT:
            quake_devices[port] = RETRO_DEVICE_JOYPAD;
            environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, classic_alt.desc);
            gp_layout_set_bind(classic_alt);
            break;
467
468
469
470
471
472
473
474
         case RETRO_DEVICE_MODERN:
            quake_devices[port] = RETRO_DEVICE_MODERN;
            environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, modern.desc);
            gp_layout_set_bind(modern);
            break;
         case RETRO_DEVICE_KEYBOARD:
            quake_devices[port] = RETRO_DEVICE_KEYBOARD;
            break;
radius's avatar
radius committed
475
         case RETRO_DEVICE_NONE:
476
         default:
radius's avatar
radius committed
477
            quake_devices[port] = RETRO_DEVICE_NONE;
478
479
480
            if (log_cb)
               log_cb(RETRO_LOG_ERROR, "[libretro]: Invalid device.\n");
      }
481
   }
twinaphex's avatar
twinaphex committed
482
483
484
485
486
487
}

void retro_get_system_info(struct retro_system_info *info)
{
   memset(info, 0, sizeof(*info));
   info->library_name     = "TyrQuake";
488
489
490
491
#ifndef GIT_VERSION
#define GIT_VERSION ""
#endif
   info->library_version  = "v" stringify(TYR_VERSION) GIT_VERSION;
Libretro-Admin's avatar
Libretro-Admin committed
492
   info->need_fullpath    = true;
twinaphex's avatar
twinaphex committed
493
   info->valid_extensions = "pak";
twinaphex's avatar
twinaphex committed
494
495
496
497
}

void retro_get_system_av_info(struct retro_system_av_info *info)
{
Libretro-Admin's avatar
Libretro-Admin committed
498
   info->timing.fps            = framerate;
499
   info->timing.sample_rate    = SAMPLERATE;
twinaphex's avatar
twinaphex committed
500

501
502
   info->geometry.base_width   = width;
   info->geometry.base_height  = height;
Libretro-Admin's avatar
Libretro-Admin committed
503
504
   info->geometry.max_width    = width;
   info->geometry.max_height   = height;
twinaphex's avatar
twinaphex committed
505
   info->geometry.aspect_ratio = 4.0 / 3.0;
twinaphex's avatar
twinaphex committed
506
507
508
509
}

void retro_set_environment(retro_environment_t cb)
{
510
   static const struct retro_controller_description port_1[] = {
radius's avatar
radius committed
511
      { "Gamepad Classic", RETRO_DEVICE_JOYPAD },
512
      { "Gamepad Classic Alt", RETRO_DEVICE_JOYPAD_ALT },
radius's avatar
radius committed
513
514
      { "Gamepad Modern", RETRO_DEVICE_MODERN },
      { "Keyboard + Mouse", RETRO_DEVICE_KEYBOARD },
515
516
517
   };

   static const struct retro_controller_info ports[] = {
Tatsuya79's avatar
Tatsuya79 committed
518
      { port_1, 4 },
519
520
521
      { 0 },
   };

Libretro-Admin's avatar
Updates    
Libretro-Admin committed
522
523
   environ_cb = cb;

524
   libretro_set_core_options(environ_cb);
525
   cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
twinaphex's avatar
twinaphex committed
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
}

void retro_set_audio_sample(retro_audio_sample_t cb)
{
   audio_cb = 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)
{
   poll_cb = cb;
}

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

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

Libretro-Admin's avatar
Libretro-Admin committed
553
554
extern void M_Game_StartNewGame(void);

twinaphex's avatar
twinaphex committed
555
556
void retro_reset(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
557
   M_Game_StartNewGame();
twinaphex's avatar
twinaphex committed
558
559
560
561
}

void Sys_SendKeyEvents(void)
{
562
   int port;
Libretro-Admin's avatar
Libretro-Admin committed
563

564
565
566
   if (!poll_cb)
      return;

twinaphex's avatar
twinaphex committed
567
568
   poll_cb();

569
570
571
   if (!input_cb)
      return;

572
   for (port = 0; port < MAX_PADS; port++)
573
   {
574
575
576
      if (!input_cb)
         break;

577
578
579
      switch (quake_devices[port])
      {
         case RETRO_DEVICE_JOYPAD:
580
         case RETRO_DEVICE_JOYPAD_ALT:
581
         case RETRO_DEVICE_MODERN:
582
583
            {
               unsigned i;
Libretro-Admin's avatar
Libretro-Admin committed
584
585
586
587
               int16_t ret    = 0;
               if (libretro_supports_bitmasks)
                  ret = input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
               else
588
               {
Libretro-Admin's avatar
Libretro-Admin committed
589
590
591
592
593
                  for (i=RETRO_DEVICE_ID_JOYPAD_B; i <= RETRO_DEVICE_ID_JOYPAD_R3; ++i)
                  {
                     if (input_cb(port, RETRO_DEVICE_JOYPAD, 0, i))
                        ret |= (1 << i);
                  }
594
               }
Libretro-Admin's avatar
Libretro-Admin committed
595
596
597

               for (i=RETRO_DEVICE_ID_JOYPAD_B; 
                     i <= RETRO_DEVICE_ID_JOYPAD_R3; ++i)
598
               {
Libretro-Admin's avatar
Libretro-Admin committed
599
                  if (ret & (1 << i))
600
601
602
                     Key_Event(K_JOY_B + i, 1);
                  else
                     Key_Event(K_JOY_B + i, 0);
603
604
605
606
               }
            }
            break;
         case RETRO_DEVICE_KEYBOARD:
607
608
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT))
               Key_Event(K_MOUSE1, 1);
609
            else
610
               Key_Event(K_MOUSE1, 0);
611

612
613
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT))
               Key_Event(K_MOUSE2, 1);
614
            else
615
               Key_Event(K_MOUSE2, 0);
616

617
618
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE))
               Key_Event(K_MOUSE3, 1);
619
            else
620
               Key_Event(K_MOUSE3, 0);
621

622
623
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP))
               Key_Event(K_MOUSE4, 1);
624
            else
625
               Key_Event(K_MOUSE4, 0);
626

627
628
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN))
               Key_Event(K_MOUSE5, 1);
629
            else
630
               Key_Event(K_MOUSE5, 0);
631

632
633
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP))
               Key_Event(K_MOUSE6, 1);
634
            else
635
               Key_Event(K_MOUSE6, 0);
636

637
638
            if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN))
               Key_Event(K_MOUSE7, 1);
639
            else
640
               Key_Event(K_MOUSE7, 0);
641

642
            if (quake_devices[0] == RETRO_DEVICE_KEYBOARD) {
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
               if (input_cb(port, RETRO_DEVICE_KEYBOARD, 0, RETROK_UP))
                  Key_Event(K_UPARROW, 1);
               else
                  Key_Event(K_UPARROW, 0);

               if (input_cb(port, RETRO_DEVICE_KEYBOARD, 0, RETROK_DOWN))
                  Key_Event(K_DOWNARROW, 1);
               else
                  Key_Event(K_DOWNARROW, 0);

               if (input_cb(port, RETRO_DEVICE_KEYBOARD, 0, RETROK_LEFT))
                  Key_Event(K_LEFTARROW, 1);
               else
                  Key_Event(K_LEFTARROW, 0);

               if (input_cb(port, RETRO_DEVICE_KEYBOARD, 0, RETROK_RIGHT))
                  Key_Event(K_RIGHTARROW, 1);
               else
                  Key_Event(K_RIGHTARROW, 0);
               }
663
            break;
radius's avatar
radius committed
664
665
         case RETRO_DEVICE_NONE:
            break;
666
      }
667
   }
twinaphex's avatar
twinaphex committed
668
669
}

670
671
672
static void keyboard_cb(bool down, unsigned keycode,
      uint32_t character, uint16_t mod)
{
673
674
675
676
677
678
679
  // character-only events are discarded
  if (keycode != RETROK_UNKNOWN) {
      if (down)
         Key_Event((knum_t) keycode, 1);
      else
         Key_Event((knum_t) keycode, 0);
   }
680
681
}

twinaphex's avatar
twinaphex committed
682
683
void Sys_Sleep(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
684
   retro_sleep(1);
twinaphex's avatar
twinaphex committed
685
686
}

Tatsuya79's avatar
Tatsuya79 committed
687
688
689
690
691
const char *argv[MAX_NUM_ARGVS];
static const char *empty_string = "";

void retro_set_rumble_strong(void)
{
Libretro-Admin's avatar
Libretro-Admin committed
692
   uint16_t strength_strong = 0xffff;
Tatsuya79's avatar
Tatsuya79 committed
693
694
695
696
697
698
699
700
701
702
703
704
705
706
   if (!rumble.set_rumble_state)
      return;

   rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, strength_strong);
}

void retro_unset_rumble_strong(void)
{
   if (!rumble.set_rumble_state)
      return;

   rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, 0);
}

707
708
extern int coloredlights;

Tatsuya79's avatar
Tatsuya79 committed
709
710
bool state_rumble;

711
static void update_variables(bool startup)
712
713
{
   struct retro_variable var;
714

Libretro-Admin's avatar
Libretro-Admin committed
715
716
717
   var.key = "tyrquake_framerate";
   var.value = NULL;

718
   if (startup)
719
   {
720
721
722
723
724
725
726
727
728
729
     if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var)) {
       if (!strcmp(var.value, "auto"))
	 {
	   float target_framerate = 0.0f;
	   if (!environ_cb(RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE,
			   &target_framerate))
	     target_framerate = 60.0f;
	   framerate = target_framerate;
	 }
       else
730
         framerate = atof(var.value);
731
732
733
     }
     else
       framerate = 60.0f;
734
   }
Libretro-Admin's avatar
Libretro-Admin committed
735

736
737
738
739
740
741
742
743
744
745
746
747
   var.key = "tyrquake_colored_lighting";
   var.value = NULL;

   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && startup)
   {
      if (!strcmp(var.value, "enabled"))
         coloredlights = 1;
      else
         coloredlights = 0;
   }
   else
      coloredlights = 0;
748
   
749
   var.key = "tyrquake_resolution";
750
751
   var.value = NULL;

Libretro-Admin's avatar
Libretro-Admin committed
752
   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && !initial_resolution_set)
753
   {
754
755
      char *pch;
      char str[100];
756
      snprintf(str, sizeof(str), "%s", var.value);
757
758

      pch = strtok(str, "x");
759
760
      if (pch)
         width = strtoul(pch, NULL, 0);
761
      pch = strtok(NULL, "x");
762
763
      if (pch)
         height = strtoul(pch, NULL, 0);
764

765
766
      if (log_cb)
         log_cb(RETRO_LOG_INFO, "Got size: %u x %u.\n", width, height);
767

Libretro-Admin's avatar
Libretro-Admin committed
768
      initial_resolution_set = true;
Libretro-Admin's avatar
Libretro-Admin committed
769
   }
770

771
   var.key = "tyrquake_rumble";
772
773
   var.value = NULL;

774
   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
775
   {
776
777
778
779
      if (strcmp(var.value, "disabled") == 0)
         state_rumble = false;
      else
         state_rumble = true;
780
   }
781

782
   var.key = "tyrquake_invert_y_axis";
Tatsuya79's avatar
Tatsuya79 committed
783
784
785
786
787
   var.value = NULL;

   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
   {
      if (strcmp(var.value, "disabled") == 0)
788
         invert_y_axis = 1;
Tatsuya79's avatar
Tatsuya79 committed
789
      else
790
         invert_y_axis = -1;
Tatsuya79's avatar
Tatsuya79 committed
791
   }
792
793
794
795
796
797
798
799
   
   var.key = "tyrquake_analog_deadzone";
   var.value = NULL;

   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
   {
		analog_deadzone = (int)(atoi(var.value) * 0.01f * ANALOG_RANGE);
   }
800

801
802
}

803
804
805
806
807
808
static void update_env_variables(void)
{
   const char *default_username = NULL;

   if (environ_cb(RETRO_ENVIRONMENT_GET_USERNAME, &default_username))
   {
Alcaro's avatar
Alcaro committed
809
      if (default_username && default_username[0] != '\0')
810
811
812
813
814
815
816
817
      {
         char setplayer[256];
         sprintf(setplayer, "name %s", default_username);
         retro_cheat_set(0, true, setplayer);
      }
   }
}

818
819
820
byte *vid_buffer;
short *zbuffer;
short *finalimage;
frangarcj's avatar
frangarcj committed
821
byte* surfcache;
822

Libretro-Admin's avatar
Libretro-Admin committed
823
824
static void audio_process(void);
static void audio_callback(void);
825

826
827
static bool did_flip;

828
829
bool shutdown_core = false;

twinaphex's avatar
twinaphex committed
830
831
void retro_run(void)
{
832
   static bool has_set_username = false;
833
   bool updated = false;
Libretro-Admin's avatar
Updates    
Libretro-Admin committed
834
835
836

   did_flip = false;

837
   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
838
      update_variables(false);
839
840
841
842
843
   if (!has_set_username)
   {
      update_env_variables();
      has_set_username = true;
   }
Tatsuya79's avatar
Tatsuya79 committed
844
   
845
846
   if (!state_rumble)
      retro_unset_rumble_strong();
847

Libretro-Admin's avatar
Libretro-Admin committed
848
   Host_Frame(1.0 / framerate);
twinaphex's avatar
twinaphex committed
849

850
851
852
   if (shutdown_core)
      return;

853
854
   if (!did_flip)
      video_cb(NULL, width, height, width << 1); /* dupe */
855
   audio_process();
856
   audio_callback();
twinaphex's avatar
twinaphex committed
857
858
859
860
}

static void extract_directory(char *buf, const char *path, size_t size)
{
Libretro-Admin's avatar
Updates    
Libretro-Admin committed
861
862
   char *base = NULL;

twinaphex's avatar
twinaphex committed
863
864
865
   strncpy(buf, path, size - 1);
   buf[size - 1] = '\0';

Libretro-Admin's avatar
Updates    
Libretro-Admin committed
866
   base = strrchr(buf, '/');
twinaphex's avatar
twinaphex committed
867
868
869
870
871
872
   if (!base)
      base = strrchr(buf, '\\');

   if (base)
      *base = '\0';
   else
873
874
875
876
    {
       buf[0] = '.';
       buf[1] = '\0';
    }
twinaphex's avatar
twinaphex committed
877
878
879
880
}

bool retro_load_game(const struct retro_game_info *info)
{
881
   unsigned i;
882
   char g_rom_dir[1024], g_pak_path[1024], g_save_dir[1024];
Adriano Moura's avatar
Adriano Moura committed
883
   char cfg_file[1024];
884
   char *path_lower;
twinaphex's avatar
twinaphex committed
885
   quakeparms_t parms;
Libretro-Admin's avatar
Libretro-Admin committed
886
887
888
889
890
891
892
#if defined(_WIN32)
   char slash = '\\';
#else
   char slash = '/';
#endif
   bool use_external_savedir = false;
   const char *base_save_dir = NULL;
Libretro-Admin's avatar
Libretro-Admin committed
893
   struct retro_keyboard_callback cb = { keyboard_cb };
twinaphex's avatar
twinaphex committed
894

895
896
897
   if (!info)
      return false;

898
   path_lower = strdup(info->path);
899
900

   for (i=0; path_lower[i]; ++i)
901
902
       path_lower[i] = tolower(path_lower[i]);

903
   environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &cb);
904

905
   update_variables(true);
906

twinaphex's avatar
twinaphex committed
907
908
   extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir));

909
   snprintf(g_pak_path, sizeof(g_pak_path), "%s", info->path);
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
   
   if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &base_save_dir) && base_save_dir)
   {
		if (strlen(base_save_dir) > 0)
		{
			// Get game 'name' (i.e. subdirectory)
			char game_name[1024];
			extract_basename(game_name, g_rom_dir, sizeof(game_name));
			
			// > Build final save path
			snprintf(g_save_dir, sizeof(g_save_dir), "%s%c%s", base_save_dir, slash, game_name);
			use_external_savedir = true;
			
			// > Create save directory, if required
			if (!path_is_directory(g_save_dir))
			{
				use_external_savedir = path_mkdir(g_save_dir);
			}
		}
   }
   // > Error check
   if (!use_external_savedir)
   {
		// > Use ROM directory fallback...
		snprintf(g_save_dir, sizeof(g_save_dir), "%s", g_rom_dir);
	}
	else
	{
		// > Final check: is the save directory the same as the 'rom' directory?
		//   (i.e. ensure logical behaviour if user has set a bizarre save path...)
		use_external_savedir = (strcmp(g_save_dir, g_rom_dir) != 0);
	}
942

Libretro-Admin's avatar
Libretro-Admin committed
943
944
945
946
   if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
      log_cb(RETRO_LOG_INFO, "Rumble environment supported.\n");
   else
      log_cb(RETRO_LOG_INFO, "Rumble environment not supported.\n");
947

948
949
   MEMSIZE_MB = DEFAULT_MEMSIZE_MB;

950
951
952
953
   if ( strstr(path_lower, "id1") ||
        strstr(path_lower, "quoth") ||
        strstr(path_lower, "hipnotic") ||
        strstr(path_lower, "rogue") )
954
   {
Libretro-Admin's avatar
Libretro-Admin committed
955
#if (defined(HW_RVL) && !defined(WIIU)) || defined(_XBOX1)
956
957
      MEMSIZE_MB = 16;
#endif
958
      extract_directory(g_rom_dir, g_rom_dir, sizeof(g_rom_dir));
959
   }
960

twinaphex's avatar
twinaphex committed
961
962
   memset(&parms, 0, sizeof(parms));

963
964
   parms.argc = 1;
   parms.basedir = g_rom_dir;
965
966
   parms.savedir = g_save_dir;
   parms.use_exernal_savedir = use_external_savedir ? 1 : 0;
967
968
969
   parms.memsize = MEMSIZE_MB * 1024 * 1024;
   argv[0] = empty_string;

Tatsuya79's avatar
Tatsuya79 committed
970
   if (strstr(g_pak_path, "rogue"))
971
972
973
974
   {
      parms.argc++;
      argv[1] = "-rogue";
   }
Tatsuya79's avatar
Tatsuya79 committed
975
   else if (strstr(g_pak_path, "hipnotic"))
976
977
978
979
   {
      parms.argc++;
      argv[1] = "-hipnotic";
   }
Tatsuya79's avatar
Tatsuya79 committed
980
   else if (strstr(g_pak_path, "quoth"))
981
982
983
984
   {
      parms.argc++;
      argv[1] = "-quoth";
   }
Tatsuya79's avatar
Tatsuya79 committed
985
   else if (!strstr(g_pak_path, "id1"))
986
   {
987
      char basename[1024];
988
989
990
      parms.argc++;
      argv[1] = "-game";
      parms.argc++;
991
992
      extract_basename(basename, g_rom_dir, sizeof(basename));
      argv[2] = basename;
993
994
      extract_directory(g_rom_dir, g_rom_dir, sizeof(g_rom_dir));
   }
995
996
997
998

   parms.argv = argv;

   COM_InitArgv(parms.argc, parms.argv);
twinaphex's avatar
twinaphex committed
999
1000
1001
1002
1003
1004
1005
1006
1007

   parms.argc = com_argc;
   parms.argv = com_argv;

   heap = (unsigned char*)malloc(parms.memsize);

   parms.membase = heap;

#ifdef NQ_HACK
1008
1009
   if (log_cb)
      log_cb(RETRO_LOG_INFO, "Quake Libretro -- TyrQuake Version %s\n", stringify(TYR_VERSION));
twinaphex's avatar
twinaphex committed
1010
1011
#endif
#ifdef QW_HACK
1012
1013
   if (log_cb)
      log_cb(RETRO_LOG_INFO, "QuakeWorld Libretro -- TyrQuake Version %s\n", stringify(TYR_VERSION));
twinaphex's avatar
twinaphex committed
1014
1015
#endif

Libretro-Admin's avatar
Libretro-Admin committed
1016
1017
   if (!Host_Init(&parms))
   {
Libretro-Admin's avatar
Libretro-Admin committed
1018
1019
1020
      struct retro_message msg;
      char msg_local[256];

Libretro-Admin's avatar
Libretro-Admin committed
1021
1022
      Host_Shutdown();

Libretro-Admin's avatar
Libretro-Admin committed
1023
1024
1025
1026
1027
1028
      snprintf(msg_local, sizeof(msg_local),
            "PAK archive loading failed...");
      msg.msg    = msg_local;
      msg.frames = 360;
      if (environ_cb)
         environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
Libretro-Admin's avatar
Libretro-Admin committed
1029
1030
      return false;
   }
twinaphex's avatar
twinaphex committed
1031

1032
1033
   /* Override some default binds with more modern ones if we are booting the 
    * game for the first time. */
1034
   snprintf(cfg_file, sizeof(cfg_file), "%s%cconfig.cfg", g_save_dir, slash);
1035

1036
   if (!path_is_valid(cfg_file))
1037
   {
1038
       Cvar_Set("gamma", "0.95");
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
       Cmd_ExecuteString("bind ' \"toggleconsole\"", src_command);
       Cmd_ExecuteString("bind ~ \"toggleconsole\"", src_command);
       Cmd_ExecuteString("bind ` \"toggleconsole\"", src_command);

       Cmd_ExecuteString("bind f \"+moveup\"", src_command);
       Cmd_ExecuteString("bind c \"+movedown\"", src_command);

       Cmd_ExecuteString("bind a \"+moveleft\"", src_command);
       Cmd_ExecuteString("bind d \"+moveright\"", src_command);
       Cmd_ExecuteString("bind w \"+forward\"", src_command);
       Cmd_ExecuteString("bind s \"+back\"", src_command);

       Cmd_ExecuteString("bind e \"impulse 10\"", src_command);
       Cmd_ExecuteString("bind q \"impulse 12\"", src_command);
   }

1055
1056
1057
1058
1059
1060
1061
1062
1063
   Cmd_ExecuteString("bind AUX1 \"+moveright\"", src_command);
   Cmd_ExecuteString("bind AUX2 \"+moveleft\"", src_command);
   Cmd_ExecuteString("bind AUX3 \"+back\"", src_command);
   Cmd_ExecuteString("bind AUX4 \"+forward\"", src_command);
   Cmd_ExecuteString("bind AUX5 \"+right\"", src_command);
   Cmd_ExecuteString("bind AUX6 \"+left\"", src_command);
   Cmd_ExecuteString("bind AUX7 \"+lookup\"", src_command);
   Cmd_ExecuteString("bind AUX8 \"+lookdown\"", src_command);

twinaphex's avatar
twinaphex committed
1064
1065
1066
   return true;
}

1067
1068


twinaphex's avatar
twinaphex committed
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
void retro_unload_game(void)
{
}

unsigned retro_get_region(void)
{
   return RETRO_REGION_NTSC;
}

bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
{
   (void)type;
   (void)info;
   (void)num;
   return false;
}

size_t retro_serialize_size(void)
{
Themaister's avatar
Themaister committed
1088
   return 0;
twinaphex's avatar
twinaphex committed
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
}

bool retro_serialize(void *data_, size_t size)
{
   return false;
}

bool retro_unserialize(const void *data_, size_t size)
{
   return false;
}

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

size_t retro_get_memory_size(unsigned id)
{
   (void)id;
   return 0;
}

void retro_cheat_reset(void)
{}

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

Libretro-Admin's avatar
Libretro-Admin committed
1121
1122
   if (code)
      Cmd_ExecuteString(code, src_command);
twinaphex's avatar
twinaphex committed
1123
1124
1125
}

/*
Libretro-Admin's avatar
Libretro-Admin committed
1126
 * VIDEO
twinaphex's avatar
twinaphex committed
1127
1128
1129
1130
 */

unsigned short d_8to16table[256];

1131
#define MAKECOLOR(r, g, b) (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3))
1132

1133

twinaphex's avatar
twinaphex committed
1134
1135
void VID_SetPalette(unsigned char *palette)
{
1136
   unsigned i, j;
1137
   unsigned short *pal = &d_8to16table[0];