Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
796 lines (662 loc) · 21.3 KB

SDL_ipodvideo.c

File metadata and controls

796 lines (662 loc) · 21.3 KB
 
Feb 21, 2006
Feb 21, 2006
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
Sep 8, 2005
Sep 8, 2005
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <ctype.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include <linux/fb.h>
#include "SDL_video.h"
#include "SDL_mouse.h"
Feb 16, 2006
Feb 16, 2006
40
41
42
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
Sep 8, 2005
Sep 8, 2005
43
44
45
46
47
#include "SDL_sysevents.h"
#include "SDL_ipodvideo.h"
#define _THIS SDL_VideoDevice *this
May 28, 2006
May 28, 2006
48
49
50
51
52
53
54
55
56
static int iPod_VideoInit (_THIS, SDL_PixelFormat * vformat);
static SDL_Rect **iPod_ListModes (_THIS, SDL_PixelFormat * format,
Uint32 flags);
static SDL_Surface *iPod_SetVideoMode (_THIS, SDL_Surface * current,
int width, int height, int bpp,
Uint32 flags);
static int iPod_SetColors (_THIS, int firstcolor, int ncolors,
SDL_Color * colors);
static void iPod_UpdateRects (_THIS, int nrects, SDL_Rect * rects);
Sep 8, 2005
Sep 8, 2005
57
58
59
static void iPod_VideoQuit (_THIS);
static void iPod_PumpEvents (_THIS);
May 28, 2006
May 28, 2006
60
static long iPod_GetGeneration ();
Sep 8, 2005
Sep 8, 2005
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
static int initd = 0;
static int kbfd = -1;
static int fbfd = -1;
static int oldvt = -1;
static int curvt = -1;
static int old_kbmode = -1;
static long generation = 0;
static struct termios old_termios, cur_termios;
FILE *dbgout;
#define LCD_DATA 0x10
#define LCD_CMD 0x08
#define IPOD_OLD_LCD_BASE 0xc0001000
#define IPOD_OLD_LCD_RTC 0xcf001110
#define IPOD_NEW_LCD_BASE 0x70003000
#define IPOD_NEW_LCD_RTC 0x60005010
static unsigned long lcd_base, lcd_rtc, lcd_width, lcd_height;
May 28, 2006
May 28, 2006
82
83
static long
iPod_GetGeneration ()
Sep 8, 2005
Sep 8, 2005
84
85
86
87
88
{
int i;
char cpuinfo[256];
char *ptr;
FILE *file;
May 28, 2006
May 28, 2006
89
90
91
92
93
94
if ((file = fopen ("/proc/cpuinfo", "r")) != NULL) {
while (fgets (cpuinfo, sizeof (cpuinfo), file) != NULL)
if (SDL_strncmp (cpuinfo, "Revision", 8) == 0)
break;
fclose (file);
Sep 8, 2005
Sep 8, 2005
95
}
May 28, 2006
May 28, 2006
96
97
for (i = 0; !isspace (cpuinfo[i]); i++);
for (; isspace (cpuinfo[i]); i++);
Sep 8, 2005
Sep 8, 2005
98
ptr = cpuinfo + i + 2;
May 28, 2006
May 28, 2006
99
100
return SDL_strtol (ptr, NULL, 10);
Sep 8, 2005
Sep 8, 2005
101
102
}
May 28, 2006
May 28, 2006
103
104
static int
iPod_Available ()
Sep 8, 2005
Sep 8, 2005
105
106
107
108
{
return 1;
}
May 28, 2006
May 28, 2006
109
110
static void
iPod_DeleteDevice (SDL_VideoDevice * device)
Sep 8, 2005
Sep 8, 2005
111
112
113
114
115
{
free (device->hidden);
free (device);
}
May 28, 2006
May 28, 2006
116
117
118
119
void
iPod_InitOSKeymap (_THIS)
{
}
Sep 8, 2005
Sep 8, 2005
120
May 28, 2006
May 28, 2006
121
122
static SDL_VideoDevice *
iPod_CreateDevice (int devindex)
Sep 8, 2005
Sep 8, 2005
123
124
{
SDL_VideoDevice *this;
May 28, 2006
May 28, 2006
125
126
this = (SDL_VideoDevice *) SDL_malloc (sizeof (SDL_VideoDevice));
Sep 8, 2005
Sep 8, 2005
127
if (this) {
May 28, 2006
May 28, 2006
128
129
130
memset (this, 0, sizeof *this);
this->hidden = (struct SDL_PrivateVideoData *)
SDL_malloc (sizeof (struct SDL_PrivateVideoData));
Sep 8, 2005
Sep 8, 2005
131
132
}
if (!this || !this->hidden) {
May 28, 2006
May 28, 2006
133
134
135
136
SDL_OutOfMemory ();
if (this)
SDL_free (this);
return 0;
Sep 8, 2005
Sep 8, 2005
137
}
May 28, 2006
May 28, 2006
138
139
140
memset (this->hidden, 0, sizeof (struct SDL_PrivateVideoData));
generation = iPod_GetGeneration ();
Sep 8, 2005
Sep 8, 2005
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
this->VideoInit = iPod_VideoInit;
this->ListModes = iPod_ListModes;
this->SetVideoMode = iPod_SetVideoMode;
this->SetColors = iPod_SetColors;
this->UpdateRects = iPod_UpdateRects;
this->VideoQuit = iPod_VideoQuit;
this->AllocHWSurface = 0;
this->CheckHWBlit = 0;
this->FillHWRect = 0;
this->SetHWColorKey = 0;
this->SetHWAlpha = 0;
this->LockHWSurface = 0;
this->UnlockHWSurface = 0;
this->FlipHWSurface = 0;
this->FreeHWSurface = 0;
this->SetCaption = 0;
this->SetIcon = 0;
this->IconifyWindow = 0;
this->GrabInput = 0;
this->GetWMInfo = 0;
this->InitOSKeymap = iPod_InitOSKeymap;
this->PumpEvents = iPod_PumpEvents;
this->free = iPod_DeleteDevice;
return this;
}
VideoBootStrap iPod_bootstrap = {
"ipod", "iPod Framebuffer Driver",
iPod_Available, iPod_CreateDevice
};
//--//
May 28, 2006
May 28, 2006
176
177
static int
iPod_VideoInit (_THIS, SDL_PixelFormat * vformat)
Sep 8, 2005
Sep 8, 2005
178
179
{
if (!initd) {
May 28, 2006
May 28, 2006
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*** Code adapted/copied from SDL fbcon driver. ***/
static const char *const tty0[] = { "/dev/tty0", "/dev/vc/0", 0 };
static const char *const vcs[] = { "/dev/vc/%d", "/dev/tty%d", 0 };
int i, tty0_fd;
dbgout =
fdopen (open ("/etc/sdlpod.log", O_WRONLY | O_SYNC | O_APPEND),
"a");
if (dbgout) {
setbuf (dbgout, 0);
fprintf (dbgout, "--> Started SDL <--\n");
}
// Try to query for a free VT
tty0_fd = -1;
for (i = 0; tty0[i] && (tty0_fd < 0); ++i) {
tty0_fd = open (tty0[i], O_WRONLY, 0);
}
if (tty0_fd < 0) {
tty0_fd = dup (0); /* Maybe stdin is a VT? */
}
ioctl (tty0_fd, VT_OPENQRY, &curvt);
close (tty0_fd);
tty0_fd = open ("/dev/tty", O_RDWR, 0);
if (tty0_fd >= 0) {
ioctl (tty0_fd, TIOCNOTTY, 0);
close (tty0_fd);
}
if ((geteuid () == 0) && (curvt > 0)) {
for (i = 0; vcs[i] && (kbfd < 0); ++i) {
char vtpath[12];
SDL_snprintf (vtpath, SDL_arraysize (vtpath), vcs[i], curvt);
kbfd = open (vtpath, O_RDWR);
}
}
if (kbfd < 0) {
if (dbgout)
fprintf (dbgout, "Couldn't open any VC\n");
return -1;
}
if (dbgout)
fprintf (stderr, "Current VT: %d\n", curvt);
if (kbfd >= 0) {
/* Switch to the correct virtual terminal */
if (curvt > 0) {
struct vt_stat vtstate;
if (ioctl (kbfd, VT_GETSTATE, &vtstate) == 0) {
oldvt = vtstate.v_active;
}
if (ioctl (kbfd, VT_ACTIVATE, curvt) == 0) {
if (dbgout)
fprintf (dbgout, "Waiting for switch to this VT... ");
ioctl (kbfd, VT_WAITACTIVE, curvt);
if (dbgout)
fprintf (dbgout, "done!\n");
}
}
// Set terminal input mode
if (tcgetattr (kbfd, &old_termios) < 0) {
if (dbgout)
fprintf (dbgout, "Can't get termios\n");
return -1;
}
cur_termios = old_termios;
// cur_termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
// cur_termios.c_iflag |= (BRKINT);
// cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN);
// cur_termios.c_oflag &= ~(OPOST);
// cur_termios.c_oflag |= (ONOCR | ONLRET);
cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
cur_termios.c_iflag &=
~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
cur_termios.c_cc[VMIN] = 0;
cur_termios.c_cc[VTIME] = 0;
if (tcsetattr (kbfd, TCSAFLUSH, &cur_termios) < 0) {
if (dbgout)
fprintf (dbgout, "Can't set termios\n");
return -1;
}
if (ioctl (kbfd, KDSKBMODE, K_MEDIUMRAW) < 0) {
if (dbgout)
fprintf (dbgout, "Can't set medium-raw mode\n");
return -1;
}
if (ioctl (kbfd, KDSETMODE, KD_GRAPHICS) < 0) {
if (dbgout)
fprintf (dbgout, "Can't set graphics\n");
return -1;
}
}
// Open the framebuffer
if ((fbfd = open ("/dev/fb0", O_RDWR)) < 0) {
if (dbgout)
fprintf (dbgout, "Can't open framebuffer\n");
return -1;
} else {
struct fb_var_screeninfo vinfo;
if (dbgout)
fprintf (dbgout, "Generation: %ld\n", generation);
if (generation >= 40000) {
lcd_base = IPOD_NEW_LCD_BASE;
} else {
lcd_base = IPOD_OLD_LCD_BASE;
}
ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo);
close (fbfd);
if (lcd_base == IPOD_OLD_LCD_BASE)
lcd_rtc = IPOD_OLD_LCD_RTC;
else if (lcd_base == IPOD_NEW_LCD_BASE)
lcd_rtc = IPOD_NEW_LCD_RTC;
else {
SDL_SetError ("Unknown iPod version");
return -1;
}
lcd_width = vinfo.xres;
lcd_height = vinfo.yres;
if (dbgout)
fprintf (dbgout, "LCD is %dx%d\n", lcd_width, lcd_height);
}
fcntl (kbfd, F_SETFL, O_RDWR | O_NONBLOCK);
/* Determine the current screen size */
this->info.current_w = lcd_width;
this->info.current_h = lcd_height;
if ((generation >= 60000) && (generation < 70000)) {
vformat->BitsPerPixel = 16;
vformat->Rmask = 0xF800;
vformat->Gmask = 0x07E0;
vformat->Bmask = 0x001F;
} else {
vformat->BitsPerPixel = 8;
vformat->Rmask = vformat->Gmask = vformat->Bmask = 0;
}
initd = 1;
if (dbgout)
fprintf (dbgout, "Initialized.\n\n");
Sep 8, 2005
Sep 8, 2005
331
332
333
334
}
return 0;
}
May 28, 2006
May 28, 2006
335
336
static SDL_Rect **
iPod_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
Sep 8, 2005
Sep 8, 2005
337
338
339
340
341
342
{
int width, height, fd;
static SDL_Rect r;
static SDL_Rect *rs[2] = { &r, 0 };
if ((fd = open ("/dev/fb0", O_RDWR)) < 0) {
May 28, 2006
May 28, 2006
343
return 0;
Sep 8, 2005
Sep 8, 2005
344
} else {
May 28, 2006
May 28, 2006
345
346
347
348
349
350
351
struct fb_var_screeninfo vinfo;
ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo);
close (fbfd);
width = vinfo.xres;
height = vinfo.yres;
Sep 8, 2005
Sep 8, 2005
352
353
354
355
356
357
358
359
}
r.x = r.y = 0;
r.w = width;
r.h = height;
return rs;
}
May 28, 2006
May 28, 2006
360
361
362
static SDL_Surface *
iPod_SetVideoMode (_THIS, SDL_Surface * current, int width, int height,
int bpp, Uint32 flags)
Sep 8, 2005
Sep 8, 2005
363
364
365
{
Uint32 Rmask, Gmask, Bmask;
if (bpp > 8) {
May 28, 2006
May 28, 2006
366
367
368
Rmask = 0xF800;
Gmask = 0x07E0;
Bmask = 0x001F;
Sep 8, 2005
Sep 8, 2005
369
} else {
May 28, 2006
May 28, 2006
370
Rmask = Gmask = Bmask = 0;
Sep 8, 2005
Sep 8, 2005
371
372
}
May 28, 2006
May 28, 2006
373
374
if (this->hidden->buffer)
SDL_free (this->hidden->buffer);
Feb 7, 2006
Feb 7, 2006
375
this->hidden->buffer = SDL_malloc (width * height * (bpp / 8));
Sep 8, 2005
Sep 8, 2005
376
if (!this->hidden->buffer) {
May 28, 2006
May 28, 2006
377
378
SDL_SetError ("Couldn't allocate buffer for requested mode");
return 0;
Sep 8, 2005
Sep 8, 2005
379
380
381
382
383
}
memset (this->hidden->buffer, 0, width * height * (bpp / 8));
if (!SDL_ReallocFormat (current, bpp, Rmask, Gmask, Bmask, 0)) {
May 28, 2006
May 28, 2006
384
385
386
387
SDL_SetError ("Couldn't allocate new pixel format");
SDL_free (this->hidden->buffer);
this->hidden->buffer = 0;
return 0;
Sep 8, 2005
Sep 8, 2005
388
389
390
}
if (bpp <= 8) {
May 28, 2006
May 28, 2006
391
392
393
394
395
396
397
398
int i, j;
for (i = 0; i < 256; i += 4) {
for (j = 0; j < 4; j++) {
current->format->palette->colors[i + j].r = 85 * j;
current->format->palette->colors[i + j].g = 85 * j;
current->format->palette->colors[i + j].b = 85 * j;
}
}
Sep 8, 2005
Sep 8, 2005
399
400
401
402
403
404
405
406
407
408
409
}
current->flags = flags & SDL_FULLSCREEN;
this->hidden->w = current->w = width;
this->hidden->h = current->h = height;
current->pitch = current->w * (bpp / 8);
current->pixels = this->hidden->buffer;
return current;
}
May 28, 2006
May 28, 2006
410
411
static int
iPod_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors)
Sep 8, 2005
Sep 8, 2005
412
{
May 28, 2006
May 28, 2006
413
414
415
416
417
418
419
420
421
422
if (SDL_VideoSurface && SDL_VideoSurface->format
&& SDL_VideoSurface->format->palette) {
int i, j;
for (i = 0; i < 256; i += 4) {
for (j = 0; j < 4; j++) {
SDL_VideoSurface->format->palette->colors[i + j].r = 85 * j;
SDL_VideoSurface->format->palette->colors[i + j].g = 85 * j;
SDL_VideoSurface->format->palette->colors[i + j].b = 85 * j;
}
}
Sep 8, 2005
Sep 8, 2005
423
424
425
426
}
return 0;
}
May 28, 2006
May 28, 2006
427
428
static void
iPod_VideoQuit (_THIS)
Sep 8, 2005
Sep 8, 2005
429
430
431
432
433
434
{
ioctl (kbfd, KDSETMODE, KD_TEXT);
tcsetattr (kbfd, TCSAFLUSH, &old_termios);
old_kbmode = -1;
if (oldvt > 0)
May 28, 2006
May 28, 2006
435
436
ioctl (kbfd, VT_ACTIVATE, oldvt);
Sep 8, 2005
Sep 8, 2005
437
if (kbfd > 0)
May 28, 2006
May 28, 2006
438
close (kbfd);
Sep 8, 2005
Sep 8, 2005
439
440
if (dbgout) {
May 28, 2006
May 28, 2006
441
442
fprintf (dbgout, "<-- Ended SDL -->\n");
fclose (dbgout);
Sep 8, 2005
Sep 8, 2005
443
}
May 28, 2006
May 28, 2006
444
Sep 8, 2005
Sep 8, 2005
445
446
447
448
kbfd = -1;
}
static char iPod_SC_keymap[] = {
May 28, 2006
May 28, 2006
449
450
0, /* 0 - no key */
'[' - 0x40, /* ESC (Ctrl+[) */
Sep 8, 2005
Sep 8, 2005
451
452
'1', '2', '3', '4', '5', '6', '7', '8', '9',
'-', '=',
May 28, 2006
May 28, 2006
453
'\b', '\t', /* Backspace, Tab (Ctrl+H,Ctrl+I) */
Sep 8, 2005
Sep 8, 2005
454
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
May 28, 2006
May 28, 2006
455
'\n', 0, /* Enter, Left CTRL */
Sep 8, 2005
Sep 8, 2005
456
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
May 28, 2006
May 28, 2006
457
0, '\\', /* left shift, backslash */
Sep 8, 2005
Sep 8, 2005
458
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
May 28, 2006
May 28, 2006
459
460
461
462
463
464
465
466
467
468
469
470
471
0, '*', 0, ' ', 0, /* right shift, KP mul, left alt, space, capslock */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1-10 */
0, 0, /* numlock, scrollock */
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', /* numeric keypad */
0, 0, /* padding */
0, 0, 0, /* "less" (?), F11, F12 */
0, 0, 0, 0, 0, 0, 0, /* padding */
'\n', 0, '/', 0, 0, /* KP enter, Rctrl, Ctrl, KP div, PrtSc, RAlt */
0, 0, 0, 0, 0, 0, 0, 0, 0, /* Break, Home, Up, PgUp, Left, Right, End, Down, PgDn */
0, 0, /* Ins, Del */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* padding */
0, 0, /* RWin, LWin */
0 /* no key */
Sep 8, 2005
Sep 8, 2005
472
473
};
May 28, 2006
May 28, 2006
474
475
476
static void
iPod_keyboard ()
Sep 8, 2005
Sep 8, 2005
477
478
479
480
481
482
483
484
{
unsigned char keybuf[128];
int i, nread;
SDL_keysym keysym;
SDL_Event ev;
keysym.mod = 0;
keysym.scancode = 0xff;
May 28, 2006
May 28, 2006
485
memset (&ev, 0, sizeof (SDL_Event));
Sep 8, 2005
Sep 8, 2005
486
487
488
nread = read (kbfd, keybuf, 128);
for (i = 0; i < nread; i++) {
May 28, 2006
May 28, 2006
489
char ascii = iPod_SC_keymap[keybuf[i] & 0x7f];
Sep 8, 2005
Sep 8, 2005
490
May 28, 2006
May 28, 2006
491
492
493
if (dbgout)
fprintf (dbgout, "Key! %02x is %c %s", keybuf[i], ascii,
(keybuf[i] & 0x80) ? "up" : "down");
Sep 8, 2005
Sep 8, 2005
494
May 28, 2006
May 28, 2006
495
496
497
498
499
keysym.sym = keysym.unicode = ascii;
ev.type = (keybuf[i] & 0x80) ? SDL_KEYUP : SDL_KEYDOWN;
ev.key.state = 0;
ev.key.keysym = keysym;
SDL_PushEvent (&ev);
Sep 8, 2005
Sep 8, 2005
500
501
502
}
}
May 28, 2006
May 28, 2006
503
504
static void
iPod_PumpEvents (_THIS)
Sep 8, 2005
Sep 8, 2005
505
506
507
508
509
510
511
{
fd_set fdset;
int max_fd = 0;
static struct timeval zero;
int posted;
do {
May 28, 2006
May 28, 2006
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
posted = 0;
FD_ZERO (&fdset);
if (kbfd >= 0) {
FD_SET (kbfd, &fdset);
max_fd = kbfd;
}
if (dbgout)
fprintf (dbgout, "Selecting");
if (select (max_fd + 1, &fdset, 0, 0, &zero) > 0) {
if (dbgout)
fprintf (dbgout, " -> match!\n");
iPod_keyboard ();
posted++;
}
if (dbgout)
fprintf (dbgout, "\n");
}
while (posted);
Sep 8, 2005
Sep 8, 2005
531
532
533
}
// enough space for 160x128x2
May 28, 2006
May 28, 2006
534
static char ipod_scr[160 * (128 / 4)];
Sep 8, 2005
Sep 8, 2005
535
536
537
538
539
540
541
542
#define outl(datum,addr) (*(volatile unsigned long *)(addr) = (datum))
#define inl(addr) (*(volatile unsigned long *)(addr))
/*** The following LCD code is taken from Linux kernel uclinux-2.4.24-uc0-ipod2,
file arch/armnommu/mach-ipod/fb.c. A few modifications have been made. ***/
/* get current usec counter */
May 28, 2006
May 28, 2006
543
544
static int
M_timer_get_current (void)
Sep 8, 2005
Sep 8, 2005
545
{
May 28, 2006
May 28, 2006
546
return inl (lcd_rtc);
Sep 8, 2005
Sep 8, 2005
547
548
549
}
/* check if number of useconds has past */
May 28, 2006
May 28, 2006
550
551
static int
M_timer_check (int clock_start, int usecs)
Sep 8, 2005
Sep 8, 2005
552
{
May 28, 2006
May 28, 2006
553
554
555
556
557
558
559
560
unsigned long clock;
clock = inl (lcd_rtc);
if ((clock - clock_start) >= usecs) {
return 1;
} else {
return 0;
}
Sep 8, 2005
Sep 8, 2005
561
562
563
}
/* wait for LCD with timeout */
May 28, 2006
May 28, 2006
564
565
static void
M_lcd_wait_write (void)
Sep 8, 2005
Sep 8, 2005
566
{
May 28, 2006
May 28, 2006
567
568
569
570
571
572
573
574
575
if ((inl (lcd_base) & 0x8000) != 0) {
int start = M_timer_get_current ();
do {
if ((inl (lcd_base) & (unsigned int) 0x8000) == 0)
break;
}
while (M_timer_check (start, 1000) == 0);
}
Sep 8, 2005
Sep 8, 2005
576
577
578
579
}
/* send LCD data */
May 28, 2006
May 28, 2006
580
581
static void
M_lcd_send_data (int data_lo, int data_hi)
Sep 8, 2005
Sep 8, 2005
582
{
May 28, 2006
May 28, 2006
583
584
585
586
587
588
589
M_lcd_wait_write ();
outl (data_lo, lcd_base + LCD_DATA);
M_lcd_wait_write ();
outl (data_hi, lcd_base + LCD_DATA);
Sep 8, 2005
Sep 8, 2005
590
591
592
593
594
}
/* send LCD command */
static void
May 28, 2006
May 28, 2006
595
M_lcd_prepare_cmd (int cmd)
Sep 8, 2005
Sep 8, 2005
596
{
May 28, 2006
May 28, 2006
597
M_lcd_wait_write ();
Sep 8, 2005
Sep 8, 2005
598
May 28, 2006
May 28, 2006
599
600
601
602
603
outl (0x0, lcd_base + LCD_CMD);
M_lcd_wait_write ();
outl (cmd, lcd_base + LCD_CMD);
Sep 8, 2005
Sep 8, 2005
604
605
606
607
}
/* send LCD command and data */
May 28, 2006
May 28, 2006
608
609
static void
M_lcd_cmd_and_data (int cmd, int data_lo, int data_hi)
Sep 8, 2005
Sep 8, 2005
610
{
May 28, 2006
May 28, 2006
611
M_lcd_prepare_cmd (cmd);
Sep 8, 2005
Sep 8, 2005
612
May 28, 2006
May 28, 2006
613
M_lcd_send_data (data_lo, data_hi);
Sep 8, 2005
Sep 8, 2005
614
615
616
}
// Copied from uW
May 28, 2006
May 28, 2006
617
618
static void
M_update_display (int sx, int sy, int mx, int my)
Sep 8, 2005
Sep 8, 2005
619
{
May 28, 2006
May 28, 2006
620
621
int y;
unsigned short cursor_pos;
Sep 8, 2005
Sep 8, 2005
622
May 28, 2006
May 28, 2006
623
624
sx >>= 3;
mx >>= 3;
Sep 8, 2005
Sep 8, 2005
625
May 28, 2006
May 28, 2006
626
cursor_pos = sx + (sy << 5);
Sep 8, 2005
Sep 8, 2005
627
May 28, 2006
May 28, 2006
628
629
630
for (y = sy; y <= my; y++) {
unsigned char *img_data;
int x;
Sep 8, 2005
Sep 8, 2005
631
May 28, 2006
May 28, 2006
632
633
/* move the cursor */
M_lcd_cmd_and_data (0x11, cursor_pos >> 8, cursor_pos & 0xff);
Sep 8, 2005
Sep 8, 2005
634
May 28, 2006
May 28, 2006
635
636
/* setup for printing */
M_lcd_prepare_cmd (0x12);
Sep 8, 2005
Sep 8, 2005
637
May 28, 2006
May 28, 2006
638
img_data = ipod_scr + (sx << 1) + (y * (lcd_width / 4));
Sep 8, 2005
Sep 8, 2005
639
May 28, 2006
May 28, 2006
640
641
642
643
/* loops up to 160 times */
for (x = sx; x <= mx; x++) {
/* display eight pixels */
M_lcd_send_data (*(img_data + 1), *img_data);
Sep 8, 2005
Sep 8, 2005
644
May 28, 2006
May 28, 2006
645
646
img_data += 2;
}
Sep 8, 2005
Sep 8, 2005
647
May 28, 2006
May 28, 2006
648
649
650
/* update cursor pos counter */
cursor_pos += 0x20;
}
Sep 8, 2005
Sep 8, 2005
651
652
653
}
/* get current usec counter */
May 28, 2006
May 28, 2006
654
655
static int
C_timer_get_current (void)
Sep 8, 2005
Sep 8, 2005
656
{
May 28, 2006
May 28, 2006
657
return inl (0x60005010);
Sep 8, 2005
Sep 8, 2005
658
659
660
}
/* check if number of useconds has past */
May 28, 2006
May 28, 2006
661
662
static int
C_timer_check (int clock_start, int usecs)
Sep 8, 2005
Sep 8, 2005
663
{
May 28, 2006
May 28, 2006
664
665
666
667
668
669
670
671
unsigned long clock;
clock = inl (0x60005010);
if ((clock - clock_start) >= usecs) {
return 1;
} else {
return 0;
}
Sep 8, 2005
Sep 8, 2005
672
673
674
}
/* wait for LCD with timeout */
May 28, 2006
May 28, 2006
675
676
static void
C_lcd_wait_write (void)
Sep 8, 2005
Sep 8, 2005
677
{
May 28, 2006
May 28, 2006
678
679
680
681
682
683
684
685
686
if ((inl (0x70008A0C) & 0x80000000) != 0) {
int start = C_timer_get_current ();
do {
if ((inl (0x70008A0C) & 0x80000000) == 0)
break;
}
while (C_timer_check (start, 1000) == 0);
}
Sep 8, 2005
Sep 8, 2005
687
}
May 28, 2006
May 28, 2006
688
689
static void
C_lcd_cmd_data (int cmd, int data)
Sep 8, 2005
Sep 8, 2005
690
{
May 28, 2006
May 28, 2006
691
692
C_lcd_wait_write ();
outl (cmd | 0x80000000, 0x70008A0C);
Sep 8, 2005
Sep 8, 2005
693
May 28, 2006
May 28, 2006
694
695
C_lcd_wait_write ();
outl (data | 0x80000000, 0x70008A0C);
Sep 8, 2005
Sep 8, 2005
696
697
}
May 28, 2006
May 28, 2006
698
699
static void
C_update_display (int sx, int sy, int mx, int my)
Sep 8, 2005
Sep 8, 2005
700
{
May 28, 2006
May 28, 2006
701
702
int height = (my - sy) + 1;
int width = (mx - sx) + 1;
Sep 8, 2005
Sep 8, 2005
703
May 28, 2006
May 28, 2006
704
char *addr = SDL_VideoSurface->pixels;
Sep 8, 2005
Sep 8, 2005
705
May 28, 2006
May 28, 2006
706
707
if (width & 1)
width++;
Sep 8, 2005
Sep 8, 2005
708
May 28, 2006
May 28, 2006
709
710
711
/* start X and Y */
C_lcd_cmd_data (0x12, (sy & 0xff));
C_lcd_cmd_data (0x13, (((SDL_VideoSurface->w - 1) - sx) & 0xff));
Sep 8, 2005
Sep 8, 2005
712
May 28, 2006
May 28, 2006
713
714
715
716
717
/* max X and Y */
C_lcd_cmd_data (0x15, (((sy + height) - 1) & 0xff));
C_lcd_cmd_data (0x16,
(((((SDL_VideoSurface->w - 1) - sx) - width) +
1) & 0xff));
Sep 8, 2005
Sep 8, 2005
718
May 28, 2006
May 28, 2006
719
addr += sx + sy * SDL_VideoSurface->pitch;
Sep 8, 2005
Sep 8, 2005
720
May 28, 2006
May 28, 2006
721
722
while (height > 0) {
int h, x, y, pixels_to_write;
Sep 8, 2005
Sep 8, 2005
723
May 28, 2006
May 28, 2006
724
pixels_to_write = (width * height) * 2;
Sep 8, 2005
Sep 8, 2005
725
May 28, 2006
May 28, 2006
726
727
728
729
730
731
/* calculate how much we can do in one go */
h = height;
if (pixels_to_write > 64000) {
h = (64000 / 2) / width;
pixels_to_write = (width * h) * 2;
}
Sep 8, 2005
Sep 8, 2005
732
May 28, 2006
May 28, 2006
733
734
735
outl (0x10000080, 0x70008A20);
outl ((pixels_to_write - 1) | 0xC0010000, 0x70008A24);
outl (0x34000000, 0x70008A20);
Sep 8, 2005
Sep 8, 2005
736
May 28, 2006
May 28, 2006
737
738
739
740
741
/* for each row */
for (x = 0; x < h; x++) {
/* for each column */
for (y = 0; y < width; y += 2) {
unsigned two_pixels;
Sep 8, 2005
Sep 8, 2005
742
May 28, 2006
May 28, 2006
743
744
two_pixels = addr[0] | (addr[1] << 16);
addr += 2;
Sep 8, 2005
Sep 8, 2005
745
May 28, 2006
May 28, 2006
746
while ((inl (0x70008A20) & 0x1000000) == 0);
Sep 8, 2005
Sep 8, 2005
747
May 28, 2006
May 28, 2006
748
749
750
/* output 2 pixels */
outl (two_pixels, 0x70008B00);
}
Sep 8, 2005
Sep 8, 2005
751
May 28, 2006
May 28, 2006
752
753
addr += SDL_VideoSurface->w - width;
}
Sep 8, 2005
Sep 8, 2005
754
May 28, 2006
May 28, 2006
755
while ((inl (0x70008A20) & 0x4000000) == 0);
Sep 8, 2005
Sep 8, 2005
756
May 28, 2006
May 28, 2006
757
outl (0x0, 0x70008A24);
Sep 8, 2005
Sep 8, 2005
758
May 28, 2006
May 28, 2006
759
760
height = height - h;
}
Sep 8, 2005
Sep 8, 2005
761
762
763
}
// Should work with photo. However, I don't have one, so I'm not sure.
May 28, 2006
May 28, 2006
764
765
static void
iPod_UpdateRects (_THIS, int nrects, SDL_Rect * rects)
Sep 8, 2005
Sep 8, 2005
766
767
{
if (SDL_VideoSurface->format->BitsPerPixel == 16) {
May 28, 2006
May 28, 2006
768
C_update_display (0, 0, lcd_width, lcd_height);
Sep 8, 2005
Sep 8, 2005
769
} else {
May 28, 2006
May 28, 2006
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
int i, y, x;
for (i = 0; i < nrects; i++) {
SDL_Rect *r = rects + i;
if (!r) {
continue;
}
for (y = r->y; (y < r->y + r->h) && y < lcd_height; y++) {
for (x = r->x; (x < r->x + r->w) && x < lcd_width; x++) {
ipod_scr[y * (lcd_width / 4) + x / 4] &=
~(3 << (2 * (x % 4)));
ipod_scr[y * (lcd_width / 4) + x / 4] |=
(((Uint8 *) (SDL_VideoSurface->pixels))[y *
SDL_VideoSurface->
pitch
+
x] &
3) << (2 * (x % 4));
}
}
}
M_update_display (0, 0, lcd_width, lcd_height);
Sep 8, 2005
Sep 8, 2005
793
794
}
}
May 28, 2006
May 28, 2006
795
796
/* vi: set ts=4 sw=4 expandtab: */