diff --git a/doomgeneric/Makefile b/doomgeneric/Makefile new file mode 100644 index 0000000..f1d8df5 --- /dev/null +++ b/doomgeneric/Makefile @@ -0,0 +1,54 @@ +################################################################ +# +# $Id:$ +# +# $Log:$ +# + +ifeq ($(V),1) + VB='' +else + VB=@ +endif + + +CC=gcc # gcc or g++ +CFLAGS+=-ggdb3 -Os +LDFLAGS+=-Wl,--gc-sections +CFLAGS+=-ggdb3 -Wall -DNORMALUNIX -DLINUX -DSNDSERV # -DUSEASM +LIBS+=-lm -lc -lX11 + +# subdirectory for objects +OBJDIR=build +OUTPUT=doomgeneric + +SRC_DOOM = i_main.o dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_xlib.o +OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM)) + +all: $(OUTPUT) + +clean: + rm -rf $(OBJDIR) + rm -f $(OUTPUT) + rm -f $(OUTPUT).gdb + rm -f $(OUTPUT).map + +$(OUTPUT): $(OBJS) + @echo [Linking $@] + $(VB)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) \ + -o $(OUTPUT) $(LIBS) -Wl,-Map,$(OUTPUT).map + @echo [Size] + -$(CROSS_COMPILE)size $(OUTPUT) + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + mkdir -p $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @echo [Compiling $<] + $(VB)$(CC) $(CFLAGS) -c $< -o $@ + +print: + @echo OBJS: $(OBJS) + diff --git a/doomgeneric/doomgeneric.h b/doomgeneric/doomgeneric.h index 97f00e2..2588710 100644 --- a/doomgeneric/doomgeneric.h +++ b/doomgeneric/doomgeneric.h @@ -17,4 +17,4 @@ uint32_t DG_GetTicksMs(); int DG_GetKey(int* pressed, unsigned char* key); void DG_SetWindowTitle(const char * title); -#endif //DOOM_GENERIC \ No newline at end of file +#endif //DOOM_GENERIC diff --git a/doomgeneric/doomgeneric_xlib.c b/doomgeneric/doomgeneric_xlib.c new file mode 100644 index 0000000..7a1972a --- /dev/null +++ b/doomgeneric/doomgeneric_xlib.c @@ -0,0 +1,211 @@ +#include "doomkeys.h" + +#include "doomgeneric.h" + +#include +#include +#include +#include + +#include +#include +#include + +static Display *s_Display = NULL; +static Window s_Window = NULL; +static int s_Screen = 0; +static GC s_Gc = 0; +static Pixmap s_Pixmap = NULL; + +#define KEYQUEUE_SIZE 16 + +static unsigned short s_KeyQueue[KEYQUEUE_SIZE]; +static unsigned int s_KeyQueueWriteIndex = 0; +static unsigned int s_KeyQueueReadIndex = 0; + +static unsigned char convertToDoomKey(unsigned int key) +{ + switch (key) + { + case XK_Return: + key = KEY_ENTER; + break; + case XK_Escape: + key = KEY_ESCAPE; + break; + case XK_Left: + key = KEY_LEFTARROW; + break; + case XK_Right: + key = KEY_RIGHTARROW; + break; + case XK_Up: + key = KEY_UPARROW; + break; + case XK_Down: + key = KEY_DOWNARROW; + break; + case XK_Control_L: + case XK_Control_R: + key = KEY_FIRE; + break; + case XK_space: + key = KEY_USE; + break; + case XK_Shift_L: + case XK_Shift_R: + key = KEY_RSHIFT; + break; + default: + key = tolower(key); + break; + } + + return key; +} + +static void addKeyToQueue(int pressed, unsigned int keyCode) +{ + unsigned char key = convertToDoomKey(keyCode); + + unsigned short keyData = (pressed << 8) | key; + + s_KeyQueue[s_KeyQueueWriteIndex] = keyData; + s_KeyQueueWriteIndex++; + s_KeyQueueWriteIndex %= KEYQUEUE_SIZE; +} + +void DG_Init() +{ + memset(s_KeyQueue, 0, KEYQUEUE_SIZE * sizeof(unsigned short)); + + // window creation + + s_Display = XOpenDisplay(NULL); + + s_Screen = DefaultScreen(s_Display); + + int blackColor = BlackPixel(s_Display, s_Screen); + int whiteColor = WhitePixel(s_Display, s_Screen); + + XSetWindowAttributes attr; + memset(&attr, 0, sizeof(XSetWindowAttributes)); + attr.event_mask = ExposureMask | KeyPressMask; + attr.background_pixel = BlackPixel(s_Display, s_Screen); + + int depth = DefaultDepth(s_Display, s_Screen); + + s_Window = XCreateSimpleWindow(s_Display, DefaultRootWindow(s_Display), 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY, 0, blackColor, blackColor); + + XSelectInput(s_Display, s_Window, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + + XMapWindow(s_Display, s_Window); + + s_Gc = XCreateGC(s_Display, s_Window, 0, NULL); + + XSetForeground(s_Display, s_Gc, whiteColor); + + // Wait for the MapNotify event + + while(1) + { + XEvent e; + XNextEvent(s_Display, &e); + if (e.type == MapNotify) + { + break; + } + } + + s_Pixmap = XCreatePixmap(s_Display, s_Window, DOOMGENERIC_RESX, DOOMGENERIC_RESY, depth); +} + + +void DG_DrawFrame() +{ + if (s_Display) + { + while (XPending(s_Display) > 0) + { + XEvent e; + XNextEvent(s_Display, &e); + if (e.type == KeyPress) + { + KeySym sym = XKeycodeToKeysym(s_Display, e.xkey.keycode, 0); + //printf("KeyPress:%d sym:%d\n", e.xkey.keycode, sym); + + addKeyToQueue(1, sym); + } + else if (e.type == KeyRelease) + { + KeySym sym = XKeycodeToKeysym(s_Display, e.xkey.keycode, 0); + //printf("KeyRelease:%d sym:%d\n", e.xkey.keycode, sym); + addKeyToQueue(0, sym); + } + } + + XSetForeground(s_Display, s_Gc, 0x0000FF); + XFillRectangle(s_Display, s_Pixmap, s_Gc, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY); + + for (int r = 0; r < DOOMGENERIC_RESY; ++r) + { + for (int c = 0; c < DOOMGENERIC_RESX; ++c) + { + unsigned int pixel = DG_ScreenBuffer[r * DOOMGENERIC_RESX + c]; + XSetForeground(s_Display, s_Gc, pixel); + XDrawPoint(s_Display, s_Pixmap, s_Gc, c, r); + } + } + + XCopyArea(s_Display, s_Pixmap, s_Window, s_Gc, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY, + 0, 0); + + //XFlush(s_Display); + } + + //printf("frame\n"); +} + +void DG_SleepMs(uint32_t ms) +{ + usleep (ms * 1000); +} + +uint32_t DG_GetTicksMs() +{ + struct timeval tp; + struct timezone tzp; + + gettimeofday(&tp, &tzp); + + return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); /* return milliseconds */ +} + +int DG_GetKey(int* pressed, unsigned char* doomKey) +{ + if (s_KeyQueueReadIndex == s_KeyQueueWriteIndex) + { + //key queue is empty + + return 0; + } + else + { + unsigned short keyData = s_KeyQueue[s_KeyQueueReadIndex]; + s_KeyQueueReadIndex++; + s_KeyQueueReadIndex %= KEYQUEUE_SIZE; + + *pressed = keyData >> 8; + *doomKey = keyData & 0xFF; + + return 1; + } +} + +void DG_SetWindowTitle(const char * title) +{ + if (s_Window) + { + XChangeProperty(s_Display, s_Window, XA_WM_NAME, XA_STRING, 8, PropModeReplace, title, strlen(title)); + } +}