📄 i_video_ggi.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: i_video_ggi.c,v 1.6 2001/04/27 13:32:14 bpereira Exp $//// Copyright (C) 1998-2000 by DooM Legacy Team.//// 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.////// $Log: i_video_ggi.c,v $// Revision 1.6 2001/04/27 13:32:14 bpereira// no message//// Revision 1.5 2001/01/25 22:15:45 bpereira// added heretic support//// Revision 1.4 2000/11/02 19:49:40 bpereira// no message//// Revision 1.3 2000/03/06 15:19:58 hurdler// Add Bell Kin's changes//// Revision 1.2 2000/02/27 00:42:12 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:33 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// Inspired from l_video.ggi.c by Colin Phipps (cph@lxdoom.linuxgames.com)// GGI target code////-----------------------------------------------------------------------------// checked mouse 19990314 by Kin#define CHECKEDMOUSE#include <stdio.h>#include <unistd.h>#include <ctype.h>#include <ggi/ggi.h>// it must be here 19990117 by Kin#include "doomdef.h"// added 19990125 by Kin#include "../vid_copy.h"#include "doomstat.h"#include "i_system.h"#include "v_video.h"#include "m_argv.h"#include "m_menu.h"#include "d_main.h"#include "s_sound.h"// added for 1.27 19990220 by Kin#include "g_input.h"#include "st_stuff.h"#include "g_game.h"#include "i_video.h"boolean showkey=0; // force to no 19990118 by Kinint vid_modenum = 0; // index for vid mode list 19990119 by Kin// added for 1.27 19990220 by Kinrendermode_t rendermode=render_soft;byte graphics_started = 0;boolean highcolor = false;boolean expand_buffer = false;static ggi_visual_t screen;static const ggi_pixelformat* pixelformat;static int multiply = 1;//static byte* out_buffer;static int ggi_screenwidth, ggi_screenheight;// Mask of events that we are interested instatic const ggi_event_mask ev_mask = \emKeyPress | emKeyRelease | emPtrRelative | emPtrButtonPress | \emPtrButtonRelease;// Unused vars to preserve in config fileint leds_always_off;int use_vsync;////////////////////////////////////////////////////////////////// Input handling utility functions// Null keyboard translation to satisfy m_misc.cint I_DoomCode2ScanCode(int c){ return c;}int I_ScanCode2DoomCode(int c){ return c;}//// I_GIITranslateKey//// Translate keys from LibGII// Adapted from Linux Heretic v0.9.2int I_GIITranslateKey(const ggi_key_event* key){ int label = key->label, sym = key->sym; int rc=0; switch(label) { case GIIK_CtrlL: case GIIK_CtrlR: rc=KEY_CTRL; break; case GIIK_ShiftL: case GIIK_ShiftR: rc=KEY_SHIFT; break; case GIIK_MetaL: case GIIK_MetaR: case GIIK_AltL: case GIIK_AltR: rc=KEY_ALT; break; case GIIUC_BackSpace: rc = KEY_BACKSPACE; break; case GIIUC_Escape: rc = KEY_ESCAPE; break; case GIIK_Delete: rc = KEY_DEL; break; case GIIK_Insert: rc = KEY_INS; break; case GIIK_PageUp: rc = KEY_PGUP; break; case GIIK_PageDown: rc = KEY_PGDN; break; case GIIK_Home: rc = KEY_HOME; break; case GIIK_End: rc = KEY_END; break; case GIIUC_Tab: rc = KEY_TAB; break; case GIIK_Up: rc = KEY_UPARROW; break; case GIIK_Down: rc = KEY_DOWNARROW; break; case GIIK_Left: rc = KEY_LEFTARROW; break; case GIIK_Right: rc = KEY_RIGHTARROW; break; case GIIK_Enter: rc = KEY_ENTER; break; case GIIK_F1: rc = KEY_F1; break; case GIIK_F2: rc = KEY_F2; break; case GIIK_F3: rc = KEY_F3; break; case GIIK_F4: rc = KEY_F4; break; case GIIK_F5: rc = KEY_F5; break; case GIIK_F6: rc = KEY_F6; break; case GIIK_F7: rc = KEY_F7; break; case GIIK_F8: rc = KEY_F8; break; case GIIK_F9: rc = KEY_F9; break; case GIIK_F10: rc = KEY_F10; break; case GIIK_F11: rc = KEY_F11; break; case GIIK_F12: rc = KEY_F12; break; case GIIK_Pause:rc = KEY_PAUSE; break; case GIIK_PSlash:rc = KEY_KPADSLASH; break; case GIIK_P0:rc = KEY_KEYPAD0;break; case GIIK_P1:rc = KEY_KEYPAD1;break; case GIIK_P2:rc = KEY_KEYPAD2;break; case GIIK_P3:rc = KEY_KEYPAD3;break; case GIIK_P4:rc = KEY_KEYPAD4;break; case GIIK_P5:rc = KEY_KEYPAD5;break; case GIIK_P6:rc = KEY_KEYPAD6;break; case GIIK_P7:rc = KEY_KEYPAD7;break; case GIIK_P8:rc = KEY_KEYPAD8;break; case GIIK_P9:rc = KEY_KEYPAD9;break; case GIIK_PPlus:rc = KEY_PLUSPAD;break; case GIIK_PMinus:rc = KEY_MINUSPAD;break; /* Decimal???? why not Dot??? */ case GIIK_PDecimal:rc = KEY_KPADDEL;break; case GIIK_CapsLock:rc = KEY_CAPSLOCK;break; case GIIK_ScrollLock:rc = KEY_SCROLLLOCK;break; case GIIK_NumLock:rc = KEY_NUMLOCK;break; default: if ((label > '0' && label < '9') || label == '.' || label == ',') { /* Must use label here, or it won't work when shift is down */ rc = label; } else if (sym < 256) { /* ASCII key - we want those */ rc = sym; /* We want lowercase */ if (rc >='A' && rc <='Z') rc -= ('A' - 'a'); switch (sym) { /* Some special cases */ case '+': rc = KEY_EQUALS; break; case '-': rc = KEY_MINUS; default: break; } } } return rc;}unsigned short I_GIITranslateButtons(const ggi_pbutton_event* ev){ return ev->button;}////////////////////////////////////////////////////////////////// API//// I_StartFrame//void I_StartFrame (void){ // If we reuse the blitting buffer in the next rendering, // make sure it is reusable now if (!expand_buffer) ggiFlush(screen);}void I_OsPolling(void) { I_GetEvent();}#ifdef CHECKEDMOUSEint btmask = 0;#endif#ifdef LJOYSTICKextern void I_GetJoyEvent();#endif#ifdef LMOUSE2extern void I_GetMouse2Event();#endifvoid I_GetEvent(void){ struct timeval nowait = { 0, 0 };#ifdef LMOUSE2 I_GetMouse2Event();#endif#ifdef LJOYSTICK I_GetJoyEvent();#endif while (ggiEventPoll(screen, ev_mask, &nowait)!=evNothing) { // There is a desirable event ggi_event ggi_ev; event_t doom_ev; int m_x = 0, m_y = 0; // Mouse motion unsigned short buttons; // Buttons int i,j; // GII will return modified button "number" ggiEventRead(screen, &ggi_ev, ev_mask); switch(ggi_ev.any.type) { case evKeyPress: doom_ev.type = ev_keydown; if ((doom_ev.data1= I_GIITranslateKey(&ggi_ev.key)) >0 ) D_PostEvent(&doom_ev); //fprintf(stderr,"p:%4x\n",doom_ev.data1); break; case evKeyRelease: doom_ev.type = ev_keyup; if ((doom_ev.data1= I_GIITranslateKey(&ggi_ev.key)) > 0 ) D_PostEvent(&doom_ev); //fprintf(stderr,"r:%4x\n",doom_ev.data1); break; case evPtrRelative: m_x += ggi_ev.pmove.x; m_y += ggi_ev.pmove.y; break; case evPtrButtonPress: buttons = I_GIITranslateButtons(&ggi_ev.pbutton);#ifdef CHECKEDMOUSE if(btmask&(1<<buttons)) { break; } else btmask |= (1<<buttons);#endif doom_ev.type = ev_keydown; // translate button2 in ggi to MOUSE3 19990225 by Kin doom_ev.data1=KEY_MOUSE1+(buttons^(buttons>>1))-1; D_PostEvent(&doom_ev); break; case evPtrButtonRelease: buttons = I_GIITranslateButtons(&ggi_ev.pbutton);#ifdef CHECKEDMOUSE if(!(btmask&(1<<buttons))) { break; } else btmask ^= (1<<buttons);#endif doom_ev.type = ev_keyup; doom_ev.data1=KEY_MOUSE1+(buttons^(buttons>>1))-1; D_PostEvent(&doom_ev); break; default: //I_Error("I_OsPolling: Bad GGI event type"); } if (m_x||m_y) { doom_ev.type = ev_mouse; // 4x mouse like xdoom 19990227 by Kin doom_ev.data2 = m_x << 2; doom_ev.data3 = -(m_y << 2); D_PostEvent(&doom_ev); } }}//// I_UpdateNoBlit//void I_UpdateNoBlit (void){ // Finish up any output ggiFlush(screen);}//// I_FinishUpdate//void I_FinishUpdate (void){ int i; // draws little dots on the bottom of the screen if (devparm) { static int lasttic; int tics; i = I_GetTime(); tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20; for (i=0 ; i<tics*2 ; i+=2) screens[0][ (vid.height-1)*vid.width + i] = 0xff; for ( ; i<20*2 ; i+=2) screens[0][ (vid.height-1)*vid.width + i] = 0x0; } // scales the screen size before blitting it // disabled for now 19990221 by Kin // if (expand_buffer) // (*I_ExpandImage)(out_buffer, screens[0]); // Blit it ggiPutBox(screen, 0, 0, ggi_screenwidth, ggi_screenheight, vid.buffer);}//// I_ReadScreen//void I_ReadScreen (byte* scr){ memcpy(scr, vid.buffer, vid.width*vid.height*vid.bpp);}void I_SetPalette(RGBA_t* palette){ if (!highcolor) { ggi_color ggi_pal[256]; ggi_color* p; int i; // PseudoColor mode, so set the palette for (i=0, p=ggi_pal; i<256; i++) { // Translate palette entry to 16 bits per component p->r = palette->s.red << 8; p->g = palette->s.green << 8; p->b = palette->s.blue << 8; p++; palette++; } ggiSetPalette(screen, 0, 256, ggi_pal); // } else { // TrueColor mode, so rewrite conversion table // I_SetPaletteTranslation(palette); }}void I_ShutdownGraphics(void){ ggiRemoveFlags(screen, GGIFLAG_ASYNC); if (vid.buffer) free(vid.buffer); ggiExit();}#define MAX_GGIMODES 18const ggi_coord temp_res[MAX_GGIMODES]= { {320,200}, {320,240}, {320,350}, /* EGA text */ {360,400}, /* VGA text */ {400,300}, {480,300}, {512,384}, {640,200}, /* EGA */ {640,350}, /* EGA */ {640,400}, {640,480}, {720,350}, /* MDA text */ {720,400}, /* VGA text */ {800,600}, {1024,768}, {1152,864}, {1280,1024}, {1600,1200}};ggi_coord real_res[MAX_GGIMODES+1];char vidname[MAX_GGIMODES+1][10];ggi_mode vidmodes[MAX_GGIMODES+1];int rescount;// dummy for test 19990221 by Kinint VID_NumModes(void) { return rescount;}char *VID_GetModeName(int modenum) { return vidname[modenum];}int VID_GetModeForSize( int w, int h) { int i; for (i=0; i<rescount;i++) { if(real_res[i].x==w) { if(real_res[i].y==h) { return i; } } } for (i=0; i<rescount;i++) { if(real_res[i].x>=w) { if(real_res[i].y>=h) { break; } } } if(i<rescount) { return i; } return 0;}void I_StartupGraphics(void){ int i; fprintf(stderr, "I_StartupGraphics:"); if (ggiInit()) I_Error("Failed to initialise GGI\n"); if (!(screen = ggiOpen(NULL))) // Open default visual I_Error("Failed to get default visual\n"); { // Check for screen enlargement char str[3] = { '-', 0, 0 }; int n; for (n=1; n<4; n++) { str[1] = n + '0'; if (M_CheckParm(str)) multiply = n; } } highcolor = M_CheckParm("-highcolor"); for(i=0,rescount=0;i<MAX_GGIMODES;i++) { if(!ggiCheckSimpleMode(screen,temp_res[i].x,temp_res[i].y,2, (highcolor?GT_15BIT:GT_8BIT),&vidmodes[rescount])) { memcpy(&real_res[rescount],&temp_res[i],sizeof(ggi_coord)); sprintf(vidname[rescount],"%4dx%4d",temp_res[i].x,temp_res[i].y); fprintf(stderr,"mode %s\n",vidname[rescount]); rescount++; } else { if(GT_DEPTH(vidmodes[rescount].graphtype)==(highcolor?15:8)) { //if((vidmodes[rescount].visible.x>temp_res[i-1].x && // vidmodes[rescount].visible.x<temp_res[i+1].x && // vidmodes[rescount].visible.y>=temp_res[i-1].y) || // (vidmodes[rescount].visible.y>temp_res[i-1].y && // vidmodes[rescount].visible.y<temp_res[i+1].y && // vidmodes[rescount].visible.x>=temp_res[i-1].x)) { if(vidmodes[rescount].visible.x==temp_res[i].x && vidmodes[rescount].visible.y==temp_res[i].y) { real_res[rescount].x = vidmodes[rescount].visible.x; real_res[rescount].y = vidmodes[rescount].visible.y; sprintf(vidname[rescount],"%4dx%4d", real_res[rescount].x,real_res[rescount].y); fprintf(stderr,"suggested mode %s\n",vidname[rescount]); rescount++; } } } } if(!rescount) { I_Error("No video modes available!"); return; } vid.buffer = NULL; VID_SetMode(0); // Go asynchronous ggiAddFlags(screen, GGIFLAG_ASYNC); // Mask events ggiSetEventMask(screen, ev_mask); // added for 1.27 19990220 by Kin graphics_started = 1;}int VID_SetMode(int modenum) { if(vid.buffer) free(vid.buffer); //if(expand_buffer) { // if(out_buffer) free(out_buffer); //} vid.bpp = (highcolor?2:1); ggi_screenwidth = vid.width = real_res[modenum].x; ggi_screenheight = vid.height = real_res[modenum].y; vid.rowbytes = vid.width*vid.bpp; vid.recalc = 1; if (ggiSetMode(screen,&vidmodes[modenum])) { I_Error("Failed to set mode"); return 0; } vid.buffer = vid.direct = (unsigned char *) malloc (vid.width * vid.height * NUMSCREENS * vid.bpp); // Allocate enlarement buffer if needed //if (expand_buffer) // out_buffer = malloc(ggi_screenheight*ggi_screenwidth*vid.bpp); //else //out_buffer = (byte*)screens[0]; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -