/* 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. */ /* * vid_allg.c - Quick'n'dirty (unfinished) Allegro driver * Based on vid_svgalib.c * * By Peter Wang */ #undef stricmp #include #include "quakedef.h" #include "d_local.h" unsigned short d_8to16table[256]; static byte *vid_surfcache; static int VID_highhunkmark; static int scantokey[KEY_MAX]; static int UseMouse = 1; static int UseDisplay = 1; static int UseKeyboard = 1; static cvar_t vid_mode = {"vid_mode", "5", false}; static cvar_t vid_redrawfull = {"vid_redrawfull", "0", false}; static cvar_t vid_waitforrefresh = {"vid_waitforrefresh", "0", true}; static cvar_t mouse_button_commands[3] = { {"mouse1", "+attack"}, {"mouse2", "+strafe"}, {"mouse3", "+forward"}, }; static cvar_t m_filter = {"m_filter", "0"}; /* Common video modes (only 8 bpp for now) */ struct modeline { int width, height; int bytesperpixel; }; static struct modeline modes[] = { { 320, 200, 1 }, { 320, 240, 1 }, { 640, 400, 1 }, { 640, 480, 1 }, { 512, 384, 1 }, { 800, 600, 1 }, { 1024, 768, 1 }, { 1280, 1024, 1 } /* Ha! */ }; #define NUM_MODES (sizeof(modes) / sizeof(struct modeline)) static int current_mode = 0; static void _init_allegro() { static int virgin = 1; if (virgin) { allegro_init(); virgin = 0; } } void D_BeginDirectRect(int x, int y, byte * pbitmap, int width, int height) { /* TODO */ } void D_EndDirectRect(int x, int y, int width, int height) { /* TODO */ } /* ================= VID_Gamma_f Keybinding command ================= */ void VID_Gamma_f(void) { float gamma, f, inf; unsigned char palette[768]; int i; if (Cmd_Argc() == 2) { gamma = Q_atof(Cmd_Argv(1)); for (i = 0; i < 768; i++) { f = pow((host_basepal[i] + 1) / 256.0, gamma); inf = f * 255 + 0.5; if (inf < 0) inf = 0; if (inf > 255) inf = 255; palette[i] = inf; } VID_SetPalette(palette); vid.recalc_refdef = 1; // force a surface cache flush } } void VID_DescribeMode_f(void) { int modenum; modenum = Q_atoi (Cmd_Argv(1)); if ((modenum >= NUM_MODES) || (modenum < 0 ) || !modes[modenum].width) { Con_Printf("Invalid video mode: %d!\n", modenum); return; } Con_Printf("%d: %d x %d - %d bpp\n", modenum, modes[modenum].width, modes[modenum].height, modes[modenum].bytesperpixel << 3); } void VID_DescribeModes_f(void) { int i; for (i=0; i= NUM_MODES) { Sys_Printf("Mode [%s] not supported\n", name); return 0; } return i; } for (i=0; i> 2; pal[i].g = *ch++ >> 2; pal[i].b = *ch++ >> 2; } set_palette(pal); } int VID_SetMode(int modenum, unsigned char *palette) { int bsize, zsize, tsize; if ((modenum >= NUM_MODES) || (modenum < 0) || !modes[modenum].width) { Cvar_SetValue ("vid_mode", (float)current_mode); Con_Printf("No such video mode: %d\n", modenum); return 0; } if (set_gfx_mode(GFX_AUTODETECT, modes[modenum].width, modes[modenum].height, 0, 0) < 0) { set_gfx_mode(GFX_SAFE, 320, 200, 0, 0); modenum = 0; } set_window_title("Quake/Allegro"); VID_SetPalette(palette); vid.direct = screen->dat; Cvar_SetValue("vid_mode", (float)modenum); vid.width = SCREEN_W; vid.height = SCREEN_H; vid.rowbytes = vid.width; vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); vid.colormap = (pixel_t *) host_colormap; vid.fullbright = 256 - LittleLong(*((int *)vid.colormap + 2048)); vid.conrowbytes = vid.rowbytes; vid.conwidth = vid.width; vid.conheight = vid.height; vid.numpages = 1; vid.maxwarpwidth = WARP_WIDTH; vid.maxwarpheight = WARP_HEIGHT; // alloc zbuffer and surface cache if (d_pzbuffer) { D_FlushCaches(); Hunk_FreeToHighMark(VID_highhunkmark); d_pzbuffer = NULL; vid_surfcache = NULL; } bsize = vid.rowbytes * vid.height; tsize = D_SurfaceCacheForRes(vid.width, vid.height); zsize = vid.width * vid.height * sizeof(*d_pzbuffer); VID_highhunkmark = Hunk_HighMark(); d_pzbuffer = Hunk_HighAllocName(bsize + tsize + zsize, "video"); vid_surfcache = ((byte *) d_pzbuffer) + zsize; vid.conbuffer = vid.buffer = (pixel_t *) (((byte *) d_pzbuffer) + zsize + tsize); D_InitCaches(vid_surfcache, tsize); vid.recalc_refdef = 1; // force a surface cache flush current_mode = modenum; return 0; } static void keyhandler(int scancode) { int sc = scancode & 0x7f; if (!sc) return; if (scantokey[sc] == -1) { Con_Printf("Unsupported key: %d. Please add to vid_allg.c\n", sc); return; } Key_Event(scantokey[sc], !(scancode & 0x80)); } void VID_Init(unsigned char *palette) { int i; int w, h, d; //Cmd_AddCommand ("gamma", VID_Gamma_f); if (UseDisplay) { _init_allegro(); VID_InitModes(); Cvar_RegisterVariable(&vid_mode); Cvar_RegisterVariable(&vid_redrawfull); Cvar_RegisterVariable(&vid_waitforrefresh); Cmd_AddCommand("vid_nummodes", VID_NumModes_f); Cmd_AddCommand("vid_describemode", VID_DescribeMode_f); Cmd_AddCommand("vid_describemodes", VID_DescribeModes_f); Cmd_AddCommand("vid_debug", VID_Debug_f); // interpret command-line params w = h = d = 0; if (COM_CheckParm("-mode")) current_mode = get_mode(com_argv[COM_CheckParm("-mode")+1], w, h, d); else if (COM_CheckParm("-w") || COM_CheckParm("-h") || COM_CheckParm("-d")) { if (COM_CheckParm("-w")) w = Q_atoi(com_argv[COM_CheckParm("-w")+1]); if (COM_CheckParm("-h")) h = Q_atoi(com_argv[COM_CheckParm("-h")+1]); if (COM_CheckParm("-d")) d = Q_atoi(com_argv[COM_CheckParm("-d")+1]); current_mode = get_mode(0, w, h, d); } else current_mode = 0; // set vid parameters VID_SetMode(current_mode, palette); // we do want to run in the background when switched away set_display_switch_mode(SWITCH_BACKGROUND); } if (COM_CheckParm("-nokbd")) UseKeyboard = 0; if (UseKeyboard) { _init_allegro(); install_keyboard(); for (i = 0; i < KEY_MAX; i++) scantokey[i] = -1; /* * Fun (tm). */ scantokey[KEY_LSHIFT] = K_SHIFT; scantokey[KEY_RSHIFT] = K_SHIFT; scantokey[KEY_UP] = K_UPARROW; scantokey[KEY_DOWN] = K_DOWNARROW; scantokey[KEY_LEFT] = K_LEFTARROW; scantokey[KEY_RIGHT] = K_RIGHTARROW; scantokey[KEY_LCONTROL] = K_CTRL; scantokey[KEY_RCONTROL] = K_CTRL; scantokey[KEY_ALT] = K_ALT; scantokey[KEY_ALTGR] = K_ALT; //scantokey[KEY_CAPSLOCK] = JK_CAPS; //scantokey[KEY_NUMLOCK] = JK_NUM_LOCK; scantokey[KEY_HOME] = K_HOME; scantokey[KEY_PGUP] = K_PGUP; scantokey[KEY_END] = K_END; scantokey[KEY_PGDN] = K_PGDN; scantokey[KEY_INSERT] = K_INS; scantokey[KEY_DEL] = K_DEL; scantokey[KEY_ESC] = K_ESCAPE; scantokey[KEY_ENTER] = K_ENTER; scantokey[KEY_TAB] = K_TAB; scantokey[KEY_BACKSPACE] = K_BACKSPACE; scantokey[KEY_PAUSE] = K_PAUSE; scantokey[KEY_SPACE] = ' '; scantokey[KEY_0_PAD] = K_INS; scantokey[KEY_1_PAD] = K_END; scantokey[KEY_2_PAD] = K_DOWNARROW; scantokey[KEY_3_PAD] = K_PGDN; scantokey[KEY_4_PAD] = K_LEFTARROW; scantokey[KEY_5_PAD] = '5'; scantokey[KEY_6_PAD] = K_RIGHTARROW; scantokey[KEY_7_PAD] = K_HOME; scantokey[KEY_8_PAD] = K_UPARROW; scantokey[KEY_9_PAD] = K_PGUP; //scantokey[KEY_NUMLOCK] = K_NUMLOCK; scantokey[KEY_MINUS_PAD] = '-'; scantokey[KEY_PLUS_PAD] = '+'; scantokey[KEY_ASTERISK] = '*'; scantokey[KEY_SLASH_PAD] = '/'; scantokey[KEY_DEL_PAD] = K_DEL; scantokey[KEY_ENTER_PAD] = K_ENTER; scantokey[KEY_1] = '1'; scantokey[KEY_2] = '2'; scantokey[KEY_3] = '3'; scantokey[KEY_4] = '4'; scantokey[KEY_5] = '5'; scantokey[KEY_6] = '6'; scantokey[KEY_7] = '7'; scantokey[KEY_8] = '8'; scantokey[KEY_9] = '9'; scantokey[KEY_0] = '0'; scantokey[KEY_MINUS] = '-'; scantokey[KEY_EQUALS] = '='; scantokey[KEY_TILDE] = '`'; scantokey[KEY_OPENBRACE] = '['; scantokey[KEY_CLOSEBRACE] = ']'; scantokey[KEY_COLON] = ';'; scantokey[KEY_QUOTE] = '\''; scantokey[KEY_COMMA] = ','; scantokey[KEY_STOP] = '.'; scantokey[KEY_SLASH] = '/'; scantokey[KEY_BACKSLASH] = '\\'; scantokey[KEY_F1] = K_F1; scantokey[KEY_F2] = K_F2; scantokey[KEY_F3] = K_F3; scantokey[KEY_F4] = K_F4; scantokey[KEY_F5] = K_F5; scantokey[KEY_F6] = K_F6; scantokey[KEY_F7] = K_F7; scantokey[KEY_F8] = K_F8; scantokey[KEY_F9] = K_F9; scantokey[KEY_F10] = K_F10; scantokey[KEY_F11] = K_F11; scantokey[KEY_F12] = K_F12; scantokey[KEY_A] = 'a'; scantokey[KEY_B] = 'b'; scantokey[KEY_C] = 'c'; scantokey[KEY_D] = 'd'; scantokey[KEY_E] = 'e'; scantokey[KEY_F] = 'f'; scantokey[KEY_G] = 'g'; scantokey[KEY_H] = 'h'; scantokey[KEY_I] = 'i'; scantokey[KEY_J] = 'j'; scantokey[KEY_K] = 'k'; scantokey[KEY_L] = 'l'; scantokey[KEY_M] = 'm'; scantokey[KEY_N] = 'n'; scantokey[KEY_O] = 'o'; scantokey[KEY_P] = 'p'; scantokey[KEY_Q] = 'q'; scantokey[KEY_R] = 'r'; scantokey[KEY_S] = 's'; scantokey[KEY_T] = 't'; scantokey[KEY_U] = 'u'; scantokey[KEY_V] = 'v'; scantokey[KEY_W] = 'w'; scantokey[KEY_X] = 'x'; scantokey[KEY_Y] = 'y'; scantokey[KEY_Z] = 'z'; keyboard_lowlevel_callback = keyhandler; } } void VID_Update(vrect_t * rects) { /* TODO */ /* if (vid_redrawfull.value) { */ if (1) { int y, w = vid.rowbytes; char *p = vid.buffer; char *dest; for (y = 0; y < vid.height; y++) { dest = (char *)bmp_write_line(screen, y); memcpy(dest, p, w); p += w; } bmp_unwrite_line(screen); } #if 0 else { while (rects) { ycount = rects->height; offset = rects->y * vid.rowbytes + rects->x; while (ycount--) { register int i = offset % 0x10000; if ((offset / 0x10000) != vidpga e) { vidpage = offset / 0x10000; vga_setpage(vidpage); } if (rects->width + i > 0x10000) { memcpy(framebuffer_ptr + i, vid.buffer + offset, 0x10000 - i); vga_setpage(++vidpage); memcpy(framebuffer_ptr, vid.buffer + offset + 0x10000 - i, rects->width - 0x10000 + i); } else memcpy(framebuffer_ptr + i, vid.buffer + offset, rects->width); offset += vid.rowbytes; } rects = rects->pnext; } } #endif } void VID_DitherOn(void) { } void VID_DitherOff(void) { } void Sys_SendKeyEvents(void) { } void Force_CenterView_f(void) { cl.viewangles[PITCH] = 0; } void IN_Init(void) { if (UseMouse) { _init_allegro(); install_mouse(); install_timer(); Cvar_RegisterVariable (&mouse_button_commands[0]); Cvar_RegisterVariable (&mouse_button_commands[1]); Cvar_RegisterVariable (&mouse_button_commands[2]); Cvar_RegisterVariable (&m_filter); Cmd_AddCommand ("force_centerview", Force_CenterView_f); } } void IN_Shutdown(void) { } /* =========== IN_Commands =========== */ static int old_mouse_b; void IN_Commands(void) { static int mask[] = { 1, 2, 4}; static int k[] = { K_MOUSE1, K_MOUSE2, K_MOUSE3 }; int i; if (!UseMouse) return; for (i=0; i<3; i++) { if (mouse_b & mask[i] && !(old_mouse_b & mask[i])) Key_Event (k[i], true); else if (!(mouse_b & mask[i]) && (old_mouse_b & mask[i])) Key_Event (k[i], false); } old_mouse_b = mouse_b; } /* =========== IN_Move =========== */ static float _mouse_x, _mouse_y; static float _old_mouse_x, _old_mouse_y; void IN_MouseMove(usercmd_t * cmd) { int mx, my; if (!UseMouse) return; get_mouse_mickeys(&mx, &my); if (m_filter.value) { _mouse_x = (mx + _old_mouse_x) * 0.5; _mouse_y = (my + _old_mouse_y) * 0.5; } else { _mouse_x = mx; _mouse_y = my; } _old_mouse_x = mx; _old_mouse_y = my; _mouse_x *= sensitivity.value; _mouse_y *= sensitivity.value; // add mouse X/Y movement to cmd if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1))) cmd->sidemove += m_side.value * _mouse_x; else cl.viewangles[YAW] -= m_yaw.value * _mouse_x; if (in_mlook.state & 1) V_StopPitchDrift(); if ((in_mlook.state & 1) && !(in_strafe.state & 1)) { cl.viewangles[PITCH] += m_pitch.value * _mouse_y; if (cl.viewangles[PITCH] > 80) cl.viewangles[PITCH] = 80; if (cl.viewangles[PITCH] < -70) cl.viewangles[PITCH] = -70; } else { if ((in_strafe.state & 1) && noclip_anglehack) cmd->upmove -= m_forward.value * _mouse_y; else cmd->forwardmove -= m_forward.value * _mouse_y; } } void IN_Move(usercmd_t * cmd) { IN_MouseMove(cmd); } /* ================ VID_ModeInfo ================ */ char *VID_ModeInfo(int modenum) { static char buf[80]; sprintf(buf, "%d x %d - %d\n", modes[modenum].width, modes[modenum].height, modes[modenum].bytesperpixel << 3); return buf; }