diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5d9edc4ab..468185793 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20090521 +-------- +arch/include/event.h, arch/include/window.h, arch/sdl/event.c, arch/sdl/mouse.c, arch/sdl/window.c, d1x-rebirth.xcodeproj/project.pbxproj, main/inferno.c, SConstruct: Add new window system, not used yet + 20090506 -------- main/config.c, main/config.h, main/menu.c, main/songs.c: Add option to force either Redbook or Jukebox to use the playing order for the game CD diff --git a/SConstruct b/SConstruct index 7d8fe89fc..5267b0900 100644 --- a/SConstruct +++ b/SConstruct @@ -83,6 +83,7 @@ common_sources = [ 'arch/sdl/mouse.c', 'arch/sdl/rbaudio.c', 'arch/sdl/timer.c', +'arch/sdl/window.c', 'arch/sdl/digi.c', 'arch/sdl/digi_audio.c', 'iff/iff.c', diff --git a/arch/include/event.h b/arch/include/event.h index 1aeaedbd7..88fb5dd5e 100644 --- a/arch/include/event.h +++ b/arch/include/event.h @@ -3,7 +3,22 @@ #ifndef _EVENT_H #define _EVENT_H +typedef enum event_type +{ + EVENT_OTHER = 0, + EVENT_DRAW +} event_type; + +// A vanilla event. Cast to the correct type of event according to 'type'. +typedef struct d_event +{ + event_type type; +} d_event; + int event_init(); void event_poll(); +// Not to be confused with event_poll, which will be removed eventually, this one sends events to event handlers +void event_process(); + #endif diff --git a/arch/include/window.h b/arch/include/window.h new file mode 100644 index 000000000..bfaac47ed --- /dev/null +++ b/arch/include/window.h @@ -0,0 +1,25 @@ +/* + * A 'window' is simply a canvas that can receive events. + * It can be anything from a simple message box to the + * game screen when playing. + * + * See event.c for event handling code. + * + * -kreator 2009-05-06 + */ + +#include "event.h" +#include "gr.h" + +typedef struct window window; + +extern window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_callback)(window *wind, d_event *event, void *data), void *data); +extern void window_close(window *wind); +extern window *window_get_front(void); +extern window *window_get_first(void); +extern window *window_get_next(window *wind); +extern void window_select(window *wind); +extern void window_set_visible(window *wind, int visible); +extern int window_is_visible(window *wind); +extern grs_canvas *window_get_canvas(window *wind); +extern int window_send_event(window *wind, d_event *event); diff --git a/arch/sdl/event.c b/arch/sdl/event.c index dcd0fc0e4..db95b897c 100644 --- a/arch/sdl/event.c +++ b/arch/sdl/event.c @@ -8,7 +8,9 @@ #include #include +#include "event.h" #include "key.h" +#include "window.h" #include @@ -69,3 +71,25 @@ int event_init() return 0; } + +// Process the first event in queue, sending to the appropriate handler +// This is the new object-oriented system +// Uses the old system for now, but this will change +void event_process(void) +{ + d_event event; + window *wind; + + // Very trivial system for now. + event.type = EVENT_OTHER; // process user input first + wind = window_get_front(); + if (!wind) + return; + + window_send_event(wind, &event); + + event.type = EVENT_DRAW; // then draw all visible windows + for (wind = window_get_first(); wind != NULL; wind = window_get_next(wind)) + if (window_is_visible(wind)) + window_send_event(wind, &event); +} diff --git a/arch/sdl/mouse.c b/arch/sdl/mouse.c index e9cb4cec2..7498addb1 100644 --- a/arch/sdl/mouse.c +++ b/arch/sdl/mouse.c @@ -79,8 +79,6 @@ void mouse_button_handler(SDL_MouseButtonEvent *mbe) void mouse_motion_handler(SDL_MouseMotionEvent *mme) { - Mouse.delta_x += mme->xrel; - Mouse.delta_y += mme->yrel; Mouse.x += mme->xrel; Mouse.y += mme->yrel; } diff --git a/arch/sdl/window.c b/arch/sdl/window.c new file mode 100644 index 000000000..d3a2e827f --- /dev/null +++ b/arch/sdl/window.c @@ -0,0 +1,123 @@ +/* + * A 'window' is simply a canvas that can receive events. + * It can be anything from a simple message box to the + * game screen when playing. + * + * See event.c for event handling code. + * + * -kreator 2009-05-06 + */ + +#include "gr.h" +#include "window.h" + +struct window +{ + grs_canvas w_canv; // the window's canvas to draw to + int (*w_callback)(window *wind, d_event *event, void *data); // the event handler + int w_visible; // whether it's visible + void *data; // whatever the user wants (eg menu data for 'newmenu' menus) + struct window *prev; // the previous window in the doubly linked list + struct window *next; // the next window in the doubly linked list +}; + +static window *FrontWindow = NULL; +static window *FirstWindow = NULL; + +window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_callback)(window *wind, d_event *event, void *data), void *data) +{ + window *wind; + + wind = d_malloc(sizeof(window)); + if (wind == NULL) + return NULL; + + Assert(src != NULL); + Assert(event_callback != NULL); + gr_init_sub_canvas(&wind->w_canv, src, x, y, w, h); + wind->w_callback = event_callback; + wind->w_visible = 1; // default to visible + wind->data = data; + + if (FirstWindow == NULL) + FirstWindow = wind; + wind->prev = FrontWindow; + FrontWindow->next = wind; + wind->next = NULL; + FrontWindow = wind; + + return wind; +} + +void window_close(window *wind) +{ + if (wind == FrontWindow) + FrontWindow = wind->prev; + if (wind == FirstWindow) + FirstWindow = wind->next; + if (wind->next) + wind->next->prev = wind->prev; + if (wind->prev) + wind->prev->next = wind->next; + + d_free(wind); +} + +// Get the top window that's visible +window *window_get_front(void) +{ + window *wind; + + for (wind = FrontWindow; (wind != NULL) && !wind->w_visible; wind = wind->prev) {} + + return wind; +} + +window *window_get_first(void) +{ + return FirstWindow; +} + +window *window_get_next(window *wind) +{ + return wind->next; +} + +// Make wind the front window +void window_select(window *wind) +{ + Assert (wind != NULL); + + if (wind == FrontWindow) + return; + if ((wind == FirstWindow) && FirstWindow->next) + FirstWindow = FirstWindow->next; + + if (wind->next) + wind->next->prev = wind->prev; + if (wind->prev) + wind->prev->next = wind->next; + wind->prev = FrontWindow; + wind->next = NULL; + FrontWindow = wind; +} + +void window_set_visible(window *wind, int visible) +{ + wind->w_visible = visible; +} + +int window_is_visible(window *wind) +{ + return wind->w_visible; +} + +grs_canvas *window_get_canvas(window *wind) +{ + return &wind->w_canv; +} + +int window_send_event(window *wind, d_event *event) +{ + return wind->w_callback(wind, event, wind->data); +} diff --git a/d1x-rebirth.xcodeproj/project.pbxproj b/d1x-rebirth.xcodeproj/project.pbxproj index a060f18ba..2fd14fc07 100755 --- a/d1x-rebirth.xcodeproj/project.pbxproj +++ b/d1x-rebirth.xcodeproj/project.pbxproj @@ -273,6 +273,10 @@ EB3319FE0D5335E600C799B0 /* netdrv_udp.h in Headers */ = {isa = PBXBuildFile; fileRef = EB3319FC0D5335E600C799B0 /* netdrv_udp.h */; }; EB331A000D5335E600C799B0 /* netdrv_udp.h in Headers */ = {isa = PBXBuildFile; fileRef = EB3319FC0D5335E600C799B0 /* netdrv_udp.h */; }; EB331A0C0D53578800C799B0 /* snddecom.c in Sources */ = {isa = PBXBuildFile; fileRef = EBEEB2680D2B364300FF39B4 /* snddecom.c */; }; + EB35ABE10FB199B800C36930 /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = EB35ABDF0FB199B800C36930 /* window.h */; }; + EB35ABE20FB199B800C36930 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = EB35ABE00FB199B800C36930 /* window.c */; }; + EB35ABE30FB199B800C36930 /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = EB35ABDF0FB199B800C36930 /* window.h */; }; + EB35ABE40FB199B800C36930 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = EB35ABE00FB199B800C36930 /* window.c */; }; EB380D7D0E168B1900EBD9AD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EB380D7B0E168B1900EBD9AD /* InfoPlist.strings */; }; EB380D7E0E168B1900EBD9AD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EB380D7B0E168B1900EBD9AD /* InfoPlist.strings */; }; EB3CA5040E97749400FB1E93 /* tracker_server.c in Sources */ = {isa = PBXBuildFile; fileRef = EB3CA5020E97749400FB1E93 /* tracker_server.c */; }; @@ -561,6 +565,8 @@ EB3319F20D53351600C799B0 /* ogl_init.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ogl_init.h; sourceTree = ""; }; EB3319FB0D5335E500C799B0 /* netdrv_udp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = netdrv_udp.c; sourceTree = ""; }; EB3319FC0D5335E600C799B0 /* netdrv_udp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netdrv_udp.h; sourceTree = ""; }; + EB35ABDF0FB199B800C36930 /* window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = ""; }; + EB35ABE00FB199B800C36930 /* window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = window.c; sourceTree = ""; }; EB380D7C0E168B1900EBD9AD /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; EB3CA4F90E97740E00FB1E93 /* tracker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tracker.h; sourceTree = ""; }; EB3CA5020E97749400FB1E93 /* tracker_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = tracker_server.c; sourceTree = ""; }; @@ -929,6 +935,7 @@ 67B441DB06687A0200DF26D8 /* mouse.c */, EBCE794C0DE59565008D8F82 /* rbaudio.c */, 67B441DD06687A0200DF26D8 /* timer.c */, + EB35ABE00FB199B800C36930 /* window.c */, ); name = sdl; path = arch/sdl; @@ -1213,6 +1220,7 @@ EB3319ED0D53341900C799B0 /* jukebox.h */, EB3319EE0D53341900C799B0 /* key.h */, EB3319EF0D53341900C799B0 /* mouse.h */, + EB35ABDF0FB199B800C36930 /* window.h */, ); name = include; path = arch/include; @@ -1433,6 +1441,7 @@ EBEEB2090D2B320C00FF39B4 /* script.h in Headers */, EB3319FE0D5335E600C799B0 /* netdrv_udp.h in Headers */, EB423CE60F6273F50082C684 /* noloss.h in Headers */, + EB35ABE30FB199B800C36930 /* window.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1477,6 +1486,7 @@ EBEEB2150D2B320C00FF39B4 /* script.h in Headers */, EB331A000D5335E600C799B0 /* netdrv_udp.h in Headers */, EB423CE40F6273F50082C684 /* noloss.h in Headers */, + EB35ABE10FB199B800C36930 /* window.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1691,6 +1701,7 @@ EB3CA5040E97749400FB1E93 /* tracker_server.c in Sources */, EB28D99D0ECEABD700E68E9B /* init.c in Sources */, EB423CE50F6273F50082C684 /* noloss.c in Sources */, + EB35ABE40FB199B800C36930 /* window.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1819,6 +1830,7 @@ EB33198F0D50A70600C799B0 /* snddecom.c in Sources */, EBCE794E0DE59565008D8F82 /* rbaudio.c in Sources */, EB28D99C0ECEABD700E68E9B /* init.c in Sources */, + EB35ABE20FB199B800C36930 /* window.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/main/inferno.c b/main/inferno.c index 9c9981e44..44b09de30 100644 --- a/main/inferno.c +++ b/main/inferno.c @@ -113,6 +113,7 @@ static char *__reference[2]={copyright,(char *)__reference}; #include "newdemo.h" #include "joy.h" #include "console.h" +#include "event.h" char desc_id_exit_num = 0; int Function_mode=FMODE_MENU; //game or editor? @@ -411,6 +412,9 @@ int main(int argc,char *argv[]) default: Error("Invalid function mode %d",Function_mode); } + + // Send events to windows and the default handler + event_process(); } WriteConfigFile();