libretro.c 37.3 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[] = {
518
      { port_1, 3 },
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
718
   var.key = "tyrquake_framerate";
   var.value = NULL;

   if (startup && environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
719
720
721
722
723
724
725
726
727
728
729
730
   {
      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
         framerate = atof(var.value);
   }
Libretro-Admin's avatar
Libretro-Admin committed
731
   else
732
      framerate = 60.0f;
Libretro-Admin's avatar
Libretro-Admin committed
733

734
735
736
737
738
739
740
741
742
743
744
745
   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;
746
   
747
   var.key = "tyrquake_resolution";
748
749
   var.value = NULL;

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

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

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

Libretro-Admin's avatar
Libretro-Admin committed
766
      initial_resolution_set = true;
Libretro-Admin's avatar
Libretro-Admin committed
767
   }
768

769
   var.key = "tyrquake_rumble";
770
771
   var.value = NULL;

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

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

   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
   {
      if (strcmp(var.value, "disabled") == 0)
786
         invert_y_axis = 1;
Tatsuya79's avatar
Tatsuya79 committed
787
      else
788
         invert_y_axis = -1;
Tatsuya79's avatar
Tatsuya79 committed
789
   }
790
791
792
793
794
795
796
797
   
   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);
   }
798

799
800
}

801
802
803
804
805
806
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
807
      if (default_username && default_username[0] != '\0')
808
809
810
811
812
813
814
815
      {
         char setplayer[256];
         sprintf(setplayer, "name %s", default_username);
         retro_cheat_set(0, true, setplayer);
      }
   }
}

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

Libretro-Admin's avatar
Libretro-Admin committed
821
822
static void audio_process(void);
static void audio_callback(void);
823

824
825
static bool did_flip;

826
827
bool shutdown_core = false;

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

   did_flip = false;

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

Libretro-Admin's avatar
Libretro-Admin committed
846
   Host_Frame(1.0 / framerate);
twinaphex's avatar
twinaphex committed
847

848
849
850
   if (shutdown_core)
      return;

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

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

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

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

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

bool retro_load_game(const struct retro_game_info *info)
{
879
   unsigned i;
880
   char g_rom_dir[1024], g_pak_path[1024], g_save_dir[1024];
Adriano Moura's avatar
Adriano Moura committed
881
   char cfg_file[1024];
882
   char *path_lower;
twinaphex's avatar
twinaphex committed
883
   quakeparms_t parms;
Libretro-Admin's avatar
Libretro-Admin committed
884
885
886
887
888
889
890
#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
891
   struct retro_keyboard_callback cb = { keyboard_cb };
twinaphex's avatar
twinaphex committed
892

893
894
895
   if (!info)
      return false;

896
   path_lower = strdup(info->path);
897
898

   for (i=0; path_lower[i]; ++i)
899
900
       path_lower[i] = tolower(path_lower[i]);

901
   environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &cb);
902

903
   update_variables(true);
904

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

907
   snprintf(g_pak_path, sizeof(g_pak_path), "%s", info->path);
908
909
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
   
   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);
	}
940

Libretro-Admin's avatar
Libretro-Admin committed
941
942
943
944
   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");
945

946
947
   MEMSIZE_MB = DEFAULT_MEMSIZE_MB;

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

twinaphex's avatar
twinaphex committed
959
960
   memset(&parms, 0, sizeof(parms));

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

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

   parms.argv = argv;

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

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

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

   parms.membase = heap;

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

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

Libretro-Admin's avatar
Libretro-Admin committed
1019
1020
      Host_Shutdown();

Libretro-Admin's avatar
Libretro-Admin committed
1021
1022
1023
1024
1025
1026
      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
1027
1028
      return false;
   }
twinaphex's avatar
twinaphex committed
1029

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

1034
   if (!path_is_valid(cfg_file))
1035
   {
1036
       Cvar_Set("gamma", "0.95");
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
       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);
   }

1053
1054
1055
1056
1057
1058
1059
1060
1061
   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
1062
1063
1064
   return true;
}

1065
1066


twinaphex's avatar
twinaphex committed
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
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
1086
   return 0;
twinaphex's avatar
twinaphex committed
1087
1088
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
}

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;
1118

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

/*
Libretro-Admin's avatar
Libretro-Admin committed
1124
 * VIDEO
twinaphex's avatar
twinaphex committed
1125
1126
1127
1128
 */

unsigned short d_8to16table[256];

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

1131

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

1137
1138
   for(i = 0, j = 0; i < 256; i++, j += 3)
      *pal++ = MAKECOLOR(palette[j], palette[j+1], palette[j+2]);
leilei-'s avatar