diff options
Diffstat (limited to 'apps/plugins/puzzles/src/emcc.c')
-rw-r--r-- | apps/plugins/puzzles/src/emcc.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/apps/plugins/puzzles/src/emcc.c b/apps/plugins/puzzles/src/emcc.c index ca033cbd47..23ab333f5d 100644 --- a/apps/plugins/puzzles/src/emcc.c +++ b/apps/plugins/puzzles/src/emcc.c | |||
@@ -310,6 +310,8 @@ void key(int keycode, int charcode, const char *key, const char *chr, | |||
310 | keyevent = MOD_NUM_KEYPAD | '7'; | 310 | keyevent = MOD_NUM_KEYPAD | '7'; |
311 | } else if (!strnullcmp(key, "PageUp") || keycode==33) { | 311 | } else if (!strnullcmp(key, "PageUp") || keycode==33) { |
312 | keyevent = MOD_NUM_KEYPAD | '9'; | 312 | keyevent = MOD_NUM_KEYPAD | '9'; |
313 | } else if (shift && ctrl && (keycode & 0x1F) == 26) { | ||
314 | keyevent = UI_REDO; | ||
313 | } else if (chr && chr[0] && !chr[1]) { | 315 | } else if (chr && chr[0] && !chr[1]) { |
314 | keyevent = chr[0] & 0xFF; | 316 | keyevent = chr[0] & 0xFF; |
315 | } else if (keycode >= 96 && keycode < 106) { | 317 | } else if (keycode >= 96 && keycode < 106) { |
@@ -323,10 +325,10 @@ void key(int keycode, int charcode, const char *key, const char *chr, | |||
323 | } | 325 | } |
324 | 326 | ||
325 | if (keyevent >= 0) { | 327 | if (keyevent >= 0) { |
326 | if (shift && keyevent >= 0x100) | 328 | if (shift && (keyevent >= 0x100 && !IS_UI_FAKE_KEY(keyevent))) |
327 | keyevent |= MOD_SHFT; | 329 | keyevent |= MOD_SHFT; |
328 | 330 | ||
329 | if (ctrl) { | 331 | if (ctrl && !IS_UI_FAKE_KEY(keyevent)) { |
330 | if (keyevent >= 0x100) | 332 | if (keyevent >= 0x100) |
331 | keyevent |= MOD_CTRL; | 333 | keyevent |= MOD_CTRL; |
332 | else | 334 | else |
@@ -725,7 +727,7 @@ void command(int n) | |||
725 | update_undo_redo(); | 727 | update_undo_redo(); |
726 | break; | 728 | break; |
727 | case 5: /* New Game */ | 729 | case 5: /* New Game */ |
728 | midend_process_key(me, 0, 0, 'n'); | 730 | midend_process_key(me, 0, 0, UI_NEWGAME); |
729 | update_undo_redo(); | 731 | update_undo_redo(); |
730 | js_focus_canvas(); | 732 | js_focus_canvas(); |
731 | break; | 733 | break; |
@@ -735,12 +737,12 @@ void command(int n) | |||
735 | js_focus_canvas(); | 737 | js_focus_canvas(); |
736 | break; | 738 | break; |
737 | case 7: /* Undo */ | 739 | case 7: /* Undo */ |
738 | midend_process_key(me, 0, 0, 'u'); | 740 | midend_process_key(me, 0, 0, UI_UNDO); |
739 | update_undo_redo(); | 741 | update_undo_redo(); |
740 | js_focus_canvas(); | 742 | js_focus_canvas(); |
741 | break; | 743 | break; |
742 | case 8: /* Redo */ | 744 | case 8: /* Redo */ |
743 | midend_process_key(me, 0, 0, 'r'); | 745 | midend_process_key(me, 0, 0, UI_REDO); |
744 | update_undo_redo(); | 746 | update_undo_redo(); |
745 | js_focus_canvas(); | 747 | js_focus_canvas(); |
746 | break; | 748 | break; |
@@ -757,6 +759,83 @@ void command(int n) | |||
757 | } | 759 | } |
758 | 760 | ||
759 | /* ---------------------------------------------------------------------- | 761 | /* ---------------------------------------------------------------------- |
762 | * Called from JS to prepare a save-game file, and free one after it's | ||
763 | * been used. | ||
764 | */ | ||
765 | |||
766 | struct savefile_write_ctx { | ||
767 | char *buffer; | ||
768 | size_t pos; | ||
769 | }; | ||
770 | |||
771 | static void savefile_write(void *vctx, void *buf, int len) | ||
772 | { | ||
773 | struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)vctx; | ||
774 | if (ctx->buffer) | ||
775 | memcpy(ctx->buffer + ctx->pos, buf, len); | ||
776 | ctx->pos += len; | ||
777 | } | ||
778 | |||
779 | char *get_save_file(void) | ||
780 | { | ||
781 | struct savefile_write_ctx ctx; | ||
782 | size_t size; | ||
783 | |||
784 | /* First pass, to count up the size */ | ||
785 | ctx.buffer = NULL; | ||
786 | ctx.pos = 0; | ||
787 | midend_serialise(me, savefile_write, &ctx); | ||
788 | size = ctx.pos; | ||
789 | |||
790 | /* Second pass, to actually write out the data */ | ||
791 | ctx.buffer = snewn(size, char); | ||
792 | ctx.pos = 0; | ||
793 | midend_serialise(me, savefile_write, &ctx); | ||
794 | assert(ctx.pos == size); | ||
795 | |||
796 | return ctx.buffer; | ||
797 | } | ||
798 | |||
799 | void free_save_file(char *buffer) | ||
800 | { | ||
801 | sfree(buffer); | ||
802 | } | ||
803 | |||
804 | struct savefile_read_ctx { | ||
805 | const char *buffer; | ||
806 | int len_remaining; | ||
807 | }; | ||
808 | |||
809 | static int savefile_read(void *vctx, void *buf, int len) | ||
810 | { | ||
811 | struct savefile_read_ctx *ctx = (struct savefile_read_ctx *)vctx; | ||
812 | if (ctx->len_remaining < len) | ||
813 | return FALSE; | ||
814 | memcpy(buf, ctx->buffer, len); | ||
815 | ctx->len_remaining -= len; | ||
816 | ctx->buffer += len; | ||
817 | return TRUE; | ||
818 | } | ||
819 | |||
820 | void load_game(const char *buffer, int len) | ||
821 | { | ||
822 | struct savefile_read_ctx ctx; | ||
823 | const char *err; | ||
824 | |||
825 | ctx.buffer = buffer; | ||
826 | ctx.len_remaining = len; | ||
827 | err = midend_deserialise(me, savefile_read, &ctx); | ||
828 | |||
829 | if (err) { | ||
830 | js_error_box(err); | ||
831 | } else { | ||
832 | select_appropriate_preset(); | ||
833 | resize(); | ||
834 | midend_redraw(me); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | /* ---------------------------------------------------------------------- | ||
760 | * Setup function called at page load time. It's called main() because | 839 | * Setup function called at page load time. It's called main() because |
761 | * that's the most convenient thing in Emscripten, but it's not main() | 840 | * that's the most convenient thing in Emscripten, but it's not main() |
762 | * in the usual sense of bounding the program's entire execution. | 841 | * in the usual sense of bounding the program's entire execution. |