r_next.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. #import <AppKit/AppKit.h>
  2. #include "../ref_soft/r_local.h"
  3. /*
  4. ====================================================================
  5. OPENSTEP specific stuff
  6. ====================================================================
  7. */
  8. @interface QuakeView : NSView
  9. @end
  10. NSWindow *vid_window_i;
  11. QuakeView *vid_view_i;
  12. unsigned *buffernative;
  13. //===========================================================
  14. int Draw_SetResolution (void);
  15. #define TYPE_FULLSCREEN 0
  16. #define TYPE_WINDOWED 1
  17. #define TYPE_STRETCHED 2
  18. #define NUM_RESOLUTIONS 7
  19. int resolutions[NUM_RESOLUTIONS][2] = {
  20. {320,200}, {320,240}, {400,300}, {512,384}, {640,480}, {800,600}, {1024,768} };
  21. qboolean available[NUM_RESOLUTIONS][3];
  22. int mode_res = 0, mode_type = TYPE_WINDOWED;
  23. byte gammatable[256]; // palette is sent through this
  24. unsigned current_palette[256];
  25. unsigned gamma_palette[256];
  26. int cursor_res, cursor_type;
  27. cvar_t *vid_x;
  28. cvar_t *vid_y;
  29. cvar_t *vid_mode;
  30. cvar_t *vid_stretched;
  31. cvar_t *vid_fullscreen;
  32. cvar_t *draw_gamma;
  33. void Draw_BuildGammaTable (void);
  34. /*
  35. ====================================================================
  36. MENU INTERACTION
  37. ====================================================================
  38. */
  39. void FindModes (void)
  40. {
  41. if (mode_res < 0 || mode_res >= NUM_RESOLUTIONS)
  42. mode_res = 0;
  43. if (mode_type < 0 || mode_type > 3)
  44. mode_type = 1;
  45. }
  46. void RM_Print (int x, int y, char *s)
  47. {
  48. while (*s)
  49. {
  50. Draw_Char (x, y, (*s)+128);
  51. s++;
  52. x += 8;
  53. }
  54. }
  55. /*
  56. ================
  57. Draw_MenuDraw
  58. ================
  59. */
  60. void Draw_MenuDraw (void)
  61. {
  62. int i, j;
  63. int y;
  64. char string[32];
  65. Draw_Pic ( 4, 4, "vidmodes");
  66. RM_Print (80, 32, "fullscreen windowed stretched");
  67. RM_Print (80, 40, "---------- -------- ---------");
  68. y = 50;
  69. // draw background behind selected mode
  70. Draw_Fill ( (mode_type+1)*80, y+(mode_res)*10, 40,10, 8);
  71. // draw available grid
  72. for (i=0 ; i<NUM_RESOLUTIONS ; i++, y+= 10)
  73. {
  74. sprintf (string, "%ix%i", resolutions[i][0], resolutions[i][1]);
  75. RM_Print (0, y, string);
  76. for (j=0 ; j<3 ; j++)
  77. if (available[i][j])
  78. RM_Print ( 80 + j*80, y, "*");
  79. }
  80. // draw the cursor
  81. Draw_Char (80 + cursor_type*80, 50 + cursor_res*10, 128 + 12+((int)(r_newrefdef.time*4)&1));
  82. }
  83. #define K_TAB 9
  84. #define K_ENTER 13
  85. #define K_ESCAPE 27
  86. #define K_SPACE 32
  87. // normal keys should be passed as lowercased ascii
  88. #define K_BACKSPACE 127
  89. #define K_UPARROW 128
  90. #define K_DOWNARROW 129
  91. #define K_LEFTARROW 130
  92. #define K_RIGHTARROW 131
  93. /*
  94. ================
  95. Draw_MenuKey
  96. ================
  97. */
  98. void Draw_MenuKey (int key)
  99. {
  100. switch (key)
  101. {
  102. case K_LEFTARROW:
  103. cursor_type--;
  104. if (cursor_type < 0)
  105. cursor_type = 2;
  106. break;
  107. case K_RIGHTARROW:
  108. cursor_type++;
  109. if (cursor_type > 2)
  110. cursor_type = 0;
  111. break;
  112. case K_UPARROW:
  113. cursor_res--;
  114. if (cursor_res < 0)
  115. cursor_res = NUM_RESOLUTIONS-1;
  116. break;
  117. case K_DOWNARROW:
  118. cursor_res++;
  119. if (cursor_res >= NUM_RESOLUTIONS)
  120. cursor_res = 0;
  121. break;
  122. case K_ENTER:
  123. ri.Cmd_ExecuteText (EXEC_NOW, va("vid_mode %i", cursor_res));
  124. switch (cursor_type)
  125. {
  126. case TYPE_FULLSCREEN:
  127. ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 1");
  128. ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 0");
  129. break;
  130. case TYPE_WINDOWED:
  131. ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 0");
  132. ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 0");
  133. break;
  134. case TYPE_STRETCHED:
  135. ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 0");
  136. ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 1");
  137. break;
  138. }
  139. mode_res = cursor_res;
  140. mode_type = cursor_type;
  141. Draw_SetResolution ();
  142. break;
  143. default:
  144. break;
  145. }
  146. }
  147. //===========================================================
  148. /*
  149. ================
  150. Draw_SetResolution
  151. The vid structure will be filled in on return
  152. Also allocates the z buffer and surface cache
  153. ================
  154. */
  155. int Draw_SetResolution (void)
  156. {
  157. NSRect content;
  158. if (vid_mode->value < 0)
  159. ri.Cmd_ExecuteText (EXEC_NOW, "vid_mode 0");
  160. if (vid_mode->value >= NUM_RESOLUTIONS)
  161. ri.Cmd_ExecuteText (EXEC_NOW, va("vid_mode %i", NUM_RESOLUTIONS-1));
  162. vid_mode->modified = false;
  163. vid_fullscreen->modified = false;
  164. vid_stretched->modified = false;
  165. // free nativebuffer
  166. if (buffernative)
  167. {
  168. free (buffernative);
  169. buffernative = NULL;
  170. }
  171. // free z buffer
  172. if (d_pzbuffer)
  173. {
  174. free (d_pzbuffer);
  175. d_pzbuffer = NULL;
  176. }
  177. // free surface cache
  178. if (sc_base)
  179. {
  180. D_FlushCaches ();
  181. free (sc_base);
  182. sc_base = NULL;
  183. }
  184. vid.width = resolutions[(int)(vid_mode->value)][0];
  185. vid.height = resolutions[(int)(vid_mode->value)][1];
  186. vid.win_width = vid.width;
  187. vid.win_height = vid.height;
  188. if (vid_stretched->value)
  189. {
  190. vid.win_width <<= 1;
  191. vid.win_height <<= 1;
  192. }
  193. vid.aspect = 1;
  194. vid.buffer = malloc (vid.width*vid.height);
  195. vid.rowbytes = vid.width;
  196. d_pzbuffer = malloc(vid.width*vid.height*2);
  197. buffernative = malloc(vid.width*vid.height*4);
  198. D_InitCaches ();
  199. Sys_SetPalette ((byte *)d_8to24table);
  200. if (vid_view_i)
  201. [vid_view_i unlockFocus];
  202. if (vid_window_i)
  203. [vid_window_i close];
  204. //
  205. // open a window
  206. //
  207. content = NSMakeRect (vid_x->value,vid_y->value,vid.win_width, vid.win_height);
  208. vid_window_i = [[NSWindow alloc]
  209. initWithContentRect: content
  210. styleMask: NSTitledWindowMask
  211. backing: NSBackingStoreRetained
  212. defer: NO
  213. ];
  214. [vid_window_i setDelegate: vid_window_i];
  215. [vid_window_i display];
  216. [NSApp activateIgnoringOtherApps: YES];
  217. [vid_window_i makeKeyAndOrderFront: nil];
  218. // NSPing ();
  219. content.origin.x = content.origin.y = 0;
  220. vid_view_i = [[QuakeView alloc] initWithFrame: content];
  221. [vid_window_i setContentView: vid_view_i];
  222. [vid_window_i makeFirstResponder: vid_view_i];
  223. [vid_window_i setDelegate: vid_view_i];
  224. // [vid_window_i addToEventMask: NS_FLAGSCHANGEDMASK];
  225. [vid_window_i setTitle: @"Bitmap Quake Console"];
  226. [vid_window_i makeKeyAndOrderFront: nil];
  227. // leave focus locked forever
  228. [vid_view_i lockFocus];
  229. ri.VID_SetSize (vid.width, vid.height);
  230. return 0;
  231. }
  232. /*
  233. @@@@@@@@@@@@@@@@@@@@@
  234. Draw_Init
  235. @@@@@@@@@@@@@@@@@@@@@
  236. */
  237. int Draw_Init (void *window)
  238. {
  239. [NSApplication sharedApplication];
  240. [NSApp finishLaunching];
  241. ri.Con_Printf (PRINT_ALL, "refresh version: "REF_VERSION"\n");
  242. vid_x = ri.Cvar_Get ("vid_x", "0", CVAR_ARCHIVE);
  243. vid_y = ri.Cvar_Get ("vid_y", "0", CVAR_ARCHIVE);
  244. vid_mode = ri.Cvar_Get ("vid_mode", "0", CVAR_ARCHIVE);
  245. vid_fullscreen = ri.Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
  246. vid_stretched = ri.Cvar_Get ("vid_stretched", "0", CVAR_ARCHIVE);
  247. draw_gamma = ri.Cvar_Get ("gamma", "1", CVAR_ARCHIVE);
  248. Draw_GetPalette ();
  249. Draw_BuildGammaTable ();
  250. // get the lighting colormap
  251. ri.FS_LoadFile ("gfx/colormap.lmp", (void **)&vid.colormap);
  252. if (!vid.colormap)
  253. {
  254. ri.Con_Printf (PRINT_ALL, "ERROR: Couldn't load gfx/colormap.lmp");
  255. return -1;
  256. }
  257. Draw_SetResolution ();
  258. R_Init ();
  259. return 0;
  260. }
  261. /*
  262. @@@@@@@@@@@@@@@@@@@@@
  263. Draw_Shutdown
  264. @@@@@@@@@@@@@@@@@@@@@
  265. */
  266. void Draw_Shutdown (void)
  267. {
  268. R_Shutdown ();
  269. }
  270. /*
  271. @@@@@@@@@@@@@@@@@@@@@
  272. Draw_BuildGammaTable
  273. @@@@@@@@@@@@@@@@@@@@@
  274. */
  275. void Draw_BuildGammaTable (void)
  276. {
  277. int i, inf;
  278. float g;
  279. draw_gamma->modified = false;
  280. g = draw_gamma->value;
  281. if (g == 1.0)
  282. {
  283. for (i=0 ; i<256 ; i++)
  284. gammatable[i] = i;
  285. return;
  286. }
  287. for (i=0 ; i<256 ; i++)
  288. {
  289. inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
  290. if (inf < 0)
  291. inf = 0;
  292. if (inf > 255)
  293. inf = 255;
  294. gammatable[i] = inf;
  295. }
  296. }
  297. /*
  298. @@@@@@@@@@@@@@@@@@@@@
  299. Draw_BeginFram
  300. @@@@@@@@@@@@@@@@@@@@@
  301. */
  302. void Draw_BeginFrame (void)
  303. {
  304. if (vid_mode->modified || vid_fullscreen->modified
  305. || vid_stretched->modified)
  306. Draw_SetResolution ();
  307. if (draw_gamma->modified)
  308. {
  309. Draw_BuildGammaTable ();
  310. Sys_SetPalette ((byte *)current_palette);
  311. }
  312. // MGL_beginDirectAccess();
  313. // vid.buffer = mgldc->surface;
  314. // vid.rowbytes = mgldc->mi.bytesPerLine;
  315. }
  316. /*
  317. @@@@@@@@@@@@@@@@@@@@@
  318. Draw_EndFrame
  319. @@@@@@@@@@@@@@@@@@@@@
  320. */
  321. void Draw_EndFrame (void)
  322. {
  323. int i, c;
  324. int bps, spp, bpp, bpr;
  325. unsigned char *planes[5];
  326. NSRect bounds;
  327. // translate to 24 bit color
  328. c = vid.width*vid.height;
  329. for (i=0 ; i<c ; i++)
  330. buffernative[i] = gamma_palette[vid.buffer[i]];
  331. bps = 8;
  332. spp = 3;
  333. bpp = 32;
  334. bpr = vid.width * 4;
  335. planes[0] = (unsigned char *)buffernative;
  336. bounds = [vid_view_i bounds];
  337. NSDrawBitmap(
  338. bounds,
  339. vid.width,
  340. vid.height,
  341. bps,
  342. spp,
  343. bpp,
  344. bpr,
  345. NO,
  346. NO,
  347. @"NSDeviceRGBColorSpace",
  348. planes
  349. );
  350. }
  351. //===============================================================================
  352. #define HUNK_MAGIC 0xffaffaff
  353. typedef struct
  354. {
  355. int magic;
  356. int length;
  357. int pad[6];
  358. } hunkheader_t;
  359. hunkheader_t *membase;
  360. int maxsize;
  361. int cursize;
  362. void *Hunk_Begin (void)
  363. {
  364. kern_return_t r;
  365. // reserve a huge chunk of memory, but don't commit any yet
  366. maxsize = 16*1024*1024;
  367. cursize = 0;
  368. membase = NULL;
  369. r = vm_allocate(task_self(), (vm_address_t *)&membase, maxsize, 1);
  370. if (!membase || r != KERN_SUCCESS)
  371. ri.Sys_Error (ERR_FATAL,"vm_allocate failed");
  372. membase->magic = HUNK_MAGIC;
  373. membase->length = maxsize;
  374. cursize = 32;
  375. return (void *)((byte *)membase + cursize);
  376. }
  377. void *Hunk_Alloc (int size)
  378. {
  379. // round to cacheline
  380. size = (size+31)&~31;
  381. cursize += size;
  382. if (cursize > maxsize)
  383. ri.Sys_Error (ERR_DROP, "Hunk_Alloc overflow");
  384. memset ((byte *)membase+cursize-size,0,size);
  385. return (void *)((byte *)membase+cursize-size);
  386. }
  387. int Hunk_End (void)
  388. {
  389. kern_return_t r;
  390. // round to pagesize
  391. cursize = (cursize+vm_page_size)&~(vm_page_size-1);
  392. membase->length = cursize;
  393. r = vm_deallocate(task_self(),
  394. (vm_address_t)((byte *)membase + cursize),
  395. maxsize - cursize);
  396. if ( r != KERN_SUCCESS )
  397. ri.Sys_Error (ERR_DROP, "vm_deallocate failed");
  398. return cursize;
  399. }
  400. void Hunk_Free (void *base)
  401. {
  402. hunkheader_t *h;
  403. kern_return_t r;
  404. h = ((hunkheader_t *)base) - 1;
  405. if (h->magic != HUNK_MAGIC)
  406. ri.Sys_Error (ERR_FATAL, "Hunk_Free: bad magic");
  407. r = vm_deallocate(task_self(), (vm_address_t)h, h->length);
  408. if ( r != KERN_SUCCESS )
  409. ri.Sys_Error (ERR_DROP, "vm_deallocate failed");
  410. }
  411. /*
  412. ================
  413. Sys_MakeCodeWriteable
  414. ================
  415. */
  416. void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
  417. {
  418. }
  419. /*
  420. ================
  421. Sys_SetPalette
  422. ================
  423. */
  424. void Sys_SetPalette (byte *palette)
  425. {
  426. byte *p;
  427. int i;
  428. memcpy (current_palette, palette, sizeof(current_palette));
  429. p = (byte *)gamma_palette;
  430. // gamma correct and byte swap
  431. for (i=0 ; i<256 ; i++, p+=4, palette+=4)
  432. {
  433. p[0] = gammatable[palette[0]];
  434. p[1] = gammatable[palette[1]];
  435. p[2] = gammatable[palette[2]];
  436. p[3] = 0xff;
  437. }
  438. }
  439. /*
  440. ==========================================================================
  441. NEXTSTEP VIEW CLASS
  442. ==========================================================================
  443. */
  444. #include "../client/keys.h"
  445. void IN_ActivateMouse (void);
  446. void IN_DeactivateMouse (void);
  447. @implementation QuakeView
  448. -(BOOL) acceptsFirstResponder
  449. {
  450. return YES;
  451. }
  452. - (void)windowDidMove: (NSNotification *)note
  453. {
  454. NSRect r;
  455. r = [vid_window_i frame];
  456. ri.Cmd_ExecuteText (EXEC_NOW, va("vid_x %i", (int)r.origin.x+1));
  457. ri.Cmd_ExecuteText (EXEC_NOW, va("vid_y %i", (int)r.origin.y+1));
  458. }
  459. - (void)becomeKeyWindow
  460. {
  461. IN_ActivateMouse ();
  462. }
  463. - (void)resignKeyWindow
  464. {
  465. IN_DeactivateMouse ();
  466. }
  467. typedef struct
  468. {
  469. int source, dest;
  470. } keymap_t;
  471. keymap_t keymaps[] =
  472. {
  473. {103, K_RIGHTARROW},
  474. {102, K_LEFTARROW},
  475. {100, K_UPARROW},
  476. {101, K_DOWNARROW},
  477. {59, K_F1},
  478. {60, K_F2},
  479. {61, K_F3},
  480. {62, K_F4},
  481. {63, K_F5},
  482. {64, K_F6},
  483. {65, K_F7},
  484. {66, K_F8},
  485. {67, K_F9},
  486. {68, K_F10},
  487. {87, K_F11},
  488. {88, K_F12},
  489. {-1,-1}
  490. };
  491. keymap_t flagmaps[] =
  492. {
  493. {NSShiftKeyMask, K_SHIFT},
  494. {NSControlKeyMask, K_CTRL},
  495. {NSAlternateKeyMask, K_ALT},
  496. {NSCommandKeyMask, K_ALT},
  497. {-1,-1}
  498. };
  499. - (void)mouseDown:(NSEvent *)theEvent
  500. {
  501. Key_Event (K_MOUSE1, true);
  502. }
  503. - (void)mouseUp:(NSEvent *)theEvent
  504. {
  505. Key_Event (K_MOUSE1, false);
  506. }
  507. - (void)rightMouseDown:(NSEvent *)theEvent
  508. {
  509. Key_Event (K_MOUSE2, true);
  510. }
  511. - (void)rightMouseUp:(NSEvent *)theEvent
  512. {
  513. Key_Event (K_MOUSE2, false);
  514. }
  515. /*
  516. ===================
  517. keyboard methods
  518. ===================
  519. */
  520. - (void)keyDown:(NSEvent *)theEvent
  521. {
  522. int ch;
  523. keymap_t *km;
  524. // PSobscurecursor ();
  525. // check for non-ascii first
  526. ch = [theEvent keyCode];
  527. for (km=keymaps;km->source!=-1;km++)
  528. if (ch == km->source)
  529. {
  530. Key_Event (km->dest, true);
  531. return;
  532. }
  533. ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
  534. if (ch >= 'A' && ch <= 'Z')
  535. ch += 'a' - 'A';
  536. if (ch>=256)
  537. return;
  538. Key_Event (ch, true);
  539. }
  540. - (void)flagsChanged:(NSEvent *)theEvent
  541. {
  542. static int oldflags;
  543. int newflags;
  544. int delta;
  545. keymap_t *km;
  546. int i;
  547. // PSobscurecursor ();
  548. newflags = [theEvent modifierFlags];
  549. delta = newflags ^ oldflags;
  550. for (i=0 ; i<32 ; i++)
  551. {
  552. if ( !(delta & (1<<i)))
  553. continue;
  554. // changed
  555. for (km=flagmaps;km->source!=-1;km++)
  556. if ( (1<<i) == km->source)
  557. {
  558. if (newflags & (1<<i))
  559. Key_Event (km->dest, true);
  560. else
  561. Key_Event (km->dest, false);
  562. }
  563. }
  564. oldflags = newflags;
  565. }
  566. - (void)keyUp:(NSEvent *)theEvent
  567. {
  568. int ch;
  569. keymap_t *km;
  570. // check for non-ascii first
  571. ch = [theEvent keyCode];
  572. for (km=keymaps;km->source!=-1;km++)
  573. if (ch == km->source)
  574. {
  575. Key_Event (km->dest, false);
  576. return;
  577. }
  578. ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
  579. if (ch >= 'A' && ch <= 'Z')
  580. ch += 'a' - 'A';
  581. if (ch>=256)
  582. return;
  583. Key_Event (ch, false);
  584. }
  585. @end