diff --git a/3rdparty/bgfx/3rdparty/khronos/vulkan/vk_platform.h b/3rdparty/bgfx/3rdparty/khronos/vulkan/vk_platform.h index f5a5243b8f2..075a18cab36 100644 --- a/3rdparty/bgfx/3rdparty/khronos/vulkan/vk_platform.h +++ b/3rdparty/bgfx/3rdparty/khronos/vulkan/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright (c) 2014-2015 The Khronos Group Inc. +** Copyright (c) 2014-2016 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -25,8 +25,8 @@ */ -#ifndef VK_PLATFORM_H_ -#define VK_PLATFORM_H_ +#ifndef __VK_PLATFORM_H__ +#define __VK_PLATFORM_H__ #ifdef __cplusplus extern "C" @@ -124,4 +124,4 @@ extern "C" #include #endif -#endif +#endif // __VK_PLATFORM_H__ diff --git a/3rdparty/bgfx/3rdparty/khronos/vulkan/vulkan.h b/3rdparty/bgfx/3rdparty/khronos/vulkan/vulkan.h index e195151acc6..f57c4d93688 100644 --- a/3rdparty/bgfx/3rdparty/khronos/vulkan/vulkan.h +++ b/3rdparty/bgfx/3rdparty/khronos/vulkan/vulkan.h @@ -41,7 +41,7 @@ extern "C" { (((major) << 22) | ((minor) << 12) | (patch)) // Vulkan API version supported by this file -#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 4) +#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 5) #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) @@ -142,6 +142,7 @@ typedef enum VkResult { VK_ERROR_OUT_OF_DATE_KHR = -1000001004, VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_RESULT_BEGIN_RANGE = VK_ERROR_FORMAT_NOT_SUPPORTED, VK_RESULT_END_RANGE = VK_INCOMPLETE, VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FORMAT_NOT_SUPPORTED + 1), @@ -979,7 +980,7 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, - VK_SHADER_STAGE_ALL_GRAPHICS = 0x1F, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, VK_SHADER_STAGE_ALL = 0x7FFFFFFF, } VkShaderStageFlagBits; typedef VkFlags VkPipelineVertexInputStateCreateFlags; @@ -992,7 +993,7 @@ typedef enum VkCullModeFlagBits { VK_CULL_MODE_NONE = 0, VK_CULL_MODE_FRONT_BIT = 0x00000001, VK_CULL_MODE_BACK_BIT = 0x00000002, - VK_CULL_MODE_FRONT_AND_BACK = 0x3, + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, } VkCullModeFlagBits; typedef VkFlags VkCullModeFlags; typedef VkFlags VkPipelineMultisampleStateCreateFlags; @@ -1083,7 +1084,7 @@ typedef VkFlags VkCommandBufferResetFlags; typedef enum VkStencilFaceFlagBits { VK_STENCIL_FACE_FRONT_BIT = 0x00000001, VK_STENCIL_FACE_BACK_BIT = 0x00000002, - VK_STENCIL_FRONT_AND_BACK = 0x3, + VK_STENCIL_FRONT_AND_BACK = 0x00000003, } VkStencilFaceFlagBits; typedef VkFlags VkStencilFaceFlags; @@ -3774,6 +3775,11 @@ VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( const char* pMessage); #endif +#define VK_NV_glsl_shader 1 +#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 +#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" + + #ifdef __cplusplus } #endif diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp index 5993e3dbe6e..77fe7decfdc 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp @@ -19,9 +19,10 @@ - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - How do I update to a newer version of ImGui? + - What is ImTextureID and how do I display an image? - Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) / A primer on the use of labels/IDs in ImGui. - I integrated ImGui in my engine and the text or lines are blurry.. - - I integrated ImGui in my engine and some elements are disappearing when I move windows around.. + - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - How can I load a different font than the default? - How can I load multiple fonts? - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? @@ -78,6 +79,7 @@ - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - see examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first at it is the simplest. + you may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). - getting started: @@ -85,12 +87,13 @@ - init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. - every frame: 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input' - 2/ call ImGui::NewFrame(). + 2/ call ImGui::NewFrame() as early as you can! 3/ use any ImGui function you want between NewFrame() and Render() - 4/ call ImGui::Render() to render all the accumulated command-lists. it will call your RenderDrawListFn handler that you set in the IO structure. + 4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure. + (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) - all rendering information are stored into command-lists until ImGui::Render() is called. - - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you must provide. - - effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases. + - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. + - effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. - refer to the examples applications in the examples/ folder for instruction on how to setup your code. - a typical application skeleton may be: @@ -107,7 +110,7 @@ unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); - // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system + // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' // Application main loop @@ -134,7 +137,7 @@ // 4) render & swap video buffers ImGui::Render(); - // swap video buffer, etc. + SwapBuffers(); } - after calling ImGui::NewFrame() you can read back flags from the IO structure to tell how ImGui intends to use your inputs. @@ -149,6 +152,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. @@ -257,6 +261,18 @@ Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. If you have a problem with a function, search for its name in the code, there will likely be a comment about it. Please report any issue to the GitHub page! + + Q: What is ImTextureID and how do I display an image? + A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. + ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! + It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc. + At the end of the chain, your renderer takes this void* to cast it back into whatever it needs to select a current texture to render. + Refer to examples applications, where each renderer (in a imgui_impl_xxxx.cpp file) is treating ImTextureID as a different thing. + (c++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) + To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions. + ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. + It is your responsibility to get textures uploaded to your GPU. + Q: Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) A: Yes. A primer on the use of labels/IDs in ImGui.. @@ -295,7 +311,7 @@ Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) - + sprintf(buf, "My game (%f FPS)###MyGame"); Begin(buf); // Variable label, ID = hash of "MyGame" @@ -354,8 +370,8 @@ A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. - Q. I integrated ImGui in my engine and some elements are disappearing when I move windows around.. - Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1,y1,x2,y2) and NOT as (x1,y1,width,height). + Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1,y1,x2,y2) and NOT as (x1,y1,width,height). Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF file you want: @@ -424,7 +440,6 @@ - window: get size/pos helpers given names (see discussion in #249) - window: a collapsed window can be stuck behind the main menu bar? - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. - - window: consider renaming "GetWindowFont" which conflict with old Windows #define (#340) - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). @@ -434,7 +449,7 @@ - widgets: clean up widgets internal toward exposing everything. - widgets: add disabled and read-only modes (#211) - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them. - - main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). + - main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) @@ -591,7 +606,6 @@ //------------------------------------------------------------------------- static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); -static const char* FindTextDisplayEnd(const char* text, const char* text_end = NULL); static void PushMultiItemsWidths(int components, float w_full = 0.0f); static float GetDraggedColumnOffset(int column_index); @@ -641,7 +655,7 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); -static void DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); //----------------------------------------------------------------------------- // Platform dependent default implementations @@ -973,7 +987,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* if ((*str & 0xf0) == 0xe0) { *out_char = 0xFFFD; // will be invalid but not end of string - if (in_text_end && in_text_end - (const char*)str < 3) return 1; + if (in_text_end && in_text_end - (const char*)str < 3) return 1; if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3; if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below c = (unsigned int)((*str++ & 0x0f) << 12); @@ -2377,7 +2391,7 @@ void ImGui::EndFrame() // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) { - g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); + g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); g.OsImePosSet = g.OsImePosRequest; } @@ -2510,8 +2524,7 @@ void ImGui::Render() } } -// Find the optional ## from which we stop displaying text. -static const char* FindTextDisplayEnd(const char* text, const char* text_end) +const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) { const char* text_display_end = text; if (!text_end) @@ -2550,7 +2563,7 @@ static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* ImGuiWindow* window = ImGui::GetCurrentWindowRead(); if (!text_end) - text_end = FindTextDisplayEnd(text, text_end); + text_end = ImGui::FindRenderedTextEnd(text, text_end); const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; window->DC.LogLinePosY = ref_pos.y; @@ -2604,7 +2617,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool const char* text_display_end; if (hide_text_after_hash) { - text_display_end = FindTextDisplayEnd(text, text_end); + text_display_end = FindRenderedTextEnd(text, text_end); } else { @@ -2643,7 +2656,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align, const ImVec2* clip_min, const ImVec2* clip_max) { // Hide anything after a '##' string - const char* text_display_end = FindTextDisplayEnd(text, text_end); + const char* text_display_end = FindRenderedTextEnd(text, text_end); const int text_len = (int)(text_display_end - text); if (text_len == 0) return; @@ -2750,7 +2763,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex const char* text_display_end; if (hide_text_after_double_hash) - text_display_end = FindTextDisplayEnd(text, text_end); // Hide anything after a '##' string + text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string else text_display_end = text_end; @@ -2829,13 +2842,13 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) // Test if mouse cursor is hovering given rectangle // NB- Rectangle is clipped by our current clip setting // NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -bool ImGui::IsMouseHoveringRect(const ImVec2& pos_min, const ImVec2& pos_max, bool clip) +bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindowRead(); // Clip - ImRect rect_clipped(pos_min, pos_max); + ImRect rect_clipped(r_min, r_max); if (clip) rect_clipped.Clip(window->ClipRect); @@ -3131,7 +3144,7 @@ static bool IsPopupOpen(ImGuiID id) return opened; } -// Mark popup as open (toggle toward open state). +// Mark popup as open (toggle toward open state). // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) @@ -3309,11 +3322,11 @@ void ImGui::EndPopup() } // This is a helper to handle the most simple case of associating one named popup to one given widget. -// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling +// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling // this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. // 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect() // and passing true to the OpenPopupEx(). -// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that +// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that // the item isn't interactable (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu // driven by click position. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) @@ -3472,7 +3485,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiWindow* ImGui::FindWindowByName(const char* name) { - // FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block + // FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block ImGuiState& g = *GImGui; ImGuiID id = ImHash(name, 0); for (int i = 0; i < g.Windows.Size; i++) @@ -3605,7 +3618,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ g.CurrentPopupStack.push_back(popup_ref); window->PopupID = popup_ref.PopupID; } - + const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); // Process SetNextWindow***() calls @@ -3753,7 +3766,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ else { size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - + // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; @@ -4832,16 +4845,19 @@ ImDrawList* ImGui::GetWindowDrawList() return window->DrawList; } -ImFont* ImGui::GetWindowFont() +ImFont* ImGui::GetFont() { - ImGuiState& g = *GImGui; - return g.Font; + return GImGui->Font; } -float ImGui::GetWindowFontSize() +float ImGui::GetFontSize() { - ImGuiState& g = *GImGui; - return g.FontSize; + return GImGui->FontSize; +} + +ImVec2 ImGui::GetFontTexUvWhitePixel() +{ + return GImGui->FontTexUvWhitePixel; } void ImGui::SetWindowFontScale(float scale) @@ -5625,7 +5641,7 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display label = str_id; const bool label_hide_text_after_double_hash = (label == str_id); // Only search and hide text after ## if we have passed label and ID separately, otherwise allow "##" within format string. const ImGuiID id = window->GetID(str_id); - const ImVec2 label_size = CalcTextSize(label, NULL, label_hide_text_after_double_hash); + const ImVec2 label_size = CalcTextSize(label, NULL, label_hide_text_after_double_hash); // We vertically grow up to current line height up the typical widget height. const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it @@ -5919,7 +5935,7 @@ static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const } // User can input math operators (e.g. +100) to edit a numerical values. -static void DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) { while (ImCharIsSpace(*buf)) buf++; @@ -5938,41 +5954,47 @@ static void DataTypeApplyOpFromText(const char* buf, const char* initial_value_b op = 0; } if (!buf[0]) - return; + return false; if (data_type == ImGuiDataType_Int) { if (!scalar_format) scalar_format = "%d"; int* v = (int*)data_ptr; - int ref_v = *v; - if (op && sscanf(initial_value_buf, scalar_format, &ref_v) < 1) - return; + const int old_v = *v; + int arg0 = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + return false; // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision - float op_v = 0.0f; - if (op == '+') { if (sscanf(buf, "%f", &op_v) == 1) *v = (int)(ref_v + op_v); } // Add (use "+-" to subtract) - else if (op == '*') { if (sscanf(buf, "%f", &op_v) == 1) *v = (int)(ref_v * op_v); } // Multiply - else if (op == '/') { if (sscanf(buf, "%f", &op_v) == 1 && op_v != 0.0f) *v = (int)(ref_v / op_v); }// Divide - else { if (sscanf(buf, scalar_format, &ref_v) == 1) *v = ref_v; } // Assign constant + float arg1 = 0.0f; + if (op == '+') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 + arg1); } // Add (use "+-" to subtract) + else if (op == '*') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 * arg1); } // Multiply + else if (op == '/') { if (sscanf(buf, "%f", &arg1) == 1 && arg1 != 0.0f) *v = (int)(arg0 / arg1); }// Divide + else { if (sscanf(buf, scalar_format, &arg0) == 1) *v = arg0; } // Assign constant + return (old_v != *v); } else if (data_type == ImGuiDataType_Float) { // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in scalar_format = "%f"; float* v = (float*)data_ptr; - float ref_v = *v; - if (op && sscanf(initial_value_buf, scalar_format, &ref_v) < 1) - return; - float op_v = 0.0f; - if (sscanf(buf, scalar_format, &op_v) < 1) - return; + const float old_v = *v; + float arg0 = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + return false; - if (op == '+') { *v = ref_v + op_v; } // Add (use "+-" to subtract) - else if (op == '*') { *v = ref_v * op_v; } // Multiply - else if (op == '/') { if (op_v != 0.0f) *v = ref_v / op_v; } // Divide - else { *v = op_v; } // Assign constant + float arg1 = 0.0f; + if (sscanf(buf, scalar_format, &arg1) < 1) + return false; + if (op == '+') { *v = arg0 + arg1; } // Add (use "+-" to subtract) + else if (op == '*') { *v = arg0 * arg1; } // Multiply + else if (op == '/') { if (arg1 != 0.0f) *v = arg0 / arg1; } // Divide + else { *v = arg1; } // Assign constant + return (old_v != *v); } + + return false; } // Create text input in place of a slider (when CTRL+Clicking on slider) @@ -5988,7 +6010,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label char buf[32]; DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); - bool value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); + bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); if (g.ScalarAsInputTextId == 0) { // First frame @@ -6001,9 +6023,9 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label // Release g.ScalarAsInputTextId = 0; } - if (value_changed) - DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); - return value_changed; + if (text_value_changed) + return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); + return false; } // Parse display precision back from the display format string @@ -6336,7 +6358,7 @@ bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_mi } ImGui::PopID(); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -6378,7 +6400,7 @@ bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int } ImGui::PopID(); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -6558,7 +6580,7 @@ bool ImGui::DragFloatN(const char* label, float* v, int components, float v_spee } ImGui::PopID(); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -6597,7 +6619,7 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu ImGui::PopItemWidth(); ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); ImGui::PopID(); @@ -6636,7 +6658,7 @@ bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, i } ImGui::PopID(); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -6675,7 +6697,7 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_ ImGui::PopItemWidth(); ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); ImGui::PopID(); @@ -6853,7 +6875,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction*100+0.01f); overlay = overlay_buf; } - + ImVec2 overlay_size = CalcTextSize(overlay, NULL); if (overlay_size.x > 0.0f) RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImGuiAlign_Left|ImGuiAlign_VCenter, &bb.Min, &bb.Max); @@ -6909,12 +6931,16 @@ bool ImGui::Checkbox(const char* label, bool* v) bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) { - bool v = (*flags & flags_value) ? true : false; + bool v = ((*flags & flags_value) == flags_value); bool pressed = ImGui::Checkbox(label, &v); - if (v) - *flags |= flags_value; - else - *flags &= ~flags_value; + if (pressed) + { + if (v) + *flags |= flags_value; + else + *flags &= ~flags_value; + } + return pressed; } @@ -7749,7 +7775,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) if (is_editable) - g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); + g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); } else { @@ -7821,10 +7847,7 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data extra_flags |= ImGuiInputTextFlags_CharsDecimal; extra_flags |= ImGuiInputTextFlags_AutoSelectAll; if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) - { - DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); - value_changed = true; - } + value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); // Step buttons if (step_ptr) @@ -7895,7 +7918,7 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal ImGui::PopID(); window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -7938,7 +7961,7 @@ bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextF ImGui::PopID(); window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); - ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::TextUnformatted(label, FindRenderedTextEnd(label)); ImGui::EndGroup(); return value_changed; @@ -8029,10 +8052,12 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const bool hovered = IsHovered(frame_bb, id); + bool popup_opened = IsPopupOpen(id); + bool popup_opened_now = false; const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING + RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_opened || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); if (*current_item >= 0 && *current_item < items_count) @@ -8045,7 +8070,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - bool menu_toggled = false; if (hovered) { SetHoveredID(id); @@ -8059,8 +8083,8 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi else { FocusWindow(window); - ImGui::OpenPopup(label); - menu_toggled = true; + OpenPopup(label); + popup_opened = popup_opened_now = true; } } } @@ -8073,8 +8097,15 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi height_in_items = 7; float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - ImRect popup_rect(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImVec2(frame_bb.Max.x, frame_bb.Max.y + popup_height)); - popup_rect.Max.y = ImMin(popup_rect.Max.y, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); // Adhoc height limit for Combo. Ideally should be handled in Begin() along with other popups size, we want to have the possibility of moving the popup above as well. + float popup_y1 = frame_bb.Max.y; + float popup_y2 = ImClamp(popup_y1 + popup_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); + if ((popup_y2 - popup_y1) < ImMin(popup_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + { + // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) + popup_y1 = ImClamp(frame_bb.Min.y - popup_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); + popup_y2 = frame_bb.Min.y; + } + ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); ImGui::SetNextWindowPos(popup_rect.Min); ImGui::SetNextWindowSize(popup_rect.GetSize()); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); @@ -8097,7 +8128,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi value_changed = true; *current_item = i; } - if (item_selected && menu_toggled) + if (item_selected && popup_opened_now) ImGui::SetScrollHere(); ImGui::PopID(); } @@ -8636,7 +8667,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) const ImVec4 col_display(col[0], col[1], col[2], 1.0f); if (ImGui::ColorButton(col_display)) g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! - + // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here if (ImGui::IsItemHovered()) ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3])); @@ -8649,7 +8680,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! } - const char* label_display_end = FindTextDisplayEnd(label); + const char* label_display_end = FindRenderedTextEnd(label); if (label != label_display_end) { ImGui::SameLine(0, (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) ? -1.0f : style.ItemInnerSpacing.x); @@ -8733,7 +8764,7 @@ void ImGui::Dummy(const ImVec2& size) ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; - + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); ItemAdd(bb, NULL); @@ -8798,33 +8829,31 @@ void ImGui::EndGroup() } // Gets back to previous line and continue with horizontal layout -// local_pos_x == 0 : follow on previous item -// local_pos_x != 0 : align to specified column +// pos_x == 0 : follow on previous item +// pos_x != 0 : align to specified column // spacing_w < 0 : use default spacing if column_x==0, no spacing if column_x!=0 // spacing_w >= 0 : enforce spacing -void ImGui::SameLine(float local_pos_x, float spacing_w) +void ImGui::SameLine(float pos_x, float spacing_w) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; ImGuiState& g = *GImGui; - float x, y; - if (local_pos_x != 0.0f) + if (pos_x != 0.0f) { if (spacing_w < 0.0f) spacing_w = 0.0f; - x = window->Pos.x - window->Scroll.x + local_pos_x + spacing_w; - y = window->DC.CursorPosPrevLine.y; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } else { if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; - x = window->DC.CursorPosPrevLine.x + spacing_w; - y = window->DC.CursorPosPrevLine.y; + window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } window->DC.CurrentLineHeight = window->DC.PrevLineHeight; window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; - window->DC.CursorPos = ImVec2(x, y); } void ImGui::NextColumn() @@ -8997,9 +9026,9 @@ void ImGui::Columns(int columns_count, const char* id, bool border) } } - // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. + // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. - ImGui::PushID(0x11223347 + (id ? 0 : columns_count)); + ImGui::PushID(0x11223347 + (id ? 0 : columns_count)); window->DC.ColumnsSetID = window->GetID(id ? id : "columns"); ImGui::PopID(); @@ -9264,10 +9293,14 @@ void ImGui::ShowMetricsWindow(bool* opened) { ImGui::SameLine(); ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) + if (node_opened) ImGui::TreePop(); + return; } if (!node_opened) return; + ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list + overlay_draw_list->PushClipRectFullScreen(); int elem_offset = 0; for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) { @@ -9276,7 +9309,7 @@ void ImGui::ShowMetricsWindow(bool* opened) ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); continue; } - ImGui::BulletText("Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); + bool draw_opened = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); if (show_clip_rects && ImGui::IsItemHovered()) { ImRect clip_rect = pcmd->ClipRect; @@ -9284,12 +9317,28 @@ void ImGui::ShowMetricsWindow(bool* opened) ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); - GImGui->OverlayDrawList.PushClipRectFullScreen(); - clip_rect.Round(); GImGui->OverlayDrawList.AddRect(clip_rect.Min, clip_rect.Max, ImColor(255,255,0)); - vtxs_rect.Round(); GImGui->OverlayDrawList.AddRect(vtxs_rect.Min, vtxs_rect.Max, ImColor(255,0,255)); - GImGui->OverlayDrawList.PopClipRect(); + clip_rect.Round(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, ImColor(255,255,0)); + vtxs_rect.Round(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, ImColor(255,0,255)); } + if (!draw_opened) + continue; + for (int i = elem_offset; i+2 < elem_offset + (int)pcmd->ElemCount; i += 3) + { + ImVec2 triangles_pos[3]; + char buf[300], *buf_p = buf; + for (int n = 0; n < 3; n++) + { + ImDrawVert& v = draw_list->VtxBuffer[(draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data[i+n] : i+n]; + triangles_pos[n] = v.pos; + buf_p += sprintf(buf_p, "vtx %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", i+n, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + } + ImGui::Selectable(buf, false); + if (ImGui::IsItemHovered()) + overlay_draw_list->AddPolyline(triangles_pos, 3, ImColor(255,255,0), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle + } + ImGui::TreePop(); } + overlay_draw_list->PopClipRect(); ImGui::TreePop(); } diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h index 7bb57318747..639891c2028 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h @@ -58,7 +58,7 @@ struct ImGuiListClipper; // Helper to manually clip large list of ite // Enumerations (declared as int for compatibility and to not pollute the top of this file) typedef unsigned int ImU32; typedef unsigned short ImWchar; // character for keyboard input/display -typedef void* ImTextureID; // user data to refer to a texture (e.g. store your texture handle/id) +typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ @@ -103,14 +103,15 @@ namespace ImGui // Main IMGUI_API ImGuiIO& GetIO(); IMGUI_API ImGuiStyle& GetStyle(); - IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() - IMGUI_API void NewFrame(); - IMGUI_API void Render(); + IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() + IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render(). + IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render()! + IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set. IMGUI_API void Shutdown(); IMGUI_API void ShowUserGuide(); // help block IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block - IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window, demonstrate ImGui features - IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window for debugging imgui + IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window demonstrating ImGui features + IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window for debugging ImGui // Window IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). @@ -124,22 +125,20 @@ namespace ImGui IMGUI_API float GetContentRegionAvailWidth(); // IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates - IMGUI_API float GetWindowContentRegionWidth(); // + IMGUI_API float GetWindowContentRegionWidth(); // IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives - IMGUI_API ImFont* GetWindowFont(); - IMGUI_API float GetWindowFontSize(); // size (also height in pixels) of current font with current scale applied - IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api) IMGUI_API ImVec2 GetWindowSize(); // get current window size IMGUI_API float GetWindowWidth(); IMGUI_API float GetWindowHeight(); IMGUI_API bool IsWindowCollapsed(); + IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin() IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin() IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() - IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() + IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set current window position - call within Begin()/End(). may incur tearing @@ -171,6 +170,9 @@ namespace ImGui IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); IMGUI_API void PopStyleVar(int count = 1); + IMGUI_API ImFont* GetFont(); // get current font + IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied + IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied @@ -189,18 +191,11 @@ namespace ImGui IMGUI_API void BeginGroup(); // lock horizontal starting position. once closing a group it is seen as a single item (so you can use IsItemHovered() on a group, SameLine() between groups, etc. IMGUI_API void EndGroup(); IMGUI_API void Separator(); // horizontal line - IMGUI_API void SameLine(float local_pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally + IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally IMGUI_API void Spacing(); // add spacing IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels IMGUI_API void Unindent(); // move content position back to the left (cancel Indent) - IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1). - IMGUI_API void NextColumn(); // next column - IMGUI_API int GetColumnIndex(); // get current column index - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this - IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column - IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) - IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position IMGUI_API float GetCursorPosX(); // " IMGUI_API float GetCursorPosY(); // " @@ -215,6 +210,16 @@ namespace ImGui IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y + // Columns + // You can also use SameLine(pos_x) for simplified columning. The columns API is still work-in-progress. + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1). + IMGUI_API void NextColumn(); // next column + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this + IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column + IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) + IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) + // ID scopes // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. @@ -330,7 +335,7 @@ namespace ImGui IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); IMGUI_API void ValueColor(const char* prefix, unsigned int v); - // Tooltip + // Tooltips IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins IMGUI_API void SetTooltipV(const char* fmt, va_list args); IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text @@ -346,8 +351,8 @@ namespace ImGui IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL - // Popup - IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). + // Popups + IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_opened = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! @@ -407,7 +412,7 @@ namespace ImGui IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window). disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any visible window - IMGUI_API bool IsMouseHoveringRect(const ImVec2& pos_min, const ImVec2& pos_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. + IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into @@ -432,6 +437,8 @@ namespace ImGui // Obsolete (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ + static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE 1.34+ static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+ static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ @@ -707,7 +714,7 @@ struct ImGuiIO // User Functions //------------------------------------------------------------------ - // Rendering function, will be called in Render(). + // Rendering function, will be called in Render(). // Alternatively you can keep this to NULL and call GetDrawData() after Render() to get the same pointer. // See example applications if you are unsure of how to implement this. void (*RenderDrawListsFn)(ImDrawData* data); @@ -1124,11 +1131,12 @@ struct ImDrawList // Primitives IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); // a: upper-left, b: lower-right - IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); // a: upper-left, b: lower-right + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f); // a: upper-left, b: lower-right + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); // a: upper-left, b: lower-right IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); + IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f); IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); - IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); + IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); @@ -1258,7 +1266,7 @@ struct ImFontAtlas int TexWidth; // Texture width calculated during Build(). int TexHeight; // Texture height calculated during Build(). int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. - ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. // Private diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp index 5169cbac1c7..533d23b4510 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -443,7 +443,7 @@ void ImGui::ShowTestWindow(bool* p_opened) static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); ImGui::Text("Password input"); - static char bufpass[64] = "password123"; + static char bufpass[64] = "password123"; ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); @@ -454,7 +454,7 @@ void ImGui::ShowTestWindow(bool* p_opened) if (ImGui::TreeNode("Multi-line Text Input")) { static bool read_only = false; - static char text[1024*16] = + static char text[1024*16] = "/*\n" " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" " the hexadecimal encoding of one offending instruction,\n" @@ -816,7 +816,7 @@ void ImGui::ShowTestWindow(bool* p_opened) if (ImGui::TreeNode("Widgets Width")) { static float f = 0.0f; - ImGui::Text("PushItemWidth(100)"); + ImGui::Text("PushItemWidth(100)"); ImGui::SameLine(); ShowHelpMarker("Fixed width."); ImGui::PushItemWidth(100); ImGui::DragFloat("float##1", &f); @@ -996,8 +996,8 @@ void ImGui::ShowTestWindow(bool* p_opened) // Tree const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; - ImGui::Button("Button##1"); - ImGui::SameLine(0.0f, spacing); + ImGui::Button("Button##1"); + ImGui::SameLine(0.0f, spacing); if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). @@ -1006,8 +1006,8 @@ void ImGui::ShowTestWindow(bool* p_opened) if (tree_opened) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data // Bullet - ImGui::Button("Button##3"); - ImGui::SameLine(0.0f, spacing); + ImGui::Button("Button##3"); + ImGui::SameLine(0.0f, spacing); ImGui::BulletText("Bullet text"); ImGui::AlignFirstTextHeightToWidgets(); @@ -1086,7 +1086,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::PopStyleVar(2); float scroll_x_delta = 0.0f; ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; - ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine(); + ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine(); ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; if (scroll_x_delta != 0.0f) { @@ -1108,7 +1108,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::InvisibleButton("##dummy", size); if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; } ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), ImColor(90,90,120,255)); - ImGui::GetWindowDrawList()->AddText(ImGui::GetWindowFont(), ImGui::GetWindowFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); + ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); ImGui::TreePop(); } } @@ -1181,7 +1181,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::Spacing(); ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); ImGui::Separator(); - // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. + // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. ImGui::PushID("foo"); @@ -1396,7 +1396,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell."); if (node_opened) { - ImGui::Columns(2, "tree items"); + ImGui::Columns(2, "tree items"); ImGui::Separator(); if (ImGui::TreeNode("Hello")) { ImGui::BulletText("Sailor"); ImGui::TreePop(); } ImGui::NextColumn(); if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Marin"); ImGui::TreePop(); } ImGui::NextColumn(); @@ -1513,7 +1513,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::Button("Holding me clears the\nthe keyboard capture flag"); if (ImGui::IsItemActive()) ImGui::CaptureKeyboardFromApp(false); - + ImGui::TreePop(); } @@ -1798,30 +1798,32 @@ static void ShowExampleAppCustomRendering(bool* opened) ImGui::Text("Primitives"); static float sz = 36.0f; static ImVec4 col = ImVec4(1.0f,1.0f,0.4f,1.0f); - ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); + ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); ImGui::ColorEdit3("Color", &col.x); { const ImVec2 p = ImGui::GetCursorScreenPos(); const ImU32 col32 = ImColor(col); float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f; - draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32); x += spacing; - draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, 1.0f); - x = p.x + 4; - y += sz+spacing; + for (int n = 0; n < 2; n++) + { + float thickness = (n == 0) ? 1.0f : 4.0f; + draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ~0, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ~0, thickness); x += sz+spacing; + draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, thickness); x += spacing; + draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, thickness); + x = p.x + 4; + y += sz+spacing; + } draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, 4.0f); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 4.0f); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, 4.0f); x += spacing; - draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, 4.0f); x += sz+spacing; + draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0)); - ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*2)); + ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); } ImGui::Separator(); { @@ -2303,7 +2305,7 @@ static void ShowExampleAppPropertyEditor(bool* p_opened) ImGui::AlignFirstTextHeightToWidgets(); ImGui::Text("my sailor is rich"); ImGui::NextColumn(); - if (opened) + if (opened) { static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; for (int i = 0; i < 8; i++) @@ -2336,7 +2338,7 @@ static void ShowExampleAppPropertyEditor(bool* p_opened) ImGui::TreePop(); } ImGui::PopID(); - } + } }; // Iterate dummy objects with dummy members (all the same data) diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp index 256bbfdd751..38a110292cf 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp @@ -18,7 +18,7 @@ #include "imgui_internal.h" #include // vsnprintf, sscanf, printf -#if !defined(alloca) && !defined(__FreeBSD__) +#if !defined(alloca) && !defined(__FreeBSD__) && !defined(__DragonFly__) #ifdef _WIN32 #include // alloca #else @@ -203,7 +203,7 @@ void ImDrawList::UpdateTextureID() AddDrawCmd(); return; } - + // Try to merge with previous command if it matches, else use current command ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; if (prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) @@ -704,11 +704,11 @@ static void PathBezierToCasteljau(ImVector* path, float x1, float y1, fl { float dx = x4 - x1; float dy = y4 - y1; - float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); - float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); + float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); + float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); d2 = (d2 >= 0) ? d2 : -d2; d3 = (d3 >= 0) ? d3 : -d3; - if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy)) + if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy)) { path->push_back(ImVec2(x4, y4)); } @@ -721,8 +721,8 @@ static void PathBezierToCasteljau(ImVector* path, float x1, float y1, fl float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; - PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); - PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); + PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); + PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); } } @@ -786,12 +786,12 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic } // a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly. -void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) +void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners, float thickness) { if ((col >> 24) == 0) return; PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners); - PathStroke(col, true); + PathStroke(col, true, thickness); } void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) @@ -825,6 +825,17 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left); } +void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathStroke(col, true, thickness); +} + void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) { if ((col >> 24) == 0) @@ -836,14 +847,14 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec PathFill(col); } -void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments) +void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness) { if ((col >> 24) == 0) return; const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments); - PathStroke(col, true); + PathStroke(col, true, thickness); } void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) @@ -856,14 +867,14 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, PathFill(col); } -void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) -{ +void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) +{ if ((col >> 24) == 0) return; - PathLineTo(pos0); - PathBezierCurveTo(cp0, cp1, pos1, num_segments); - PathStroke(col, false, thickness); + PathLineTo(pos0); + PathBezierCurveTo(cp0, cp1, pos1, num_segments); + PathStroke(col, false, thickness); } void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) @@ -876,6 +887,13 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if (text_begin == text_end) return; + // Note: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. + // Might just move Font/FontSize to ImDrawList? + if (font == NULL) + font = GImGui->Font; + if (font_size == 0.0f) + font_size = GImGui->FontSize; + IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. // reserve vertices for worse case (over-reserving is useful and easily amortized) @@ -908,12 +926,8 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, _VtxCurrentIdx = (unsigned int)VtxBuffer.Size; } -// This is one of the few function breaking the encapsulation of ImDrawLst, but it is just so useful. void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { - if ((col >> 24) == 0) - return; - AddText(GImGui->Font, GImGui->FontSize, pos, col, text_begin, text_end); } @@ -1123,7 +1137,7 @@ static unsigned int stb_decompress_length(unsigned char *input); static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); static const char* GetDefaultCompressedFontDataTTFBase85(); static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; } -static void Decode85(const unsigned char* src, unsigned char* dst) +static void Decode85(const unsigned char* src, unsigned char* dst) { while (*src) { @@ -1994,10 +2008,10 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re { char_width = glyph->XAdvance * scale; - // Clipping on Y is more likely + // Arbitrarily assume that both space and tabs are empty glyphs as an optimization if (c != ' ' && c != '\t') { - // We don't do a second finer clipping test on the Y axis (TODO: do some measurement see if it is worth it, probably not) + // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w float y1 = (float)(y + glyph->Y0 * scale); float y2 = (float)(y + glyph->Y1 * scale); @@ -2041,8 +2055,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re } } - // NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. - // inlined: + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. + // Inlined here: { idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h index f6300e74b16..9c42da079dd 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h @@ -356,7 +356,7 @@ struct ImGuiState ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. - ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvForWhite + ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel float Time; int FrameCount; @@ -683,8 +683,6 @@ namespace ImGui IMGUI_API void SetHoveredID(ImGuiID id); IMGUI_API void KeepAliveID(ImGuiID id); - IMGUI_API void EndFrame(); // Automatically called by Render() - IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); @@ -708,6 +706,7 @@ namespace ImGui IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); + IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true); IMGUI_API void PopClipRect(); diff --git a/3rdparty/bgfx/CONTRUBUTING.md b/3rdparty/bgfx/CONTRUBUTING.md index 37c959400c8..e65eb715934 100644 --- a/3rdparty/bgfx/CONTRUBUTING.md +++ b/3rdparty/bgfx/CONTRUBUTING.md @@ -4,6 +4,12 @@ Everyone is welcome to contribute to bgfx by submitting bug reports, testing on different platforms, writing examples, improving documentation, profiling and optimizing, helping newcomers, telling others about bgfx, etc. +## Submitting bugs + +Unless bug is trivial, and easy to explain and understand, the fastest way to +fix bug is to get repro case. In most of cases it's enough to modify existing +example (with minimal number of changes) and reproduce bug there. + ## Contributing code **When contributing to the bgfx project you must agree to the BSD 2-clause diff --git a/3rdparty/bgfx/README.md b/3rdparty/bgfx/README.md index 1299cab6a0c..ca00102568c 100644 --- a/3rdparty/bgfx/README.md +++ b/3rdparty/bgfx/README.md @@ -21,6 +21,7 @@ Supported rendering backends: * OpenGL ES 2 * OpenGL ES 3.1 * WebGL 1.0 + * WebGL 2.0 Supported HMD: @@ -128,6 +129,13 @@ http://makingartstudios.itch.io/dls - DLS the digital logic simulator game. ![dls-screenshot](https://img.itch.io/aW1hZ2UvMzk3MTgvMTc5MjQ4LnBuZw==/original/kA%2FQPb.png) https://github.com/mamedev/mame MAME - Multiple Arcade Machine Emulator +[Try MAME in Browser!](http://fos.textfiles.com/dfjustin/pacman/pacman/) +![mame-screenshot](https://raw.githubusercontent.com/mamedev/www.mamedev.org/d8d716dbb63919a11964b5d47b9b7f6cfa006b56/bgfx/Raiden.png) + +https://blackshift.itch.io/blackshift - Blackshift is a grid-based, space-themed +action puzzle game which isn't afraid of complexity — think Chip's Challenge on +crack. +![blackshift-screenshot](https://img.itch.io/aW1hZ2UvNTA3NDkvMjU2OTIzLmpwZw==/original/V%2BbpZD.jpg) [License (BSD 2-clause)](https://bkaradzic.github.io/bgfx/license.html) ----------------------------------------------------------------------- diff --git a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp index 92996ae0314..e2e8a599a15 100644 --- a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp +++ b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp @@ -7,6 +7,7 @@ #include "common.h" #include "bgfx_utils.h" #include "logo.h" +#include "imgui/imgui.h" class ExampleHelloWorld : public entry::AppI { @@ -28,23 +29,111 @@ class ExampleHelloWorld : public entry::AppI // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH - , 0x303030ff + , 0x000000ff , 1.0f , 0 ); + imguiCreate(); + ImGui::GetIO().FontGlobalScale = 1.5; } virtual int shutdown() BX_OVERRIDE { + // Cleanup. + imguiDestroy(); + // Shutdown bgfx. bgfx::shutdown(); return 0; } + void displayMainMenu() + { + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("Left")) + { + if (ImGui::MenuItem("Brief", "CTRL+1")) {} + if (ImGui::MenuItem("Medium", "CTRL+2")) {} + if (ImGui::MenuItem("Two columns", "CTRL+3")) {} + if (ImGui::MenuItem("Full (name)", "CTRL+4")) {} + if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {} + if (ImGui::MenuItem("Full (access)", "CTRL+6")) {} + ImGui::Separator(); + if (ImGui::BeginMenu("Sort mode")) + { + ImGui::MenuItem("Name"); + ImGui::MenuItem("Extension"); + ImGui::MenuItem("Modif. Time"); + ImGui::MenuItem("Size"); + ImGui::MenuItem("Unsorted"); + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Change source")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Files")) + { + if (ImGui::MenuItem("User menu", "F2")) {} + if (ImGui::MenuItem("View", "F3")) {} + if (ImGui::MenuItem("Edit", "F4")) {} + if (ImGui::MenuItem("Copy", "F5")) {} + if (ImGui::MenuItem("Rename or move", "F6")) {} + if (ImGui::MenuItem("Make directory", "F7")) {} + if (ImGui::MenuItem("Delete", "F8")) {} + ImGui::Separator(); + if (ImGui::MenuItem("File attributes", "CTRL+A")) {} + if (ImGui::MenuItem("Apply command", "CTRL+G")) {} + ImGui::Separator(); + if (ImGui::MenuItem("Select group")) {} + if (ImGui::MenuItem("Unselect group")) {} + if (ImGui::MenuItem("Invert selection")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Commands")) + { + if (ImGui::MenuItem("Find file", "ALT+F7")) {} + if (ImGui::MenuItem("History", "ALT+F8")) {} + if (ImGui::MenuItem("Maximize window", "ALT+F9")) {} + ImGui::Separator(); + if (ImGui::MenuItem("Panel on/off", "CTRL+O")) {} + if (ImGui::MenuItem("Equal panels", "CTRL+=")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Options")) + { + if (ImGui::MenuItem("Settings")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Right")) + { + if (ImGui::MenuItem("Brief", "CTRL+1")) {} + if (ImGui::MenuItem("Medium", "CTRL+2")) {} + if (ImGui::MenuItem("Two columns", "CTRL+3")) {} + if (ImGui::MenuItem("Full (name)", "CTRL+4")) {} + if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {} + if (ImGui::MenuItem("Full (access)", "CTRL+6")) {} + ImGui::Separator(); + if (ImGui::BeginMenu("Sort mode")) + { + ImGui::MenuItem("Name"); + ImGui::MenuItem("Extension"); + ImGui::MenuItem("Modif. Time"); + ImGui::MenuItem("Size"); + ImGui::MenuItem("Unsorted"); + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Change source")) {} + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } + } + bool update() BX_OVERRIDE { - if (!entry::processEvents(m_width, m_height, m_debug, m_reset) ) + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, m_width, m_height); @@ -53,18 +142,91 @@ class ExampleHelloWorld : public entry::AppI // if no other draw calls are submitted to view 0. bgfx::touch(0); - // Use debug font to print information about this example. - bgfx::dbgTextClear(); - bgfx::dbgTextImage(bx::uint16_max(m_width /2/8, 20)-20 - , bx::uint16_max(m_height/2/16, 6)-6 - , 40 - , 12 - , s_logo - , 160 - ); - bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld"); - bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text."); + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) + , m_mouseState.m_mz + , m_width + , m_height + ); + displayMainMenu(); + ImGui::SetNextWindowPos(ImVec2(0, 32)); + ImGui::SetNextWindowSize(ImVec2(m_width/2, m_height - 32)); + if (ImGui::Begin("Window1", nullptr, ImVec2(m_width/2, m_height-32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar)) + { + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); + ImGui::BeginChild("Sub1", ImVec2(0, m_height - 48), true); + + ImGui::Columns(4, "mycolumns"); + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 50; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + ImGui::NextColumn(); + ImGui::Text(names[i%3]); ImGui::NextColumn(); + ImGui::Text(paths[i % 3]); ImGui::NextColumn(); + ImGui::Text("...."); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + + + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + ImGui::End(); + ImGui::SameLine(); + ImGui::SetNextWindowPos(ImVec2(m_width / 2, 32)); + ImGui::SetNextWindowSize(ImVec2(m_width / 2, m_height - 32)); + if (ImGui::Begin("Window2", nullptr, ImVec2(m_width/2, m_height - 32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar)) + { + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); + ImGui::BeginChild("Sub2", ImVec2(0, m_height - 48), true); + + ImGui::Columns(4, "mycolumns"); + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("...."); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + ImGui::End(); + imguiEndFrame(); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); @@ -79,6 +241,7 @@ class ExampleHelloWorld : public entry::AppI uint32_t m_height; uint32_t m_debug; uint32_t m_reset; + entry::MouseState m_mouseState; }; ENTRY_IMPLEMENT_MAIN(ExampleHelloWorld); diff --git a/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp new file mode 100644 index 00000000000..4d467b95e61 --- /dev/null +++ b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp @@ -0,0 +1,200 @@ +/* + * Copyright 2011-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "common.h" +#include "bgfx_utils.h" +#include +#include +#include "camera.h" + +#include + +#include "../common/debugdraw/debugdraw.h" + +class DebugDrawApp : public entry::AppI +{ + void init(int _argc, char** _argv) BX_OVERRIDE + { + Args args(_argc, _argv); + + m_width = 1280; + m_height = 720; + m_debug = BGFX_DEBUG_TEXT; + m_reset = BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X16; + + bgfx::init(args.m_type, args.m_pciId); + bgfx::reset(m_width, m_height, m_reset); + + // Enable m_debug text. + bgfx::setDebug(m_debug); + + // Set view 0 clear state. + bgfx::setViewClear(0 + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 0x303030ff + , 1.0f + , 0 + ); + + m_timeOffset = bx::getHPCounter(); + + cameraCreate(); + + const float initialPos[3] = { 0.0f, 2.0f, -12.0f }; + cameraSetPosition(initialPos); + cameraSetVerticalAngle(0.0f); + + ddInit(); + } + + virtual int shutdown() BX_OVERRIDE + { + ddShutdown(); + + cameraDestroy(); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } + + bool update() BX_OVERRIDE + { + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, m_width, m_height); + + int64_t now = bx::getHPCounter() - m_timeOffset; + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency() ); + const double toMs = 1000.0/freq; + const float deltaTime = float(frameTime/freq); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/29-debugdraw"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Debug draw."); + bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); + + // Update camera. + cameraUpdate(deltaTime, m_mouseState); + + float view[16]; + cameraGetViewMtx(view); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + float zero[3] = {}; + + float mvp[16]; + float eye[] = { 5.0f, 10.0f, 5.0f }; + bx::mtxLookAt(view, eye, zero); + bx::mtxProj(proj, 45.0f, float(m_width)/float(m_height), 1.0f, 15.0f); + bx::mtxMul(mvp, view, proj); + + ddBegin(0); + ddDrawAxis(0.0f, 0.0f, 0.0f); + + ddPush(); + ddSetColor(0xff00ff00); + + Aabb aabb = + { + { 5.0f, 1.0f, 1.0f }, + { 10.0f, 5.0f, 5.0f }, + }; + ddDraw(aabb); + ddPop(); + + float time = float(now/freq); + + Obb obb; + bx::mtxRotateX(obb.m_mtx, time); + ddSetWireframe(true); + ddDraw(obb); + + ddSetColor(0xffffffff); + bx::mtxSRT(obb.m_mtx, 1.0f, 1.0f, 1.0f, 0.0f, time, 0.0f, 3.0f, 0.0f, 0.0f); + ddSetWireframe(false); + ddDraw(obb); + + ddSetTranslate(0.0f, -2.0f, 0.0f); + ddDrawGrid(Axis::Y, zero, 20, 1.0f); + ddSetTransform(NULL); + + ddDrawFrustum(mvp); + + ddPush(); + Sphere sphere = { { 0.0f, 5.0f, 0.0f }, 1.0f }; + ddSetColor(0xfff0c0ff); + ddSetWireframe(true); + ddSetLod(3); + ddDraw(sphere); + ddSetWireframe(false); + + ddSetColor(0xf0ffc0ff); + sphere.m_center[0] = -2.0f; + ddSetLod(2); + ddDraw(sphere); + + ddSetColor(0xc0f0ffff); + sphere.m_center[0] = -4.0f; + ddSetLod(1); + ddDraw(sphere); + + ddSetColor(0xffc0ff00); + sphere.m_center[0] = -6.0f; + ddSetLod(0); + ddDraw(sphere); + ddPop(); + + ddSetColor(0xffffffff); + + ddPush(); + ddSetStipple(true, 1.0f, time*0.1f); + ddSetColor(0xff0000ff); + { + float normal[3] = { 0.0f, 0.0f, 1.0f }; + float center[3] = { -8.0f, 0.0f, 0.0f }; + ddDrawCircle(normal, center, 1.0f, 0.5f + bx::fsin(time*10.0f) ); + } + ddPop(); + + ddPush(); + ddSetStipple(true, 1.0f, -time*0.1f); + ddDrawCircle(Axis::Z, -8.0f, 0.0f, 0.0f, 1.25f, 2.0f); + ddPop(); + + ddDrawOrb(-11.0f, 0.0f, 0.0f, 1.0f); + ddEnd(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + + return true; + } + + return false; + } + + entry::MouseState m_mouseState; + + int64_t m_timeOffset; + + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; +}; + +ENTRY_IMPLEMENT_MAIN(DebugDrawApp); diff --git a/3rdparty/bgfx/examples/assets/textures/normalmap.png b/3rdparty/bgfx/examples/assets/textures/normalmap.png new file mode 100644 index 00000000000..104222ee4d8 Binary files /dev/null and b/3rdparty/bgfx/examples/assets/textures/normalmap.png differ diff --git a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp index 741adb25433..87bc1e6530a 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp +++ b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp @@ -324,13 +324,15 @@ static bgfx::ShaderHandle createEmbeddedShader(bgfx::RendererType::Enum _type, u struct DebugDraw { DebugDraw() - : m_state(State::Count) + : m_depthTestLess(true) + , m_state(State::Count) { } - void init(bx::AllocatorI* _allocator) + void init(bool _depthTestLess, bx::AllocatorI* _allocator) { m_allocator = _allocator; + m_depthTestLess = _depthTestLess; #if BX_CONFIG_ALLOCATOR_CRT if (NULL == _allocator) @@ -502,9 +504,9 @@ struct DebugDraw Attrib& attrib = m_attrib[0]; attrib.m_state = 0 | BGFX_STATE_RGB_WRITE - | BGFX_STATE_DEPTH_TEST_LESS - | BGFX_STATE_DEPTH_WRITE + | (m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LESS : BGFX_STATE_DEPTH_TEST_GREATER) | BGFX_STATE_CULL_CW + | BGFX_STATE_DEPTH_WRITE ; attrib.m_scale = 1.0f; attrib.m_offset = 0.0f; @@ -533,7 +535,10 @@ struct DebugDraw void pop() { BX_CHECK(State::Count != m_state); - if (m_attrib[m_stack].m_stipple != m_attrib[m_stack-1].m_stipple) + const Attrib& curr = m_attrib[m_stack]; + const Attrib& prev = m_attrib[m_stack-1]; + if (curr.m_stipple != prev.m_stipple + || curr.m_state != prev.m_state) { flush(); } @@ -570,15 +575,20 @@ struct DebugDraw void setState(bool _depthTest, bool _depthWrite, bool _clockwise) { + const uint64_t depthTest = m_depthTestLess + ? BGFX_STATE_DEPTH_TEST_LESS + : BGFX_STATE_DEPTH_TEST_GREATER + ; + m_attrib[m_stack].m_state &= ~(0 - | BGFX_STATE_DEPTH_TEST_LESS + | BGFX_STATE_DEPTH_TEST_MASK | BGFX_STATE_DEPTH_WRITE | BGFX_STATE_CULL_CW | BGFX_STATE_CULL_CCW ); m_attrib[m_stack].m_state |= _depthTest - ? BGFX_STATE_DEPTH_TEST_LESS + ? depthTest : 0 ; @@ -1266,7 +1276,7 @@ private: bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_PT_LINES - | BGFX_STATE_DEPTH_TEST_LEQUAL + | (m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LEQUAL : BGFX_STATE_DEPTH_TEST_GEQUAL) | BGFX_STATE_DEPTH_WRITE | BGFX_STATE_LINEAA | BGFX_STATE_BLEND_ALPHA @@ -1306,6 +1316,7 @@ private: uint16_t m_vertexPos; uint8_t m_viewId; uint8_t m_stack; + bool m_depthTestLess; struct Attrib { @@ -1335,9 +1346,9 @@ private: static DebugDraw s_dd; -void ddInit(bx::AllocatorI* _allocator) +void ddInit(bool _depthTestLess, bx::AllocatorI* _allocator) { - s_dd.init(_allocator); + s_dd.init(_depthTestLess, _allocator); } void ddShutdown() diff --git a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h index e6c22094537..a318132e94f 100644 --- a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h +++ b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.h @@ -22,7 +22,7 @@ struct Axis }; /// -void ddInit(bx::AllocatorI* _allocator = NULL); +void ddInit(bool _depthTestLess = true, bx::AllocatorI* _allocator = NULL); /// void ddShutdown(); diff --git a/3rdparty/bgfx/include/bgfx/bgfx.h b/3rdparty/bgfx/include/bgfx/bgfx.h index 22537bb455d..28c232d5c7d 100644 --- a/3rdparty/bgfx/include/bgfx/bgfx.h +++ b/3rdparty/bgfx/include/bgfx/bgfx.h @@ -2361,7 +2361,14 @@ namespace bgfx , uint32_t _flags = UINT32_MAX ); - /// Touch view. + /// Submit an empty primitive for rendering. Uniforms and draw state + /// will be applied but no geometry will be submitted. + /// + /// These empty draw calls will sort before ordinary draw calls. + /// + /// @param[in] _id View id. + /// @returns Number of draw calls. + /// uint32_t touch(uint8_t _id); /// Submit primitive for rendering. diff --git a/3rdparty/bgfx/scripts/genie.lua b/3rdparty/bgfx/scripts/genie.lua index 97fe1403013..5ae3b4f73f1 100644 --- a/3rdparty/bgfx/scripts/genie.lua +++ b/3rdparty/bgfx/scripts/genie.lua @@ -422,6 +422,7 @@ exampleProject("24-nbody") exampleProject("26-occlusion") exampleProject("27-terrain") exampleProject("28-wireframe") +exampleProject("29-debugdraw") -- C99 source doesn't compile under WinRT settings if not premake.vstudio.iswinrt() then diff --git a/3rdparty/bgfx/scripts/shader.mk b/3rdparty/bgfx/scripts/shader.mk index 97be37eeee2..7a479ea8896 100644 --- a/3rdparty/bgfx/scripts/shader.mk +++ b/3rdparty/bgfx/scripts/shader.mk @@ -25,38 +25,38 @@ all: else ifeq ($(TARGET), 0) -VS_FLAGS=--platform windows -p vs_3_0 -O 3 --debug -FS_FLAGS=--platform windows -p ps_3_0 -O 3 --debug -SHADER_PATH=bgfx/shaders/dx9 +VS_FLAGS=--platform windows -p vs_3_0 -O 3 +FS_FLAGS=--platform windows -p ps_3_0 -O 3 +SHADER_PATH=shaders/dx9 else ifeq ($(TARGET), 1) -VS_FLAGS=--platform windows -p vs_4_0 -O 3 --debug -FS_FLAGS=--platform windows -p ps_4_0 -O 3 --debug -CS_FLAGS=--platform windows -p cs_5_0 -O 1 --debug -SHADER_PATH=bgfx/shaders/dx11 +VS_FLAGS=--platform windows -p vs_4_0 -O 3 +FS_FLAGS=--platform windows -p ps_4_0 -O 3 +CS_FLAGS=--platform windows -p cs_5_0 -O 1 +SHADER_PATH=shaders/dx11 else ifeq ($(TARGET), 2) VS_FLAGS=--platform nacl FS_FLAGS=--platform nacl -SHADER_PATH=bgfx/shaders/gles +SHADER_PATH=shaders/gles else ifeq ($(TARGET), 3) VS_FLAGS=--platform android FS_FLAGS=--platform android CS_FLAGS=--platform android -SHADER_PATH=bgfx/shaders/gles +SHADER_PATH=shaders/gles else ifeq ($(TARGET), 4) VS_FLAGS=--platform linux -p 120 FS_FLAGS=--platform linux -p 120 CS_FLAGS=--platform linux -p 430 -SHADER_PATH=bgfx/shaders/glsl +SHADER_PATH=shaders/glsl else ifeq ($(TARGET), 5) VS_FLAGS=--platform osx -p metal FS_FLAGS=--platform osx -p metal CS_FLAGS=--platform osx -p metal -SHADER_PATH=bgfx/shaders/metal +SHADER_PATH=shaders/metal endif endif endif diff --git a/3rdparty/bgfx/src/bgfx_shader.sh b/3rdparty/bgfx/src/bgfx_shader.sh index 29f80d0f4b2..3a1c669f321 100644 --- a/3rdparty/bgfx/src/bgfx_shader.sh +++ b/3rdparty/bgfx/src/bgfx_shader.sh @@ -29,6 +29,7 @@ #endif // BGFX_SHADER_LANGUAGE_HLSL > 3 && BGFX_SHADER_TYPE_FRAGMENT #if BGFX_SHADER_LANGUAGE_HLSL +# define CONST(_x) static const _x # define dFdx(_x) ddx(_x) # define dFdy(_y) ddy(-_y) # define inversesqrt(_x) rsqrt(_x) @@ -109,6 +110,12 @@ vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord) return _sampler.m_texture.Sample(_sampler.m_sampler, coord); } +struct BgfxSampler2DMS +{ + SamplerState m_sampler; + Texture2DMS m_texture; +}; + struct BgfxSampler2DShadow { SamplerComparisonState m_sampler; @@ -182,6 +189,21 @@ vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level) return _sampler.m_texture.SampleLevel(_sampler.m_sampler, _coord, _level); } +vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec3(_coord, _lod) ); +} + +vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx) +{ + return _sampler.m_texture.Load(_coord, _sampleIdx); +} + +vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod) +{ + return _sampler.m_texture.Load(ivec4(_coord, _lod) ); +} + # define SAMPLER2D(_name, _reg) \ uniform SamplerState _name ## Sampler : register(s[_reg]); \ uniform Texture2D _name ## Texture : register(t[_reg]); \ @@ -191,6 +213,13 @@ vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level) # define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level) # define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord) +# define SAMPLER2DMS(_name, _reg) \ + uniform SamplerState _name ## Sampler : register(s[_reg]); \ + uniform Texture2DMS _name ## Texture : register(t[_reg]); \ + static BgfxSampler2DMS _name = { _name ## Sampler, _name ## Texture } +# define sampler2DMS BgfxSampler2DMS +# define texture2DMS(_sampler, _coord, _idx) bgfxTexture2DMS(_sampler, _coord, _idx) + # define SAMPLER2DSHADOW(_name, _reg) \ uniform SamplerComparisonState _name ## Sampler : register(s[_reg]); \ uniform Texture2D _name ## Texture : register(t[_reg]); \ @@ -220,6 +249,8 @@ vec4 bgfxTextureCubeLod(BgfxSamplerCube _sampler, vec3 _coord, float _level) # define samplerCube BgfxSamplerCube # define textureCube(_sampler, _coord) bgfxTextureCube(_sampler, _coord) # define textureCubeLod(_sampler, _coord, _level) bgfxTextureCubeLod(_sampler, _coord, _level) + +# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod) # else # define sampler2DShadow sampler2D @@ -256,6 +287,7 @@ float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord) } # define SAMPLER2D(_name, _reg) uniform sampler2D _name : register(s ## _reg) +# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name : register(s ## _reg) # define texture2D(_sampler, _coord) tex2D(_sampler, _coord) # define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord) @@ -321,10 +353,12 @@ vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); } vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); } #else +# define CONST(_x) const _x # define atan2(_x, _y) atan(_x, _y) # define mul(_a, _b) ( (_a) * (_b) ) # define saturate(_x) clamp(_x, 0.0, 1.0) # define SAMPLER2D(_name, _reg) uniform sampler2D _name +# define SAMPLER2DMS(_name, _reg) uniform sampler2DMS _name # define SAMPLER3D(_name, _reg) uniform sampler3D _name # define SAMPLERCUBE(_name, _reg) uniform samplerCube _name # define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name diff --git a/3rdparty/bgfx/src/config.h b/3rdparty/bgfx/src/config.h index d16e1b97dc7..f9e4ddd2408 100644 --- a/3rdparty/bgfx/src/config.h +++ b/3rdparty/bgfx/src/config.h @@ -266,7 +266,7 @@ #endif // BGFX_CONFIG_MAX_TEXTURE_SAMPLERS #ifndef BGFX_CONFIG_MAX_FRAME_BUFFERS -# define BGFX_CONFIG_MAX_FRAME_BUFFERS 64 +# define BGFX_CONFIG_MAX_FRAME_BUFFERS 128 #endif // BGFX_CONFIG_MAX_FRAME_BUFFERS #ifndef BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS diff --git a/3rdparty/bgfx/src/glcontext_egl.cpp b/3rdparty/bgfx/src/glcontext_egl.cpp index 960500ac155..1a79d2240cc 100644 --- a/3rdparty/bgfx/src/glcontext_egl.cpp +++ b/3rdparty/bgfx/src/glcontext_egl.cpp @@ -252,6 +252,8 @@ EGL_IMPORT const bool hasEglKhrCreateContext = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context"); const bool hasEglKhrNoError = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error"); + const uint32_t gles = BGFX_CONFIG_RENDERER_OPENGLES; + for (uint32_t ii = 0; ii < 2; ++ii) { bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) ); @@ -264,10 +266,10 @@ EGL_IMPORT if (hasEglKhrCreateContext) { bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) ); - bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES / 10) ); + bx::write(&writer, EGLint(gles / 10) ); bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) ); - bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES % 10) ); + bx::write(&writer, EGLint(gles % 10) ); flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0 | EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR diff --git a/3rdparty/bgfx/src/glimports.h b/3rdparty/bgfx/src/glimports.h index de3b1c7b72d..f288a6a3597 100644 --- a/3rdparty/bgfx/src/glimports.h +++ b/3rdparty/bgfx/src/glimports.h @@ -65,6 +65,7 @@ typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat typedef void (GL_APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble d); typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); @@ -169,6 +170,7 @@ typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum mode); typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); @@ -181,7 +183,9 @@ typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat* param); typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); @@ -249,6 +253,7 @@ GL_IMPORT______(false, PFNGLCLEARPROC, glClear); GL_IMPORT______(true, PFNGLCLEARBUFFERFVPROC, glClearBufferfv); GL_IMPORT______(false, PFNGLCLEARCOLORPROC, glClearColor); GL_IMPORT______(false, PFNGLCLEARSTENCILPROC, glClearStencil); +GL_IMPORT______(true, PFNGLCLIPCONTROLPROC, glClipControl); GL_IMPORT______(false, PFNGLCOLORMASKPROC, glColorMask); GL_IMPORT______(false, PFNGLCOMPILESHADERPROC, glCompileShader); GL_IMPORT______(false, PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D); @@ -354,6 +359,7 @@ GL_IMPORT______(true, PFNGLREADBUFFERPROC, glReadBuffer) GL_IMPORT______(false, PFNGLREADPIXELSPROC, glReadPixels); GL_IMPORT______(true, PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage); GL_IMPORT______(true, PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample); +GL_IMPORT______(true, PFNGLSAMPLEMASKIPROC, glSampleMaski); GL_IMPORT______(true, PFNGLSAMPLERPARAMETERIPROC, glSamplerParameteri); GL_IMPORT______(true, PFNGLSAMPLERPARAMETERFPROC, glSamplerParameterf); GL_IMPORT______(true, PFNGLSAMPLERPARAMETERFVPROC, glSamplerParameterfv); @@ -366,7 +372,9 @@ GL_IMPORT______(true, PFNGLSTENCILMASKSEPARATEPROC, glStencilMask GL_IMPORT______(false, PFNGLSTENCILOPPROC, glStencilOp); GL_IMPORT______(true, PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate); GL_IMPORT______(false, PFNGLTEXIMAGE2DPROC, glTexImage2D); +GL_IMPORT______(true, PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); GL_IMPORT______(true, PFNGLTEXIMAGE3DPROC, glTexImage3D); +GL_IMPORT______(true, PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); GL_IMPORT______(false, PFNGLTEXPARAMETERIPROC, glTexParameteri); GL_IMPORT______(false, PFNGLTEXPARAMETERIVPROC, glTexParameteriv); GL_IMPORT______(false, PFNGLTEXPARAMETERFPROC, glTexParameterf); diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index e86b09eaa58..cd794028c30 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -2705,11 +2705,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_blendStateCache.add(hash, bs); } - const uint64_t f0 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR); - const uint64_t f1 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_FACTOR, BGFX_STATE_BLEND_INV_FACTOR); - bool hasFactor = false + const uint64_t f0 = BGFX_STATE_BLEND_FACTOR; + const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR; + const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4; + const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4; + bool hasFactor = 0 || f0 == (_state & f0) || f1 == (_state & f1) + || f2 == (_state & f2) + || f3 == (_state & f3) ; float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; @@ -2798,6 +2802,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { uint32_t cull = (_state&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT; +#if BX_PLATFORM_WINDOWS if (m_deviceInterfaceVersion >= 3) { D3D11_RASTERIZER_DESC2 desc; @@ -2821,6 +2826,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_CHECK(device3->CreateRasterizerState2(&desc, reinterpret_cast(&rs) ) ); } else +#endif // BX_PLATFORM_WINDOWS { D3D11_RASTERIZER_DESC desc; desc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp index 40366c59078..9cb4f1915d0 100644 --- a/3rdparty/bgfx/src/renderer_d3d12.cpp +++ b/3rdparty/bgfx/src/renderer_d3d12.cpp @@ -4629,8 +4629,10 @@ data.NumQualityLevels = 0; m_backBufferColorIdx = m_swapChain->GetCurrentBackBufferIndex(); #endif // BX_PLATFORM_WINDOWS - const uint64_t f0 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR); - const uint64_t f1 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_FACTOR, BGFX_STATE_BLEND_INV_FACTOR); + const uint64_t f0 = BGFX_STATE_BLEND_FACTOR; + const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR; + const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4; + const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4; D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle; ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; @@ -5029,6 +5031,8 @@ data.NumQualityLevels = 0; bool hasFactor = 0 || f0 == (state & f0) || f1 == (state & f1) + || f2 == (state & f2) + || f3 == (state & f3) ; const VertexBufferD3D12& vb = m_vertexBuffers[draw.m_vertexBuffer.idx]; diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp index 43516be1919..ca09b64eba1 100644 --- a/3rdparty/bgfx/src/renderer_gl.cpp +++ b/3rdparty/bgfx/src/renderer_gl.cpp @@ -186,9 +186,9 @@ namespace bgfx { namespace gl static const GLenum s_textureFilterMin[][3] = { - { GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_LINEAR }, - { GL_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_NEAREST }, - { GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_LINEAR }, + { GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST }, + { GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST }, + { GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST }, }; struct TextureFormatInfo @@ -465,6 +465,7 @@ namespace bgfx { namespace gl APPLE_texture_format_BGRA8888, APPLE_texture_max_level, + ARB_clip_control, ARB_compute_shader, ARB_conservative_depth, ARB_copy_image, @@ -540,6 +541,7 @@ namespace bgfx { namespace gl EXT_framebuffer_blit, EXT_framebuffer_object, EXT_framebuffer_sRGB, + EXT_gpu_shader4, EXT_multi_draw_indirect, EXT_occlusion_query_boolean, EXT_packed_float, @@ -673,6 +675,7 @@ namespace bgfx { namespace gl { "APPLE_texture_format_BGRA8888", false, true }, { "APPLE_texture_max_level", false, true }, + { "ARB_clip_control", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_compute_shader", BGFX_CONFIG_RENDERER_OPENGL >= 43, true }, { "ARB_conservative_depth", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, { "ARB_copy_image", BGFX_CONFIG_RENDERER_OPENGL >= 42, true }, @@ -748,6 +751,7 @@ namespace bgfx { namespace gl { "EXT_framebuffer_blit", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "EXT_framebuffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, { "EXT_framebuffer_sRGB", BGFX_CONFIG_RENDERER_OPENGL >= 30, true }, + { "EXT_gpu_shader4", false, true }, { "EXT_multi_draw_indirect", false, true }, // GLES3.1 extension. { "EXT_occlusion_query_boolean", false, true }, // GLES2 extension. { "EXT_packed_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true }, @@ -899,6 +903,21 @@ namespace bgfx { namespace gl NULL }; + static const char* s_texelFetch[] = + { + "texelFetch", + "texelFetchOffset", + NULL + }; + + static const char* s_ARB_texture_multisample[] = + { + "sampler2DMS", + "isampler2DMS", + "usampler2DMS", + NULL + }; + static void GL_APIENTRY stubVertexAttribDivisor(GLuint /*_index*/, GLuint /*_divisor*/) { } @@ -4437,11 +4456,11 @@ namespace bgfx { namespace gl && !s_textureFilter[m_textureFormat]) { // Force point sampling when texture format doesn't support linear sampling. - _flags &= 0 + _flags &= ~(0 | BGFX_TEXTURE_MIN_MASK | BGFX_TEXTURE_MAG_MASK | BGFX_TEXTURE_MIP_MASK - ; + ); _flags |= 0 | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT @@ -4819,16 +4838,18 @@ namespace bgfx { namespace gl else if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) && BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL <= 21) ) { - bool usesTextureLod = true + const bool usesTextureLod = true && s_extension[Extension::ARB_shader_texture_lod].m_supported && bx::findIdentifierMatch(code, s_ARB_shader_texture_lod) ; + const bool usesIUsamplers = !!bx::findIdentifierMatch(code, s_uisamplers); + const bool usesTexelFetch = !!bx::findIdentifierMatch(code, s_texelFetch); + const bool usesTextureMS = !!bx::findIdentifierMatch(code, s_ARB_texture_multisample); - bool usesIUsamplers = !!bx::findIdentifierMatch(code, s_uisamplers); - - uint32_t version = usesIUsamplers - ? 130 - : (usesTextureLod ? 120 : 0) + uint32_t version = + usesIUsamplers || usesTexelFetch || usesTextureMS ? 130 + : usesTextureLod ? 120 + : 0 ; if (0 != version) @@ -4844,6 +4865,11 @@ namespace bgfx { namespace gl } } + if (usesTextureMS) + { + writeString(&writer, "#extension GL_ARB_texture_multisample : enable\n"); + } + if (130 <= version) { if (m_type == GL_FRAGMENT_SHADER) diff --git a/3rdparty/bgfx/src/shader.cpp b/3rdparty/bgfx/src/shader.cpp index 32970b8ce08..54c08aec5ce 100644 --- a/3rdparty/bgfx/src/shader.cpp +++ b/3rdparty/bgfx/src/shader.cpp @@ -42,13 +42,13 @@ namespace bgfx uint32_t magic; bx::peek(_reader, magic); - if (magic == 0x07230203) + if (magic == SPV_CHUNK_HEADER) { SpirV spirv; read(_reader, spirv, _err); parse(spirv.shader, printAsm, _writer, _err); } - else if (magic == BX_MAKEFOURCC('D', 'X', 'B', 'C') ) + else if (magic == DXBC_CHUNK_HEADER) { DxbcContext dxbc; read(_reader, dxbc, _err); diff --git a/3rdparty/bgfx/src/shader_dxbc.cpp b/3rdparty/bgfx/src/shader_dxbc.cpp index 780688a3e8b..1cc948d316e 100644 --- a/3rdparty/bgfx/src/shader_dxbc.cpp +++ b/3rdparty/bgfx/src/shader_dxbc.cpp @@ -1735,7 +1735,6 @@ namespace bgfx return size; } -#define DXBC_CHUNK_HEADER BX_MAKEFOURCC('D', 'X', 'B', 'C') #define DXBC_CHUNK_SHADER BX_MAKEFOURCC('S', 'H', 'D', 'R') #define DXBC_CHUNK_SHADER_EX BX_MAKEFOURCC('S', 'H', 'E', 'X') diff --git a/3rdparty/bgfx/src/shader_dxbc.h b/3rdparty/bgfx/src/shader_dxbc.h index 0216ec808ef..db90e3ef80c 100644 --- a/3rdparty/bgfx/src/shader_dxbc.h +++ b/3rdparty/bgfx/src/shader_dxbc.h @@ -8,6 +8,8 @@ #include +#define DXBC_CHUNK_HEADER BX_MAKEFOURCC('D', 'X', 'B', 'C') + namespace bgfx { struct DxbcOpcode diff --git a/3rdparty/bgfx/src/shader_spirv.cpp b/3rdparty/bgfx/src/shader_spirv.cpp index 2d30e996af6..a5809ae6c13 100644 --- a/3rdparty/bgfx/src/shader_spirv.cpp +++ b/3rdparty/bgfx/src/shader_spirv.cpp @@ -706,54 +706,54 @@ namespace bgfx SpvOperand::Enum operands[2]; }; -// static const SpvDecorationInfo s_spvDecorationInfo[] = -// { -// { /* RelaxedPrecision */ SPV_OPERAND(_) }, -// { /* SpecId */ SPV_OPERAND(LiteralNumber) }, -// { /* Block */ SPV_OPERAND(_) }, -// { /* BufferBlock */ SPV_OPERAND(_) }, -// { /* RowMajor */ SPV_OPERAND(_) }, -// { /* ColMajor */ SPV_OPERAND(_) }, -// { /* ArrayStride */ SPV_OPERAND(LiteralNumber) }, -// { /* MatrixStride */ SPV_OPERAND(LiteralNumber) }, -// { /* GLSLShared */ SPV_OPERAND(_) }, -// { /* GLSLPacked */ SPV_OPERAND(_) }, -// { /* CPacked */ SPV_OPERAND(_) }, -// { /* BuiltIn */ SPV_OPERAND(LiteralNumber) }, -// { /* Unknown12 */ SPV_OPERAND(_) }, -// { /* NoPerspective */ SPV_OPERAND(_) }, -// { /* Flat */ SPV_OPERAND(_) }, -// { /* Patch */ SPV_OPERAND(_) }, -// { /* Centroid */ SPV_OPERAND(_) }, -// { /* Sample */ SPV_OPERAND(_) }, -// { /* Invariant */ SPV_OPERAND(_) }, -// { /* Restrict */ SPV_OPERAND(_) }, -// { /* Aliased */ SPV_OPERAND(_) }, -// { /* Volatile */ SPV_OPERAND(_) }, -// { /* Constant */ SPV_OPERAND(_) }, -// { /* Coherent */ SPV_OPERAND(_) }, -// { /* NonWritable */ SPV_OPERAND(_) }, -// { /* NonReadable */ SPV_OPERAND(_) }, -// { /* Uniform */ SPV_OPERAND(_) }, -// { /* Unknown27 */ SPV_OPERAND(_) }, -// { /* SaturatedConversion */ SPV_OPERAND(_) }, -// { /* Stream */ SPV_OPERAND(LiteralNumber) }, -// { /* Location */ SPV_OPERAND(LiteralNumber) }, -// { /* Component */ SPV_OPERAND(LiteralNumber) }, -// { /* Index */ SPV_OPERAND(LiteralNumber) }, -// { /* Binding */ SPV_OPERAND(LiteralNumber) }, -// { /* DescriptorSet */ SPV_OPERAND(LiteralNumber) }, -// { /* Offset */ SPV_OPERAND(LiteralNumber) }, -// { /* XfbBuffer */ SPV_OPERAND(LiteralNumber) }, -// { /* XfbStride */ SPV_OPERAND(LiteralNumber) }, -// { /* FuncParamAttr */ SPV_OPERAND(_) }, -// { /* FPRoundingMode */ SPV_OPERAND(_) }, -// { /* FPFastMathMode */ SPV_OPERAND(_) }, -// { /* LinkageAttributes */ SPV_OPERAND(LiteralString, LinkageType) }, -// { /* NoContraction */ SPV_OPERAND(_) }, -// { /* InputAttachmentIndex */ SPV_OPERAND(LiteralNumber) }, -// { /* Alignment */ SPV_OPERAND(LiteralNumber) }, -// }; + static const SpvDecorationInfo s_spvDecorationInfo[] = + { + { /* RelaxedPrecision */ SPV_OPERAND(_) }, + { /* SpecId */ SPV_OPERAND(LiteralNumber) }, + { /* Block */ SPV_OPERAND(_) }, + { /* BufferBlock */ SPV_OPERAND(_) }, + { /* RowMajor */ SPV_OPERAND(_) }, + { /* ColMajor */ SPV_OPERAND(_) }, + { /* ArrayStride */ SPV_OPERAND(LiteralNumber) }, + { /* MatrixStride */ SPV_OPERAND(LiteralNumber) }, + { /* GLSLShared */ SPV_OPERAND(_) }, + { /* GLSLPacked */ SPV_OPERAND(_) }, + { /* CPacked */ SPV_OPERAND(_) }, + { /* BuiltIn */ SPV_OPERAND(LiteralNumber) }, + { /* Unknown12 */ SPV_OPERAND(_) }, + { /* NoPerspective */ SPV_OPERAND(_) }, + { /* Flat */ SPV_OPERAND(_) }, + { /* Patch */ SPV_OPERAND(_) }, + { /* Centroid */ SPV_OPERAND(_) }, + { /* Sample */ SPV_OPERAND(_) }, + { /* Invariant */ SPV_OPERAND(_) }, + { /* Restrict */ SPV_OPERAND(_) }, + { /* Aliased */ SPV_OPERAND(_) }, + { /* Volatile */ SPV_OPERAND(_) }, + { /* Constant */ SPV_OPERAND(_) }, + { /* Coherent */ SPV_OPERAND(_) }, + { /* NonWritable */ SPV_OPERAND(_) }, + { /* NonReadable */ SPV_OPERAND(_) }, + { /* Uniform */ SPV_OPERAND(_) }, + { /* Unknown27 */ SPV_OPERAND(_) }, + { /* SaturatedConversion */ SPV_OPERAND(_) }, + { /* Stream */ SPV_OPERAND(LiteralNumber) }, + { /* Location */ SPV_OPERAND(LiteralNumber) }, + { /* Component */ SPV_OPERAND(LiteralNumber) }, + { /* Index */ SPV_OPERAND(LiteralNumber) }, + { /* Binding */ SPV_OPERAND(LiteralNumber) }, + { /* DescriptorSet */ SPV_OPERAND(LiteralNumber) }, + { /* Offset */ SPV_OPERAND(LiteralNumber) }, + { /* XfbBuffer */ SPV_OPERAND(LiteralNumber) }, + { /* XfbStride */ SPV_OPERAND(LiteralNumber) }, + { /* FuncParamAttr */ SPV_OPERAND(_) }, + { /* FPRoundingMode */ SPV_OPERAND(_) }, + { /* FPFastMathMode */ SPV_OPERAND(_) }, + { /* LinkageAttributes */ SPV_OPERAND(LiteralString, LinkageType) }, + { /* NoContraction */ SPV_OPERAND(_) }, + { /* InputAttachmentIndex */ SPV_OPERAND(LiteralNumber) }, + { /* Alignment */ SPV_OPERAND(LiteralNumber) }, + }; static const char* s_spvDecoration[] = { @@ -808,6 +808,7 @@ namespace bgfx const char* getName(SpvDecoration::Enum _enum) { + BX_UNUSED(s_spvDecorationInfo); BX_CHECK(_enum <= SpvDecoration::Count, "Unknown decoration id %d.", _enum); return _enum <= SpvDecoration::Count ? s_spvDecoration[_enum] @@ -920,7 +921,7 @@ namespace bgfx break; default: - size += bx::read(_reader, _operand.data[0], _err); + size += bx::read(_reader, _operand.data, _err); break; } @@ -1046,7 +1047,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%sAddressingModel(%d)" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; @@ -1054,7 +1055,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%s%s" , 0 == ii ? " " : ", " - , getName(SpvDecoration::Enum(operand.data[0]) ) + , getName(SpvDecoration::Enum(operand.data) ) ); break; @@ -1062,7 +1063,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%s0x%08x" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; @@ -1070,7 +1071,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%s%d" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; @@ -1086,7 +1087,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%sMemoryModel(%d)" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; @@ -1094,7 +1095,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%s%s" , 0 == ii ? " " : ", " - , getName(SpvStorageClass::Enum(operand.data[0]) ) + , getName(SpvStorageClass::Enum(operand.data) ) ); break; @@ -1102,7 +1103,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%s__%d__" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; @@ -1110,7 +1111,7 @@ namespace bgfx size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size) , "%sr%d" , 0 == ii ? " " : ", " - , operand.data[0] + , operand.data ); break; diff --git a/3rdparty/bgfx/src/shader_spirv.h b/3rdparty/bgfx/src/shader_spirv.h index 5c7a983f63a..9a7f4ccdeef 100644 --- a/3rdparty/bgfx/src/shader_spirv.h +++ b/3rdparty/bgfx/src/shader_spirv.h @@ -11,6 +11,8 @@ BX_ERROR_RESULT(BGFX_SHADER_SPIRV_INVALID_HEADER, BX_MAKEFOURCC('S', 'H', 0, 1) ); BX_ERROR_RESULT(BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, BX_MAKEFOURCC('S', 'H', 0, 2) ); +#define SPV_CHUNK_HEADER BX_MAKEFOURCC(0x03, 0x02, 0x23, 0x07) + namespace bgfx { // Reference: https://www.khronos.org/registry/spir-v/specs/1.0/SPIRV.html @@ -581,9 +583,8 @@ namespace bgfx }; Enum type; - uint32_t data[4]; + uint32_t data; - uint32_t target; stl::string literalString; }; diff --git a/3rdparty/bgfx/tools/shaderc/shaderc.cpp b/3rdparty/bgfx/tools/shaderc/shaderc.cpp index a5b14edcf48..a0f89e4f647 100644 --- a/3rdparty/bgfx/tools/shaderc/shaderc.cpp +++ b/3rdparty/bgfx/tools/shaderc/shaderc.cpp @@ -98,6 +98,14 @@ namespace bgfx NULL }; + static const char* s_ARB_texture_multisample[] = + { + "sampler2DMS", + "isampler2DMS", + "usampler2DMS", + NULL + }; + const char* s_uniformTypeName[UniformType::Count] = { "int", @@ -1058,6 +1066,20 @@ namespace bgfx memset(&data[size+1], 0, padding); fclose(file); + if (!raw) + { + // To avoid commented code being recognized as used feature, + // first preprocess pass is used to strip all comments before + // substituting code. + preprocessor.run(data); + delete [] data; + + size = (uint32_t)preprocessor.m_preprocessed.size(); + data = new char[size+padding+1]; + memcpy(data, preprocessor.m_preprocessed.c_str(), size); + memset(&data[size], 0, padding+1); + } + strNormalizeEol(data); input = const_cast(bx::strws(data) ); @@ -1090,21 +1112,6 @@ namespace bgfx input = const_cast(bx::strws(input) ); } - - if (!raw) - { - // To avoid commented code being recognized as used feature, - // first preprocess pass is used to strip all comments before - // substituting code. - preprocessor.run(input); - delete [] data; - - size = (uint32_t)preprocessor.m_preprocessed.size(); - data = new char[size+padding+1]; - memcpy(data, preprocessor.m_preprocessed.c_str(), size); - memset(&data[size], 0, padding+1); - input = data; - } } if (raw) @@ -1726,6 +1733,7 @@ namespace bgfx const bool hasTextureLod = NULL != bx::findIdentifierMatch(input, s_ARB_shader_texture_lod /*EXT_shader_texture_lod*/); const bool hasShader5 = NULL != bx::findIdentifierMatch(input, s_ARB_gpu_shader5); const bool hasShaderPacking = NULL != bx::findIdentifierMatch(input, s_ARB_shading_language_packing); + const bool hasTextureMS = NULL != bx::findIdentifierMatch(input, s_ARB_texture_multisample); if (0 == essl) { @@ -1768,6 +1776,13 @@ namespace bgfx , "#extension GL_ARB_shader_texture_lod : enable\n" ); } + + if (hasTextureMS) + { + bx::stringPrintf(code + , "#extension GL_ARB_texture_multisample : enable\n" + ); + } } else { diff --git a/3rdparty/bx/3rdparty/UnitTest++/src/Config.h b/3rdparty/bx/3rdparty/UnitTest++/src/Config.h index 5deeb277156..200833e9eae 100644 --- a/3rdparty/bx/3rdparty/UnitTest++/src/Config.h +++ b/3rdparty/bx/3rdparty/UnitTest++/src/Config.h @@ -22,7 +22,8 @@ || defined(__NetBSD__) \ || defined(__OpenBSD__) \ || defined(__FreeBSD__) \ - || defined(__native_client__) + || defined(__native_client__) \ + || defined(__riscv) # define UNITTEST_POSIX #endif diff --git a/3rdparty/bx/include/bx/config.h b/3rdparty/bx/include/bx/config.h index 72a6dc3e4af..59917706b43 100644 --- a/3rdparty/bx/include/bx/config.h +++ b/3rdparty/bx/include/bx/config.h @@ -24,6 +24,15 @@ # define BX_CONFIG_CRT_FILE_READER_WRITER !(BX_PLATFORM_NACL) #endif // BX_CONFIG_CRT_FILE_READER_WRITER +#ifndef BX_CONFIG_CRT_PROCESS +# define BX_CONFIG_CRT_PROCESS !(0 \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE \ + ) +#endif // BX_CONFIG_CRT_PROCESS + #ifndef BX_CONFIG_SEMAPHORE_PTHREAD # define BX_CONFIG_SEMAPHORE_PTHREAD (BX_PLATFORM_OSX || BX_PLATFORM_IOS) #endif // BX_CONFIG_SEMAPHORE_PTHREAD diff --git a/3rdparty/bx/include/bx/crtimpl.h b/3rdparty/bx/include/bx/crtimpl.h index 70cee21d028..a4820334ee3 100644 --- a/3rdparty/bx/include/bx/crtimpl.h +++ b/3rdparty/bx/include/bx/crtimpl.h @@ -192,6 +192,117 @@ namespace bx }; #endif // BX_CONFIG_CRT_FILE_READER_WRITER +#if BX_CONFIG_CRT_PROCESS + +#if BX_COMPILER_MSVC_COMPATIBLE +# define popen _popen +# define pclose _pclose +#endif // BX_COMPILER_MSVC_COMPATIBLE + + class ProcessReader : public ReaderOpenI, public CloserI, public ReaderI + { + public: + ProcessReader() + : m_file(NULL) + { + } + + ~ProcessReader() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + virtual bool open(const char* _command, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + m_file = popen(_command, "r"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process."); + return false; + } + + return true; + } + + virtual void close() BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Process not open!"); + pclose(m_file); + m_file = NULL; + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + int32_t size = (int32_t)fread(_data, 1, _size, m_file); + if (size != _size) + { + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + }; + + class ProcessWriter : public WriterOpenI, public CloserI, public WriterI + { + public: + ProcessWriter() + : m_file(NULL) + { + } + + ~ProcessWriter() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + virtual bool open(const char* _command, bool, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + m_file = popen(_command, "w"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process."); + return false; + } + + return true; + } + + virtual void close() BX_OVERRIDE + { + BX_CHECK(NULL != m_file, "Process not open!"); + pclose(m_file); + m_file = NULL; + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + int32_t size = (int32_t)fwrite(_data, 1, _size, m_file); + if (size != _size) + { + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + }; + +#endif // BX_CONFIG_CRT_PROCESS + } // namespace bx #endif // BX_CRTIMPL_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/fpumath.h b/3rdparty/bx/include/bx/fpumath.h index 0dd274feb24..2335ad4f2f3 100644 --- a/3rdparty/bx/include/bx/fpumath.h +++ b/3rdparty/bx/include/bx/fpumath.h @@ -14,10 +14,28 @@ namespace bx { - static const float pi = 3.14159265358979323846f; - static const float invPi = 1.0f/3.14159265358979323846f; - static const float piHalf = 1.57079632679489661923f; - static const float sqrt2 = 1.41421356237309504880f; + static const float pi = 3.14159265358979323846f; + static const float invPi = 1.0f/3.14159265358979323846f; + static const float piHalf = 1.57079632679489661923f; + static const float sqrt2 = 1.41421356237309504880f; + + struct Handness + { + enum Enum + { + Left, + Right, + }; + }; + + struct NearFar + { + enum Enum + { + Default, + Reverse, + }; + }; inline float toRad(float _deg) { @@ -631,7 +649,8 @@ namespace bx mtxLookAtLh(_result, _eye, _at, _up); } - inline void mtxProjRhXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc = false) + template + inline void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc = false) { const float diff = _far-_near; const float aa = _oglNdc ? (_far+_near)/diff : _far/diff; @@ -640,14 +659,15 @@ namespace bx memset(_result, 0, sizeof(float)*16); _result[ 0] = _width; _result[ 5] = _height; - _result[ 8] = _x; - _result[ 9] = _y; - _result[10] = -aa; - _result[11] = -1.0f; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; _result[14] = -bb; } - inline void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) + template + inline void mtxProj_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) { const float invDiffRl = 1.0f/(_rt - _lt); const float invDiffUd = 1.0f/(_ut - _dt); @@ -655,76 +675,197 @@ namespace bx const float height = 2.0f*_near * invDiffUd; const float xx = (_rt + _lt) * invDiffRl; const float yy = (_ut + _dt) * invDiffUd; - mtxProjRhXYWH(_result, xx, yy, width, height, _near, _far, _oglNdc); + mtxProjXYWH(_result, xx, yy, width, height, _near, _far, _oglNdc); } - inline void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) + template + inline void mtxProj_impl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) { - mtxProjRh(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); + mtxProj_impl(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); } - inline void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) + template + inline void mtxProj_impl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) { const float height = 1.0f/tanf(toRad(_fovy)*0.5f); const float width = height * 1.0f/_aspect; - mtxProjRhXYWH(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); - } - - inline void mtxProjLhXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc = false) - { - const float diff = _far-_near; - const float aa = _oglNdc ? (_far+_near)/diff : _far/diff; - const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa; - - memset(_result, 0, sizeof(float)*16); - _result[ 0] = _width; - _result[ 5] = _height; - _result[ 8] = -_x; - _result[ 9] = -_y; - _result[10] = aa; - _result[11] = 1.0f; - _result[14] = -bb; - } - - inline void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) - { - const float invDiffRl = 1.0f/(_rt - _lt); - const float invDiffUd = 1.0f/(_ut - _dt); - const float width = 2.0f*_near * invDiffRl; - const float height = 2.0f*_near * invDiffUd; - const float xx = (_rt + _lt) * invDiffRl; - const float yy = (_ut + _dt) * invDiffUd; - mtxProjLhXYWH(_result, xx, yy, width, height, _near, _far, _oglNdc); - } - - inline void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) - { - mtxProjLh(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); - } - - inline void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) - { - const float height = 1.0f/tanf(toRad(_fovy)*0.5f); - const float width = height * 1.0f/_aspect; - mtxProjLhXYWH(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); + mtxProjXYWH(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); } inline void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) { - mtxProjLh(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + mtxProj_impl(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); } inline void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) { - mtxProjLh(_result, _fov, _near, _far, _oglNdc); + mtxProj_impl(_result, _fov, _near, _far, _oglNdc); } inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) { - mtxProjLh(_result, _fovy, _aspect, _near, _far, _oglNdc); + mtxProj_impl(_result, _fovy, _aspect, _near, _far, _oglNdc); } - inline void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) + inline void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + inline void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _fov, _near, _far, _oglNdc); + } + + inline void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + inline void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + inline void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _fov, _near, _far, _oglNdc); + } + + inline void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc = false) + { + mtxProj_impl(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + template + inline void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc = false) + { + float aa; + float bb; + if (BX_ENABLED(NearFar::Reverse == NearFarT) ) + { + aa = _oglNdc ? -1.0f : 0.0f; + bb = _oglNdc ? -2.0f*_near : -_near; + } + else + { + aa = 1.0f; + bb = _oglNdc ? 2.0f*_near : _near; + } + + memset(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; + _result[14] = -bb; + } + + template + inline void mtxProjInf_impl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + const float invDiffRl = 1.0f/(_rt - _lt); + const float invDiffUd = 1.0f/(_ut - _dt); + const float width = 2.0f*_near * invDiffRl; + const float height = 2.0f*_near * invDiffUd; + const float xx = (_rt + _lt) * invDiffRl; + const float yy = (_ut + _dt) * invDiffUd; + mtxProjInfXYWH(_result, xx, yy, width, height, _near, _oglNdc); + } + + template + inline void mtxProjInf_impl(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc); + } + + template + inline void mtxProjInf_impl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + const float height = 1.0f/tanf(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjInfXYWH(_result, 0.0f, 0.0f, width, height, _near, _oglNdc); + } + + inline void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov, _near, _oglNdc); + } + + inline void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + inline void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fovy, _aspect, _near, _oglNdc); + } + + inline void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + inline void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov, _near, _oglNdc); + } + + inline void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fovy, _aspect, _near, _oglNdc); + } + + inline void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + inline void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov, _near, _oglNdc); + } + + inline void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fovy, _aspect, _near, _oglNdc); + } + + inline void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + inline void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov, _near, _oglNdc); + } + + inline void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fovy, _aspect, _near, _oglNdc); + } + + inline void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + inline void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fov, _near, _oglNdc); + } + + inline void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc = false) + { + mtxProjInf_impl(_result, _fovy, _aspect, _near, _oglNdc); + } + + template + inline void mtxOrtho_impl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) { const float aa = 2.0f/(_right - _left); const float bb = 2.0f/(_top - _bottom); @@ -736,26 +877,7 @@ namespace bx memset(_result, 0, sizeof(float)*16); _result[ 0] = aa; _result[ 5] = bb; - _result[10] = cc; - _result[12] = dd + _offset; - _result[13] = ee; - _result[14] = ff; - _result[15] = 1.0f; - } - - inline void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) - { - const float aa = 2.0f/(_right - _left); - const float bb = 2.0f/(_top - _bottom); - const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near); - const float dd = (_left + _right)/(_left - _right); - const float ee = (_top + _bottom)/(_bottom - _top); - const float ff = _oglNdc ? (_near + _far)/(_near - _far) : _near/(_near - _far); - - memset(_result, 0, sizeof(float)*16); - _result[ 0] = aa; - _result[ 5] = bb; - _result[10] = -cc; + _result[10] = (Handness::Right == HandnessT) ? -cc : cc; _result[12] = dd + _offset; _result[13] = ee; _result[14] = ff; @@ -764,7 +886,17 @@ namespace bx inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) { - return mtxOrthoLh(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + mtxOrtho_impl(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + inline void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) + { + mtxOrtho_impl(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + inline void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset = 0.0f, bool _oglNdc = false) + { + mtxOrtho_impl(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); } inline void mtxRotateX(float* _result, float _ax) diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h index d07e031de34..4ed4752eca7 100644 --- a/3rdparty/bx/include/bx/platform.h +++ b/3rdparty/bx/include/bx/platform.h @@ -28,11 +28,12 @@ #define BX_PLATFORM_XBOX360 0 #define BX_PLATFORM_XBOXONE 0 -#define BX_CPU_ARM 0 -#define BX_CPU_JIT 0 -#define BX_CPU_MIPS 0 -#define BX_CPU_PPC 0 -#define BX_CPU_X86 0 +#define BX_CPU_ARM 0 +#define BX_CPU_JIT 0 +#define BX_CPU_MIPS 0 +#define BX_CPU_PPC 0 +#define BX_CPU_RISCV 0 +#define BX_CPU_X86 0 #define BX_ARCH_32BIT 0 #define BX_ARCH_64BIT 0 @@ -84,6 +85,12 @@ # undef BX_CPU_PPC # define BX_CPU_PPC 1 # define BX_CACHE_LINE_SIZE 128 +#elif defined(__riscv) || \ + defined(__riscv__) || \ + defined(RISCVEL) +# undef BX_CPU_RISCV +# define BX_CPU_RISCV 1 +# define BX_CACHE_LINE_SIZE 64 #elif defined(_M_IX86) || \ defined(_M_X64) || \ defined(__i386__) || \ @@ -103,7 +110,8 @@ defined(__64BIT__) || \ defined(__mips64) || \ defined(__powerpc64__) || \ - defined(__ppc64__) + defined(__ppc64__) || \ + defined(__LP64__) # undef BX_ARCH_64BIT # define BX_ARCH_64BIT 64 #else @@ -171,10 +179,12 @@ // RaspberryPi compiler defines __linux__ # undef BX_PLATFORM_RPI # define BX_PLATFORM_RPI 1 -#elif defined(__linux__) +#elif defined(__linux__) \ + || defined(__riscv__) # undef BX_PLATFORM_LINUX # define BX_PLATFORM_LINUX 1 -#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) +#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \ + || defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) # undef BX_PLATFORM_IOS # define BX_PLATFORM_IOS 1 #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) @@ -183,7 +193,7 @@ # define BX_PLATFORM_OSX __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ # else # define BX_PLATFORM_OSX 1 -# endif // defined(MAC_OS_X_VERSION_MAX_ALLOWED) +# endif // defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) #elif defined(__EMSCRIPTEN__) # undef BX_PLATFORM_EMSCRIPTEN # define BX_PLATFORM_EMSCRIPTEN 1 @@ -283,12 +293,14 @@ #if BX_CPU_ARM # define BX_CPU_NAME "ARM" +#elif BX_CPU_JIT +# define BX_CPU_NAME "JIT-VM" #elif BX_CPU_MIPS # define BX_CPU_NAME "MIPS" #elif BX_CPU_PPC # define BX_CPU_NAME "PowerPC" -#elif BX_CPU_JIT -# define BX_CPU_NAME "JIT-VM" +#elif BX_CPU_RISCV +# define BX_CPU_NAME "RISC-V" #elif BX_CPU_X86 # define BX_CPU_NAME "x86" #endif // BX_CPU_ diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h index 245d158e742..2f1d4f512cf 100644 --- a/3rdparty/bx/include/bx/readerwriter.h +++ b/3rdparty/bx/include/bx/readerwriter.h @@ -230,38 +230,59 @@ namespace bx { }; - struct BX_NO_VTABLE FileReaderI : public ReaderSeekerI + struct BX_NO_VTABLE ReaderOpenI { + virtual ~ReaderOpenI() = 0; virtual bool open(const char* _filePath, Error* _err) = 0; - virtual void close() = 0; }; - struct BX_NO_VTABLE FileWriterI : public WriterSeekerI + inline ReaderOpenI::~ReaderOpenI() { + } + + struct BX_NO_VTABLE WriterOpenI + { + virtual ~WriterOpenI() = 0; virtual bool open(const char* _filePath, bool _append, Error* _err) = 0; + }; + + inline WriterOpenI::~WriterOpenI() + { + } + + struct BX_NO_VTABLE CloserI + { + virtual ~CloserI() = 0; virtual void close() = 0; }; - inline bool open(FileReaderI* _reader, const char* _filePath, Error* _err = NULL) + inline CloserI::~CloserI() + { + } + + struct BX_NO_VTABLE FileReaderI : public ReaderOpenI, public CloserI, public ReaderSeekerI + { + }; + + struct BX_NO_VTABLE FileWriterI : public WriterOpenI, public CloserI, public WriterSeekerI + { + }; + + inline bool open(ReaderOpenI* _reader, const char* _filePath, Error* _err = NULL) { BX_ERROR_USE_TEMP_WHEN_NULL(_err); return _reader->open(_filePath, _err); } - inline void close(FileReaderI* _reader) - { - _reader->close(); - } - - inline bool open(FileWriterI* _writer, const char* _filePath, bool _append = false, Error* _err = NULL) + inline bool open(WriterOpenI* _writer, const char* _filePath, bool _append = false, Error* _err = NULL) { BX_ERROR_USE_TEMP_WHEN_NULL(_err); return _writer->open(_filePath, _append, _err); } - inline void close(FileWriterI* _writer) + inline void close(CloserI* _reader) { - _writer->close(); + _reader->close(); } struct BX_NO_VTABLE MemoryBlockI diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua index e87e5f3b236..4f37458df07 100644 --- a/3rdparty/bx/scripts/toolchain.lua +++ b/3rdparty/bx/scripts/toolchain.lua @@ -37,6 +37,7 @@ function toolchain(_buildDir, _libDir) { "ps4", "PS4" }, { "qnx-arm", "QNX/Blackberry - ARM" }, { "rpi", "RaspberryPi" }, + { "riscv", "RISC-V" }, }, } @@ -336,6 +337,13 @@ function toolchain(_buildDir, _libDir) elseif "rpi" == _OPTIONS["gcc"] then location (path.join(_buildDir, "projects", _ACTION .. "-rpi")) + + elseif "riscv" == _OPTIONS["gcc"] then + premake.gcc.cc = "/opt/riscv/bin/riscv64-unknown-elf-gcc" + premake.gcc.cxx = "/opt/riscv/bin/riscv64-unknown-elf-g++" + premake.gcc.ar = "/opt/riscv/bin/riscv64-unknown-elf-ar" + location (path.join(_buildDir, "projects", _ACTION .. "-riscv")) + end elseif _ACTION == "vs2012" or _ACTION == "vs2013" or _ACTION == "vs2015" then @@ -1128,6 +1136,17 @@ function toolchain(_buildDir, _libDir) "-Wl,--gc-sections", } + configuration { "riscv" } + targetdir (path.join(_buildDir, "riscv/bin")) + objdir (path.join(_buildDir, "riscv/obj")) + buildoptions { + "-Wunused-value", + "-Wundef", + } + buildoptions_cpp { + "-std=c++0x", + } + configuration {} -- reset configuration return true @@ -1191,6 +1210,7 @@ function strip() -- .. "-s EMTERPRETIFY_ASYNC=1 " .. "-s TOTAL_MEMORY=268435456 " -- .. "-s ALLOW_MEMORY_GROWTH=1 " +-- .. "-s USE_WEBGL2=1 " .. "--memory-init-file 1 " .. "\"$(TARGET)\" -o \"$(TARGET)\".html " -- .. "--preload-file ../../../examples/runtime@/" diff --git a/3rdparty/bx/scripts/unittest++.lua b/3rdparty/bx/scripts/unittest++.lua index 3a52b246b3e..cf183c1f2f0 100644 --- a/3rdparty/bx/scripts/unittest++.lua +++ b/3rdparty/bx/scripts/unittest++.lua @@ -15,7 +15,7 @@ project "UnitTest++" "../3rdparty/UnitTest++/src/*.h", } - configuration { "linux or osx or android-* or *nacl* or ps4" } + configuration { "linux or osx or android-* or *nacl* or ps4 or rpi or riscv" } files { "../3rdparty/UnitTest++/src/Posix/**.cpp", "../3rdparty/UnitTest++/src/Posix/**.h", diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie index d938ff91dc5..4ecf8c000ae 100644 Binary files a/3rdparty/bx/tools/bin/darwin/genie and b/3rdparty/bx/tools/bin/darwin/genie differ diff --git a/3rdparty/bx/tools/bin/darwin/ninja b/3rdparty/bx/tools/bin/darwin/ninja new file mode 100644 index 00000000000..64fcacc550c Binary files /dev/null and b/3rdparty/bx/tools/bin/darwin/ninja differ diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie index 1487e071d06..8db245dfb99 100644 Binary files a/3rdparty/bx/tools/bin/linux/genie and b/3rdparty/bx/tools/bin/linux/genie differ diff --git a/3rdparty/bx/tools/bin/linux/ninja b/3rdparty/bx/tools/bin/linux/ninja new file mode 100644 index 00000000000..e4a6202d999 Binary files /dev/null and b/3rdparty/bx/tools/bin/linux/ninja differ diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe index 232485d34fd..0553e86fc45 100644 Binary files a/3rdparty/bx/tools/bin/windows/genie.exe and b/3rdparty/bx/tools/bin/windows/genie.exe differ diff --git a/3rdparty/bx/tools/bin/windows/ninja.exe b/3rdparty/bx/tools/bin/windows/ninja.exe new file mode 100644 index 00000000000..40f662e32ac Binary files /dev/null and b/3rdparty/bx/tools/bin/windows/ninja.exe differ diff --git a/3rdparty/genie/LICENSE b/3rdparty/genie/LICENSE index 5d1f47a5b2c..590c8e5b06a 100644 --- a/3rdparty/genie/LICENSE +++ b/3rdparty/genie/LICENSE @@ -85,3 +85,25 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# profiler.lua + +Lua profiler - Copyright Pepperfish 2002,2003,2004 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to +do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/3rdparty/genie/README.md b/3rdparty/genie/README.md index 63622ccd584..4a2924bee34 100644 --- a/3rdparty/genie/README.md +++ b/3rdparty/genie/README.md @@ -37,7 +37,7 @@ Download (stable) [![Build Status](https://travis-ci.org/bkaradzic/GENie.svg?branch=master)](https://travis-ci.org/bkaradzic/GENie) - version 405 (commit 8f8ab7d903a1495180175784adb7d3b5657c68bb) + version 415 (commit 53635be7264271a6d6c95b059c420251b7eb3280) Linux: https://github.com/bkaradzic/bx/raw/master/tools/bin/linux/genie diff --git a/3rdparty/genie/src/_manifest.lua b/3rdparty/genie/src/_manifest.lua index 75d9b657ffe..b4e0518e3f8 100644 --- a/3rdparty/genie/src/_manifest.lua +++ b/3rdparty/genie/src/_manifest.lua @@ -26,6 +26,7 @@ "base/api.lua", "base/cmdline.lua", "base/inspect.lua", + "base/profiler.lua", "tools/dotnet.lua", "tools/gcc.lua", "tools/ghs.lua", diff --git a/3rdparty/genie/src/_premake_main.lua b/3rdparty/genie/src/_premake_main.lua index fb3d4a89a3d..a48f2cf6fe7 100644 --- a/3rdparty/genie/src/_premake_main.lua +++ b/3rdparty/genie/src/_premake_main.lua @@ -16,28 +16,28 @@ local function injectplatform(platform) if not platform then return true end platform = premake.checkvalue(platform, premake.fields.platforms.allowed) - + for sln in premake.solution.each() do local platforms = sln.platforms or { } - + -- an empty table is equivalent to a native build if #platforms == 0 then table.insert(platforms, "Native") end - + -- the solution must provide a native build in order to support this feature if not table.contains(platforms, "Native") then return false, sln.name .. " does not target native platform\nNative platform settings are required for the --platform feature." end - + -- add it to the end of the list, if it isn't in there already if not table.contains(platforms, platform) then table.insert(platforms, platform) end - + sln.platforms = platforms end - + return true end @@ -46,22 +46,22 @@ -- function _premake_main(scriptpath) - - -- if running off the disk (in debug mode), load everything + + -- if running off the disk (in debug mode), load everything -- listed in _manifest.lua; the list divisions make sure -- everything gets initialized in the proper order. - + if (scriptpath) then local scripts = dofile(scriptpath .. "/_manifest.lua") for _,v in ipairs(scripts) do dofile(scriptpath .. "/" .. v) end end - + -- Now that the scripts are loaded, I can use path.getabsolute() to properly -- canonicalize the executable path. - + _PREMAKE_COMMAND = path.getabsolute(_PREMAKE_COMMAND) @@ -70,15 +70,15 @@ premake.action.set(_ACTION) - + -- Seed the random number generator so actions don't have to do it themselves - + math.randomseed(os.time()) - - + + -- If there is a project script available, run it to get the -- project information, available options and actions, etc. - + if (nil ~= _OPTIONS["file"]) then local fname = _OPTIONS["file"] @@ -96,10 +96,10 @@ end -- Process special options - + if (_OPTIONS["version"] or _OPTIONS["help"] or not _ACTION) then printf("GENie - Project generator tool %s", _GENIE_VERSION_STR) - printf("https://github.com/bkaradzic/genie") + printf("https://github.com/bkaradzic/GENie") if (not _OPTIONS["version"]) then premake.showhelp() end @@ -108,7 +108,7 @@ -- Validate the command-line arguments. This has to happen after the -- script has run to allow for project-specific options - + action = premake.action.current() if (not action) then error("Error: no such action '" .. _ACTION .. "'", 0) @@ -116,28 +116,42 @@ ok, err = premake.option.validate(_OPTIONS) if (not ok) then error("Error: " .. err, 0) end - + -- Sanity check the current project setup ok, err = premake.checktools() if (not ok) then error("Error: " .. err, 0) end - - + + -- If a platform was specified on the command line, inject it now ok, err = injectplatform(_OPTIONS["platform"]) if (not ok) then error("Error: " .. err, 0) end - + local profiler = newProfiler() + if (nil ~= _OPTIONS["debug-profiler"]) then + profiler:start() + end + -- work-in-progress: build the configurations print("Building configurations...") premake.bake.buildconfigs() - + + if (nil ~= _OPTIONS["debug-profiler"]) then + profiler:stop() + + local filePath = path.getabsolute("GENie-profiler-bake.txt") + print("Writing debug-profiler report " .. filePath .. ".") + + local outfile = io.open(filePath, "w+") + profiler:report(outfile) + outfile:close() + end + ok, err = premake.checkprojects() if (not ok) then error("Error: " .. err, 0) end - - + -- Hand over control to the action printf("Running action '%s'...", action.trigger) premake.action.call(action.trigger) @@ -146,4 +160,3 @@ return 0 end - diff --git a/3rdparty/genie/src/base/api.lua b/3rdparty/genie/src/base/api.lua index f784209b677..ccd021981c3 100644 --- a/3rdparty/genie/src/base/api.lua +++ b/3rdparty/genie/src/base/api.lua @@ -1146,3 +1146,13 @@ function newoption(opt) premake.option.add(opt) end + + +-- +-- Enable file level configuration +-- this makes project generation slower for large projects +-- + + function enablefilelevelconfig() + premake._filelevelconfig = true + end diff --git a/3rdparty/genie/src/base/bake.lua b/3rdparty/genie/src/base/bake.lua index ab50612671d..90e7909809d 100644 --- a/3rdparty/genie/src/base/bake.lua +++ b/3rdparty/genie/src/base/bake.lua @@ -728,11 +728,16 @@ -- step of building it later? cfg.__fileconfigs = { } for _, fname in ipairs(cfg.files) do - cfg.terms.required = fname:lower() local fcfg = {} - for _, blk in ipairs(cfg.project.blocks) do - if (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then - mergeobject(fcfg, blk) + + -- Only do this if the script has called enablefilelevelconfig() + if premake._filelevelconfig then + cfg.terms.required = fname:lower() + for _, blk in ipairs(cfg.project.blocks) do + -- BK - `iskeywordsmatch` call is super slow for large projects... + if (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then + mergeobject(fcfg, blk) + end end end diff --git a/3rdparty/genie/src/base/cmdline.lua b/3rdparty/genie/src/base/cmdline.lua index 6e135785a9c..c3357b702ae 100644 --- a/3rdparty/genie/src/base/cmdline.lua +++ b/3rdparty/genie/src/base/cmdline.lua @@ -87,9 +87,14 @@ description = "Search for additional scripts on the given path" } + newoption + { + trigger = "debug-profiler", + description = "GENie script generation profiler." + } + newoption { trigger = "version", description = "Display version information" } - diff --git a/3rdparty/genie/src/base/globals.lua b/3rdparty/genie/src/base/globals.lua index 9e1182d96fe..5a04172c481 100644 --- a/3rdparty/genie/src/base/globals.lua +++ b/3rdparty/genie/src/base/globals.lua @@ -71,7 +71,6 @@ { cfgsuffix = "orbis", iscrosscompiler = true, - nosharedlibs = true, -- @thendrix, Fix this to allow SPRXs namestyle = "Orbis", }, Durango = diff --git a/3rdparty/genie/src/base/premake.lua b/3rdparty/genie/src/base/premake.lua index feeb6bd7240..b27790cbbcc 100644 --- a/3rdparty/genie/src/base/premake.lua +++ b/3rdparty/genie/src/base/premake.lua @@ -4,6 +4,7 @@ -- Copyright (c) 2002-2009 Jason Perkins and the Premake project -- + premake._filelevelconfig = false -- -- Open a file for output, and call a function to actually do the writing. @@ -70,4 +71,4 @@ end return nil, nil - end \ No newline at end of file + end diff --git a/3rdparty/genie/src/base/profiler.lua b/3rdparty/genie/src/base/profiler.lua new file mode 100644 index 00000000000..0fbea437f48 --- /dev/null +++ b/3rdparty/genie/src/base/profiler.lua @@ -0,0 +1,613 @@ +-- +-- http://lua-users.org/wiki/PepperfishProfiler +-- +-- == Introduction == +-- +-- Note that this requires os.clock(), debug.sethook(), +-- and debug.getinfo() or your equivalent replacements to +-- be available if this is an embedded application. +-- +-- Example usage: +-- +-- profiler = newProfiler() +-- profiler:start() +-- +-- < call some functions that take time > +-- +-- profiler:stop() +-- +-- local outfile = io.open( "profile.txt", "w+" ) +-- profiler:report( outfile ) +-- outfile:close() +-- +-- == Optionally choosing profiling method == +-- +-- The rest of this comment can be ignored if you merely want a good profiler. +-- +-- newProfiler(method, sampledelay): +-- +-- If method is omitted or "time", will profile based on real performance. +-- optionally, frequency can be provided to control the number of opcodes +-- per profiling tick. By default this is 100000, which (on my system) provides +-- one tick approximately every 2ms and reduces system performance by about 10%. +-- This can be reduced to increase accuracy at the cost of performance, or +-- increased for the opposite effect. +-- +-- If method is "call", will profile based on function calls. Frequency is +-- ignored. +-- +-- +-- "time" may bias profiling somewhat towards large areas with "simple opcodes", +-- as the profiling function (which introduces a certain amount of unavoidable +-- overhead) will be called more often. This can be minimized by using a larger +-- sample delay - the default should leave any error largely overshadowed by +-- statistical noise. With a delay of 1000 I was able to achieve inaccuray of +-- approximately 25%. Increasing the delay to 100000 left inaccuracy below my +-- testing error. +-- +-- "call" may bias profiling heavily towards areas with many function calls. +-- Testing found a degenerate case giving a figure inaccurate by approximately +-- 20,000%. (Yes, a multiple of 200.) This is, however, more directly comparable +-- to common profilers (such as gprof) and also gives accurate function call +-- counts, which cannot be retrieved from "time". +-- +-- I strongly recommend "time" mode, and it is now the default. +-- +-- == History == +-- +-- 2008-09-16 - Time-based profiling and conversion to Lua 5.1 +-- by Ben Wilhelm ( zorba-pepperfish@pavlovian.net ). +-- Added the ability to optionally choose profiling methods, along with a new +-- profiling method. +-- +-- Converted to Lua 5, a few improvements, and +-- additional documentation by Tom Spilman ( tom@sickheadgames.com ) +-- +-- Additional corrections and tidying by original author +-- Daniel Silverstone ( dsilvers@pepperfish.net ) +-- +-- == Status == +-- +-- Daniel Silverstone is no longer using this code, and judging by how long it's +-- been waiting for Lua 5.1 support, I don't think Tom Spilman is either. I'm +-- perfectly willing to take on maintenance, so if you have problems or +-- questions, go ahead and email me :) +-- -- Ben Wilhelm ( zorba-pepperfish@pavlovian.net ) ' +-- +-- == Copyright == +-- +-- Lua profiler - Copyright Pepperfish 2002,2003,2004 +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and associated documentation files (the "Software"), to +-- deal in the Software without restriction, including without limitation the +-- rights to use, copy, modify, merge, publish, distribute, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to +-- do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +-- IN THE SOFTWARE. +-- + +-- +-- All profiler related stuff is stored in the top level table '_profiler' +-- +_profiler = {} + + +-- +-- newProfiler() creates a new profiler object for managing +-- the profiler and storing state. Note that only one profiler +-- object can be executing at one time. +-- +function newProfiler(variant, sampledelay) + if _profiler.running then + print("Profiler already running.") + return + end + + variant = variant or "time" + + if variant ~= "time" and variant ~= "call" then + print("Profiler method must be 'time' or 'call'.") + return + end + + local newprof = {} + for k,v in pairs(_profiler) do + newprof[k] = v + end + newprof.variant = variant + newprof.sampledelay = sampledelay or 100000 + return newprof +end + + +-- +-- This function starts the profiler. It will do nothing +-- if this (or any other) profiler is already running. +-- +function _profiler.start(self) + if _profiler.running then + return + end + -- Start the profiler. This begins by setting up internal profiler state + _profiler.running = self + self.rawstats = {} + self.callstack = {} + if self.variant == "time" then + self.lastclock = os.clock() + debug.sethook( _profiler_hook_wrapper_by_time, "", self.sampledelay ) + elseif self.variant == "call" then + debug.sethook( _profiler_hook_wrapper_by_call, "cr" ) + else + print("Profiler method must be 'time' or 'call'.") + sys.exit(1) + end +end + + +-- +-- This function stops the profiler. It will do nothing +-- if a profiler is not running, and nothing if it isn't +-- the currently running profiler. +-- +function _profiler.stop(self) + if _profiler.running ~= self then + return + end + -- Stop the profiler. + debug.sethook( nil ) + _profiler.running = nil +end + + +-- +-- Simple wrapper to handle the hook. You should not +-- be calling this directly. Duplicated to reduce overhead. +-- +function _profiler_hook_wrapper_by_call(action) + if _profiler.running == nil then + debug.sethook( nil ) + end + _profiler.running:_internal_profile_by_call(action) +end +function _profiler_hook_wrapper_by_time(action) + if _profiler.running == nil then + debug.sethook( nil ) + end + _profiler.running:_internal_profile_by_time(action) +end + + +-- +-- This is the main by-function-call function of the profiler and should not +-- be called except by the hook wrapper +-- +function _profiler._internal_profile_by_call(self,action) + -- Since we can obtain the 'function' for the item we've had call us, we + -- can use that... + local caller_info = debug.getinfo( 3 ) + if caller_info == nil then + print "No caller_info" + return + end + + --SHG_LOG("[_profiler._internal_profile] "..(caller_info.name or "")) + + -- Retrieve the most recent activation record... + local latest_ar = nil + if table.getn(self.callstack) > 0 then + latest_ar = self.callstack[table.getn(self.callstack)] + end + + -- Are we allowed to profile this function? + local should_not_profile = 0 + for k,v in pairs(self.prevented_functions) do + if k == caller_info.func then + should_not_profile = v + end + end + -- Also check the top activation record... + if latest_ar then + if latest_ar.should_not_profile == 2 then + should_not_profile = 2 + end + end + + -- Now then, are we in 'call' or 'return' ? + -- print("Profile:", caller_info.name, "SNP:", should_not_profile, + -- "Action:", action ) + if action == "call" then + -- Making a call... + local this_ar = {} + this_ar.should_not_profile = should_not_profile + this_ar.parent_ar = latest_ar + this_ar.anon_child = 0 + this_ar.name_child = 0 + this_ar.children = {} + this_ar.children_time = {} + this_ar.clock_start = os.clock() + -- Last thing to do on a call is to insert this onto the ar stack... + table.insert( self.callstack, this_ar ) + else + local this_ar = latest_ar + if this_ar == nil then + return -- No point in doing anything if no upper activation record + end + + -- Right, calculate the time in this function... + this_ar.clock_end = os.clock() + this_ar.this_time = this_ar.clock_end - this_ar.clock_start + + -- Now, if we have a parent, update its call info... + if this_ar.parent_ar then + this_ar.parent_ar.children[caller_info.func] = + (this_ar.parent_ar.children[caller_info.func] or 0) + 1 + this_ar.parent_ar.children_time[caller_info.func] = + (this_ar.parent_ar.children_time[caller_info.func] or 0 ) + + this_ar.this_time + if caller_info.name == nil then + this_ar.parent_ar.anon_child = + this_ar.parent_ar.anon_child + this_ar.this_time + else + this_ar.parent_ar.name_child = + this_ar.parent_ar.name_child + this_ar.this_time + end + end + -- Now if we're meant to record information about ourselves, do so... + if this_ar.should_not_profile == 0 then + local inforec = self:_get_func_rec(caller_info.func,1) + inforec.count = inforec.count + 1 + inforec.time = inforec.time + this_ar.this_time + inforec.anon_child_time = inforec.anon_child_time + this_ar.anon_child + inforec.name_child_time = inforec.name_child_time + this_ar.name_child + inforec.func_info = caller_info + for k,v in pairs(this_ar.children) do + inforec.children[k] = (inforec.children[k] or 0) + v + inforec.children_time[k] = + (inforec.children_time[k] or 0) + this_ar.children_time[k] + end + end + + -- Last thing to do on return is to drop the last activation record... + table.remove( self.callstack, table.getn( self.callstack ) ) + end +end + + +-- +-- This is the main by-time internal function of the profiler and should not +-- be called except by the hook wrapper +-- +function _profiler._internal_profile_by_time(self,action) + -- we do this first so we add the minimum amount of extra time to this call + local timetaken = os.clock() - self.lastclock + + local depth = 3 + local at_top = true + local last_caller + local caller = debug.getinfo(depth) + while caller do + if not caller.func then caller.func = "(tail call)" end + if self.prevented_functions[caller.func] == nil then + local info = self:_get_func_rec(caller.func, 1, caller) + info.count = info.count + 1 + info.time = info.time + timetaken + if last_caller then + -- we're not the head, so update the "children" times also + if last_caller.name then + info.name_child_time = info.name_child_time + timetaken + else + info.anon_child_time = info.anon_child_time + timetaken + end + info.children[last_caller.func] = + (info.children[last_caller.func] or 0) + 1 + info.children_time[last_caller.func] = + (info.children_time[last_caller.func] or 0) + timetaken + end + end + depth = depth + 1 + last_caller = caller + caller = debug.getinfo(depth) + end + + self.lastclock = os.clock() +end + + +-- +-- This returns a (possibly empty) function record for +-- the specified function. It is for internal profiler use. +-- +function _profiler._get_func_rec(self,func,force,info) + -- Find the function ref for 'func' (if force and not present, create one) + local ret = self.rawstats[func] + if ret == nil and force ~= 1 then + return nil + end + if ret == nil then + -- Build a new function statistics table + ret = {} + ret.func = func + ret.count = 0 + ret.time = 0 + ret.anon_child_time = 0 + ret.name_child_time = 0 + ret.children = {} + ret.children_time = {} + ret.func_info = info + self.rawstats[func] = ret + end + return ret +end + + +-- +-- This writes a profile report to the output file object. If +-- sort_by_total_time is nil or false the output is sorted by +-- the function time minus the time in it's children. +-- +function _profiler.report( self, outfile, sort_by_total_time ) + + outfile:write + [[Lua Profile output created by profiler.lua. Copyright Pepperfish 2002+ + + ]] + + -- This is pretty awful. + local terms = {} + if self.variant == "time" then + terms.capitalized = "Sample" + terms.single = "sample" + terms.pastverb = "sampled" + elseif self.variant == "call" then + terms.capitalized = "Call" + terms.single = "call" + terms.pastverb = "called" + else + assert(false) + end + + local total_time = 0 + local ordering = {} + for func,record in pairs(self.rawstats) do + table.insert(ordering, func) + end + + if sort_by_total_time then + table.sort( ordering, + function(a,b) return self.rawstats[a].time > self.rawstats[b].time end + ) + else + table.sort( ordering, + function(a,b) + local arec = self.rawstats[a] + local brec = self.rawstats[b] + local atime = arec.time - (arec.anon_child_time + arec.name_child_time) + local btime = brec.time - (brec.anon_child_time + brec.name_child_time) + return atime > btime + end + ) + end + + for i=1,#ordering do + local func = ordering[i] + local record = self.rawstats[func] + local thisfuncname = " " .. self:_pretty_name(func) .. " " + if string.len( thisfuncname ) < 42 then + thisfuncname = string.rep( "-", math.floor((42 - string.len(thisfuncname))/2) ) .. thisfuncname + thisfuncname = thisfuncname .. string.rep( "-", 42 - string.len(thisfuncname) ) + end + + total_time = total_time + ( record.time - ( record.anon_child_time + + record.name_child_time ) ) + outfile:write( string.rep( "-", 19 ) .. thisfuncname .. + string.rep( "-", 19 ) .. "\n" ) + outfile:write( terms.capitalized.." count: " .. + string.format( "%4d", record.count ) .. "\n" ) + outfile:write( "Time spend total: " .. + string.format( "%4.3f", record.time ) .. "s\n" ) + outfile:write( "Time spent in children: " .. + string.format("%4.3f",record.anon_child_time+record.name_child_time) .. + "s\n" ) + local timeinself = + record.time - (record.anon_child_time + record.name_child_time) + outfile:write( "Time spent in self: " .. + string.format("%4.3f", timeinself) .. "s\n" ) + outfile:write( "Time spent per " .. terms.single .. ": " .. + string.format("%4.5f", record.time/record.count) .. + "s/" .. terms.single .. "\n" ) + outfile:write( "Time spent in self per "..terms.single..": " .. + string.format( "%4.5f", timeinself/record.count ) .. "s/" .. + terms.single.."\n" ) + + -- Report on each child in the form + -- Child called n times and took a.bs + local added_blank = 0 + for k,v in pairs(record.children) do + if self.prevented_functions[k] == nil or + self.prevented_functions[k] == 0 + then + if added_blank == 0 then + outfile:write( "\n" ) -- extra separation line + added_blank = 1 + end + outfile:write( "Child " .. self:_pretty_name(k) .. + string.rep( " ", 41-string.len(self:_pretty_name(k)) ) .. " " .. + terms.pastverb.." " .. string.format("%6d", v) ) + outfile:write( " times. Took " .. + string.format("%4.2f", record.children_time[k] ) .. "s\n" ) + end + end + + outfile:write( "\n" ) -- extra separation line + outfile:flush() + end + outfile:write( "\n\n" ) + outfile:write( "Total time spent in profiled functions: " .. + string.format("%5.3g",total_time) .. "s\n" ) + outfile:write( [[ + + END + ]] ) + outfile:flush() +end + + +-- +-- This writes the profile to the output file object as +-- loadable Lua source. +-- +function _profiler.lua_report(self,outfile) + -- Purpose: Write out the entire raw state in a cross-referenceable form. + local ordering = {} + local functonum = {} + for func,record in pairs(self.rawstats) do + table.insert(ordering, func) + functonum[func] = table.getn(ordering) + end + + outfile:write( + "-- Profile generated by profiler.lua Copyright Pepperfish 2002+\n\n" ) + outfile:write( "-- Function names\nfuncnames = {}\n" ) + for i=1,table.getn(ordering) do + local thisfunc = ordering[i] + outfile:write( "funcnames[" .. i .. "] = " .. + string.format("%q", self:_pretty_name(thisfunc)) .. "\n" ) + end + outfile:write( "\n" ) + outfile:write( "-- Function times\nfunctimes = {}\n" ) + for i=1,table.getn(ordering) do + local thisfunc = ordering[i] + local record = self.rawstats[thisfunc] + outfile:write( "functimes[" .. i .. "] = { " ) + outfile:write( "tot=" .. record.time .. ", " ) + outfile:write( "achild=" .. record.anon_child_time .. ", " ) + outfile:write( "nchild=" .. record.name_child_time .. ", " ) + outfile:write( "count=" .. record.count .. " }\n" ) + end + outfile:write( "\n" ) + outfile:write( "-- Child links\nchildren = {}\n" ) + for i=1,table.getn(ordering) do + local thisfunc = ordering[i] + local record = self.rawstats[thisfunc] + outfile:write( "children[" .. i .. "] = { " ) + for k,v in pairs(record.children) do + if functonum[k] then -- non-recorded functions will be ignored now + outfile:write( functonum[k] .. ", " ) + end + end + outfile:write( "}\n" ) + end + outfile:write( "\n" ) + outfile:write( "-- Child call counts\nchildcounts = {}\n" ) + for i=1,table.getn(ordering) do + local thisfunc = ordering[i] + local record = self.rawstats[thisfunc] + outfile:write( "children[" .. i .. "] = { " ) + for k,v in record.children do + if functonum[k] then -- non-recorded functions will be ignored now + outfile:write( v .. ", " ) + end + end + outfile:write( "}\n" ) + end + outfile:write( "\n" ) + outfile:write( "-- Child call time\nchildtimes = {}\n" ) + for i=1,table.getn(ordering) do + local thisfunc = ordering[i] + local record = self.rawstats[thisfunc]; + outfile:write( "children[" .. i .. "] = { " ) + for k,v in pairs(record.children) do + if functonum[k] then -- non-recorded functions will be ignored now + outfile:write( record.children_time[k] .. ", " ) + end + end + outfile:write( "}\n" ) + end + outfile:write( "\n\n-- That is all.\n\n" ) + outfile:flush() +end + +-- Internal function to calculate a pretty name for the profile output +function _profiler._pretty_name(self,func) + + -- Only the data collected during the actual + -- run seems to be correct.... why? + local info = self.rawstats[ func ].func_info + -- local info = debug.getinfo( func ) + + local name = "" + if info.what == "Lua" then + name = "L:" + end + if info.what == "C" then + name = "C:" + end + if info.what == "main" then + name = " :" + end + + if info.name == nil then + name = name .. "<"..tostring(func) .. ">" + else + name = name .. info.name + end + + if info.source then + name = name .. "@" .. info.source + else + if info.what == "C" then + name = name .. "@?" + else + name = name .. "@" + end + end + name = name .. ":" + if info.what == "C" then + name = name .. "?" + else + name = name .. info.linedefined + end + + return name +end + + +-- +-- This allows you to specify functions which you do +-- not want profiled. Setting level to 1 keeps the +-- function from being profiled. Setting level to 2 +-- keeps both the function and its children from +-- being profiled. +-- +-- BUG: 2 will probably act exactly like 1 in "time" mode. +-- If anyone cares, let me (zorba) know and it can be fixed. +-- +function _profiler.prevent(self, func, level) + self.prevented_functions[func] = (level or 1) +end + + +_profiler.prevented_functions = { + [_profiler.start] = 2, + [_profiler.stop] = 2, + [_profiler._internal_profile_by_time] = 2, + [_profiler._internal_profile_by_call] = 2, + [_profiler_hook_wrapper_by_time] = 2, + [_profiler_hook_wrapper_by_call] = 2, + [_profiler.prevent] = 2, + [_profiler._get_func_rec] = 2, + [_profiler.report] = 2, + [_profiler.lua_report] = 2, + [_profiler._pretty_name] = 2 +} diff --git a/3rdparty/genie/src/base/project.lua b/3rdparty/genie/src/base/project.lua index 5806757f532..76d41996453 100644 --- a/3rdparty/genie/src/base/project.lua +++ b/3rdparty/genie/src/base/project.lua @@ -529,6 +529,8 @@ elseif kind == "StaticLib" then prefix = "lib" ext = ".a" + elseif kind == "SharedLib" then + ext = ".prx" end end diff --git a/3rdparty/genie/src/host/scripts.c b/3rdparty/genie/src/host/scripts.c index bb67db9cada..47814bb1e95 100644 --- a/3rdparty/genie/src/host/scripts.c +++ b/3rdparty/genie/src/host/scripts.c @@ -28,9 +28,8 @@ const char* builtin_scripts[] = { "function io.capture()\nio.captured = ''\nend\nfunction io.endcapture()\nlocal captured = io.captured\nio.captured = nil\nreturn captured\nend\nlocal builtin_open = io.open\nfunction io.open(fname, mode)\nif (mode) then\nif (mode:find(\"w\")) then\nlocal dir = path.getdirectory(fname)\nok, err = os.mkdir(dir)\nif (not ok) then\nerror(err, 0)\nend\nend\nend\nreturn builtin_open(fname, mode)\nend\nfunction io.printf(msg, ...)\nlocal arg={...}\nif not io.eol then\nio.eol = \"\\n\"\nend\nif not io.indent then\nio.indent = \"\\t\"\nend\nif type(msg) == \"number\" then\ns = string.rep(io.indent, msg) .. string.format(table.unpack(arg))\nelse\ns = string.format(msg, table.unpack(arg))\nend\nif io.captured then\nio.captured = io.captured .. s .. io.eol\nelse\nio.write(s)\nio.write(io.eol)\nend\nend\n_p = io.printf\n", /* base/globals.lua */ - "premake = { }\npremake.platforms =\n{\nNative =\n{\ncfgsuffix = \"\",\n},\nx32 =\n{\ncfgsuffix = \"32\",\n},\nx64 =\n{\ncfgsuffix = \"64\",\n},\nUniversal =\n{\ncfgsuffix = \"univ\",\n},\nUniversal32 =\n{\ncfgsuffix = \"univ32\",\n},\nUniversal64 =\n{\ncfgsuffix = \"univ64\",\n},\nPS3 =\n{\ncfgsuffix = \"ps3\",\niscrosscompiler = true,\nnosharedlibs = true,\nnamestyle = \"PS3\",\n},\nWiiDev =\n{\ncfgsuffix = \"wii\",\niscrosscompiler = true,\nnamestyle = \"PS3\",\n},\nXbox360 =\n{\ncfgsuffix = \"xbox360\",\niscrosscompiler = true,\nnamestyle = \"windows\",\n},\nPowerPC =\n{\ncfgsuffix = \"ppc\",\niscrosscompiler = true,\n},\nARM =\n{\ncfgsuffix = \"ARM\",\niscrosscompiler = true,\n},\nOrbis =\n{\ncfgsuffix = \"orbis\",\niscrosscompiler = true,\nnosharedlibs = true, -- @thendrix, Fix this to allow SPRXs\nnamestyle = \"Orbis\",\n},\nDurango =\n{\ncfgsuffix = \"durango\",\niscrosscompiler = true,\nnoshared" - "libs = true,\nnamestyle = \"windows\",\n},\n}\nlocal builtin_dofile = dofile\nfunction dofile(fname)\nlocal oldcwd = os.getcwd()\nlocal oldfile = _SCRIPT\nif (not os.isfile(fname)) then\nlocal path = os.pathsearch(fname, _OPTIONS[\"scripts\"], os.getenv(\"PREMAKE_PATH\"))\nif (path) then\nfname = path..\"/\"..fname\nend\nend\n_SCRIPT = path.getabsolute(fname)\nlocal newcwd = path.getdirectory(_SCRIPT)\nos.chdir(newcwd)\nlocal a, b, c, d, e, f = builtin_dofile(_SCRIPT)\n_SCRIPT = oldfile\nos.chdir(oldcwd)\nreturn a, b, c, d, e, f\nend\nfunction iif(expr, trueval, falseval)\nif (expr) then\nreturn trueval\nelse\nreturn falseval\nend\nend\nfunction include(fname)\nlocal dir, name = premake.findDefaultScript(fname, false)\nif dir ~= nil then\nreturn dofile(dir .. \"/\" .. name)\nend\nreturn nil\nend\nfunction printf(msg, ...)\nlocal arg={...}\nprint(string.format(msg, table.unpack(arg)))\nend\nlocal builtin_type = type\nfunction type(t)\nlocal mt = getmetatable(t)\nif (mt) then\nif (mt.__type) then\nretur" - "n mt.__type\nend\nend\nreturn builtin_type(t)\nend\n", + "premake = { }\npremake.platforms =\n{\nNative =\n{\ncfgsuffix = \"\",\n},\nx32 =\n{\ncfgsuffix = \"32\",\n},\nx64 =\n{\ncfgsuffix = \"64\",\n},\nUniversal =\n{\ncfgsuffix = \"univ\",\n},\nUniversal32 =\n{\ncfgsuffix = \"univ32\",\n},\nUniversal64 =\n{\ncfgsuffix = \"univ64\",\n},\nPS3 =\n{\ncfgsuffix = \"ps3\",\niscrosscompiler = true,\nnosharedlibs = true,\nnamestyle = \"PS3\",\n},\nWiiDev =\n{\ncfgsuffix = \"wii\",\niscrosscompiler = true,\nnamestyle = \"PS3\",\n},\nXbox360 =\n{\ncfgsuffix = \"xbox360\",\niscrosscompiler = true,\nnamestyle = \"windows\",\n},\nPowerPC =\n{\ncfgsuffix = \"ppc\",\niscrosscompiler = true,\n},\nARM =\n{\ncfgsuffix = \"ARM\",\niscrosscompiler = true,\n},\nOrbis =\n{\ncfgsuffix = \"orbis\",\niscrosscompiler = true,\nnamestyle = \"Orbis\",\n},\nDurango =\n{\ncfgsuffix = \"durango\",\niscrosscompiler = true,\nnosharedlibs = true,\nnamestyle = \"windows\",\n},\n}\nlocal bu" + "iltin_dofile = dofile\nfunction dofile(fname)\nlocal oldcwd = os.getcwd()\nlocal oldfile = _SCRIPT\nif (not os.isfile(fname)) then\nlocal path = os.pathsearch(fname, _OPTIONS[\"scripts\"], os.getenv(\"PREMAKE_PATH\"))\nif (path) then\nfname = path..\"/\"..fname\nend\nend\n_SCRIPT = path.getabsolute(fname)\nlocal newcwd = path.getdirectory(_SCRIPT)\nos.chdir(newcwd)\nlocal a, b, c, d, e, f = builtin_dofile(_SCRIPT)\n_SCRIPT = oldfile\nos.chdir(oldcwd)\nreturn a, b, c, d, e, f\nend\nfunction iif(expr, trueval, falseval)\nif (expr) then\nreturn trueval\nelse\nreturn falseval\nend\nend\nfunction include(fname)\nlocal dir, name = premake.findDefaultScript(fname, false)\nif dir ~= nil then\nreturn dofile(dir .. \"/\" .. name)\nend\nreturn nil\nend\nfunction printf(msg, ...)\nlocal arg={...}\nprint(string.format(msg, table.unpack(arg)))\nend\nlocal builtin_type = type\nfunction type(t)\nlocal mt = getmetatable(t)\nif (mt) then\nif (mt.__type) then\nreturn mt.__type\nend\nend\nreturn builtin_type(t)\nend\n", /* base/action.lua */ "premake.action = { }\npremake.action.list = { }\nfunction premake.action.add(a)\nlocal missing\nfor _, field in ipairs({\"description\", \"trigger\"}) do\nif (not a[field]) then\nmissing = field\nend\nend\nif (missing) then\nerror(\"action needs a \" .. missing, 3)\nend\npremake.action.list[a.trigger] = a\nend\nfunction premake.action.call(name)\nlocal a = premake.action.list[name]\nfor sln in premake.solution.each() do\nif a.onsolution then\na.onsolution(sln)\nend\nfor prj in premake.solution.eachproject(sln) do\nif a.onproject then\na.onproject(prj)\nend\nend\nend\nif a.execute then\na.execute()\nend\nend\nfunction premake.action.current()\nreturn premake.action.get(_ACTION)\nend\nfunction premake.action.get(name)\nreturn premake.action.list[name]\nend\nfunction premake.action.each()\nlocal keys = { }\nfor _, action in pairs(premake.action.list) do\ntable.insert(keys, action.trigger)\nend\ntable.sort(keys)\nlocal i = 0\nreturn function()\ni = i + 1\nreturn premake.action.list[keys[i]]\nend\nend\nfunction pre" @@ -57,9 +56,9 @@ const char* builtin_scripts[] = { "fig(prj, cfgname, cfg.platform)\nif kind == \"dependencies\" or canlink(cfg, prjcfg) then\nif (part == \"directory\") then\nitem = path.rebase(prjcfg.linktarget.directory, prjcfg.location, cfg.location)\nelseif (part == \"basename\") then\nitem = prjcfg.linktarget.basename\nelseif (part == \"fullpath\") then\nitem = path.rebase(prjcfg.linktarget.fullpath, prjcfg.location, cfg.location)\nelseif (part == \"object\") then\nitem = prjcfg\nend\nend\nelseif not prj and (kind == \"system\" or kind == \"all\") then\nif (part == \"directory\") then\nitem = path.getdirectory(link)\nelseif (part == \"fullpath\") then\nitem = link\nif namestyle == \"windows\" then\nif premake.iscppproject(cfg) then\nitem = item .. \".lib\"\nelseif premake.isdotnetproject(cfg) then\nitem = item .. \".dll\"\nend\nend\nelseif part == \"name\" then\nitem = path.getname(link)\nelseif part == \"basename\" then\nitem = path.getbasename(link)\nelse\nitem = link\nend\nif item:find(\"/\", nil, true) then\nitem = path.getrelative(cfg.project.locatio" "n, item)\nend\nend\nif item then\nif pathstyle == \"windows\" and part ~= \"object\" then\nitem = path.translate(item, \"\\\\\")\nend\nif not table.contains(result, item) then\ntable.insert(result, item)\nend\nend\nend\nreturn result\nend\nfunction premake.getnamestyle(cfg)\nreturn premake.platforms[cfg.platform].namestyle or premake.gettool(cfg).namestyle or \"posix\"\nend\nfunction premake.getpathstyle(cfg)\nif premake.action.current().os == \"windows\" then\nreturn \"windows\"\nelse\nreturn \"posix\"\nend\nend\nfunction premake.gettarget(cfg, direction, pathstyle, namestyle, system)\nif system == \"bsd\" then\nsystem = \"linux\"\nend\nlocal kind = cfg.kind\nif premake.iscppproject(cfg) then\nif (namestyle == \"windows\" or system == \"windows\")\nand kind == \"SharedLib\" and direction == \"link\"\nand not cfg.flags.NoImportLib\nthen\nkind = \"StaticLib\"\nend\nif namestyle == \"posix\" and system == \"windows\" and kind ~= \"StaticLib\" then\nnamestyle = \"windows\"\nend\nend\nlocal field = \"build\"\nif" " direction == \"link\" and cfg.kind == \"SharedLib\" then\nfield = \"implib\"\nend\nlocal name = cfg[field..\"name\"] or cfg.targetname or cfg.project.name\nlocal dir = cfg[field..\"dir\"] or cfg.targetdir or path.getrelative(cfg.location, cfg.basedir)\nlocal subdir = cfg[field..\"subdir\"] or cfg.targetsubdir or \".\"\nlocal prefix = \"\"\nlocal suffix = \"\"\nlocal ext = \"\"\nlocal bundlepath, bundlename\ndir = path.join(dir, subdir)\nif namestyle == \"windows\" then\nif kind == \"ConsoleApp\" or kind == \"WindowedApp\" then\next = \".exe\"\nelseif kind == \"SharedLib\" then\next = \".dll\"\nelseif kind == \"StaticLib\" then\next = \".lib\"\nend\nelseif namestyle == \"posix\" then\nif kind == \"WindowedApp\" and system == \"macosx\" then\nbundlename = name .. \".app\"\nbundlepath = path.join(dir, bundlename)\ndir = path.join(bundlepath, \"Contents/MacOS\")\nelseif (kind == \"ConsoleApp\" or kind == \"WindowedApp\") and system == \"os2\" then\next = \".exe\"\nelseif kind == \"SharedLib\" then\n" - "prefix = \"lib\"\next = iif(system == \"macosx\", \".dylib\", \".so\")\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nend\nelseif namestyle == \"PS3\" then\nif kind == \"ConsoleApp\" or kind == \"WindowedApp\" then\next = \".elf\"\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nend\nelseif namestyle == \"Orbis\" then\nif kind == \"ConsoleApp\" or kind == \"WindowedApp\" then\next = \".elf\"\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nend\nend\nprefix = cfg[field..\"prefix\"] or cfg.targetprefix or prefix\nsuffix = cfg[field..\"suffix\"] or cfg.targetsuffix or suffix\next = cfg[field..\"extension\"] or cfg.targetextension or ext\nlocal result = { }\nresult.basename = name .. suffix\nresult.name = prefix .. name .. suffix .. ext\nresult.directory = dir\nresult.subdirectory = subdir\nresult.prefix = prefix\nresult.suffix = suffix\nresult.fullpath = path.join(result.directory, result.name)\nresult.bundlepath = bund" - "lepath or result.fullpath\nif pathstyle == \"windows\" then\nresult.directory = path.translate(result.directory, \"\\\\\")\nresult.subdirectory = path.translate(result.subdirectory, \"\\\\\")\nresult.fullpath = path.translate(result.fullpath, \"\\\\\")\nend\nreturn result\nend\nfunction premake.gettool(cfg)\nif premake.iscppproject(cfg) then\nif _OPTIONS.cc then\nreturn premake[_OPTIONS.cc]\nend\nlocal action = premake.action.current()\nif action.valid_tools then\nreturn premake[action.valid_tools.cc[1]]\nend\nreturn premake.gcc\nelse\nreturn premake.dotnet\nend\nend\nfunction premake.project.getvpath(prj, abspath)\nlocal vpath = abspath\nlocal fname = path.getname(abspath)\nlocal max = abspath:len() - fname:len()\nfor replacement, patterns in pairs(prj.vpaths or {}) do\nfor _, pattern in ipairs(patterns) do\nlocal i = abspath:find(path.wildcards(pattern))\nif i == 1 then\ni = pattern:find(\"*\", 1, true) or (pattern:len() + 1)\nlocal leaf\nif i < max then\nleaf = abspath:sub(i)\nelse\nleaf = fname\nen" - "d\nif leaf:startswith(\"/\") then\nleaf = leaf:sub(2)\nend\nlocal stem = \"\"\nif replacement:len() > 0 then\nstem, stars = replacement:gsub(\"%*\", \"\")\nif stars == 0 then\nleaf = path.getname(leaf)\nend\nelse\nleaf = path.getname(leaf)\nend\nvpath = path.join(stem, leaf)\nend\nend\nend\nreturn path.trimdots(vpath)\nend\nfunction premake.hascppproject(sln)\nfor prj in premake.solution.eachproject(sln) do\nif premake.iscppproject(prj) then\nreturn true\nend\nend\nend\nfunction premake.hasdotnetproject(sln)\nfor prj in premake.solution.eachproject(sln) do\nif premake.isdotnetproject(prj) then\nreturn true\nend\nend\nend\nfunction premake.project.iscproject(prj)\nreturn prj.language == \"C\"\nend\nfunction premake.iscppproject(prj)\nreturn (prj.language == \"C\" or prj.language == \"C++\")\nend\nfunction premake.isdotnetproject(prj)\nreturn (prj.language == \"C#\")\nend\n", + "prefix = \"lib\"\next = iif(system == \"macosx\", \".dylib\", \".so\")\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nend\nelseif namestyle == \"PS3\" then\nif kind == \"ConsoleApp\" or kind == \"WindowedApp\" then\next = \".elf\"\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nend\nelseif namestyle == \"Orbis\" then\nif kind == \"ConsoleApp\" or kind == \"WindowedApp\" then\next = \".elf\"\nelseif kind == \"StaticLib\" then\nprefix = \"lib\"\next = \".a\"\nelseif kind == \"SharedLib\" then\next = \".prx\"\nend\nend\nprefix = cfg[field..\"prefix\"] or cfg.targetprefix or prefix\nsuffix = cfg[field..\"suffix\"] or cfg.targetsuffix or suffix\next = cfg[field..\"extension\"] or cfg.targetextension or ext\nlocal result = { }\nresult.basename = name .. suffix\nresult.name = prefix .. name .. suffix .. ext\nresult.directory = dir\nresult.subdirectory = subdir\nresult.prefix = prefix\nresult.suffix = suffix\nresult.fullpath = path.join(result." + "directory, result.name)\nresult.bundlepath = bundlepath or result.fullpath\nif pathstyle == \"windows\" then\nresult.directory = path.translate(result.directory, \"\\\\\")\nresult.subdirectory = path.translate(result.subdirectory, \"\\\\\")\nresult.fullpath = path.translate(result.fullpath, \"\\\\\")\nend\nreturn result\nend\nfunction premake.gettool(cfg)\nif premake.iscppproject(cfg) then\nif _OPTIONS.cc then\nreturn premake[_OPTIONS.cc]\nend\nlocal action = premake.action.current()\nif action.valid_tools then\nreturn premake[action.valid_tools.cc[1]]\nend\nreturn premake.gcc\nelse\nreturn premake.dotnet\nend\nend\nfunction premake.project.getvpath(prj, abspath)\nlocal vpath = abspath\nlocal fname = path.getname(abspath)\nlocal max = abspath:len() - fname:len()\nfor replacement, patterns in pairs(prj.vpaths or {}) do\nfor _, pattern in ipairs(patterns) do\nlocal i = abspath:find(path.wildcards(pattern))\nif i == 1 then\ni = pattern:find(\"*\", 1, true) or (pattern:len() + 1)\nlocal leaf\nif i < max " + "then\nleaf = abspath:sub(i)\nelse\nleaf = fname\nend\nif leaf:startswith(\"/\") then\nleaf = leaf:sub(2)\nend\nlocal stem = \"\"\nif replacement:len() > 0 then\nstem, stars = replacement:gsub(\"%*\", \"\")\nif stars == 0 then\nleaf = path.getname(leaf)\nend\nelse\nleaf = path.getname(leaf)\nend\nvpath = path.join(stem, leaf)\nend\nend\nend\nreturn path.trimdots(vpath)\nend\nfunction premake.hascppproject(sln)\nfor prj in premake.solution.eachproject(sln) do\nif premake.iscppproject(prj) then\nreturn true\nend\nend\nend\nfunction premake.hasdotnetproject(sln)\nfor prj in premake.solution.eachproject(sln) do\nif premake.isdotnetproject(prj) then\nreturn true\nend\nend\nend\nfunction premake.project.iscproject(prj)\nreturn prj.language == \"C\"\nend\nfunction premake.iscppproject(prj)\nreturn (prj.language == \"C\" or prj.language == \"C++\")\nend\nfunction premake.isdotnetproject(prj)\nreturn (prj.language == \"C#\")\nend\n", /* base/config.lua */ "premake.config = { }\nlocal config = premake.config\nfunction premake.config.isdebugbuild(cfg)\nif cfg.flags.DebugRuntime then\nreturn true\nend\nif cfg.flags.ReleaseRuntime then\nreturn false\nend\nif cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed then\nreturn false\nend\nif not cfg.flags.Symbols then\nreturn false\nend\nreturn true\nend\nfunction premake.config.isincrementallink(cfg)\nif cfg.kind == \"StaticLib\" \nor config.isoptimizedbuild(cfg.flags)\nor cfg.flags.NoIncrementalLink then\nreturn false\nend\nreturn true\nend\nfunction premake.config.isoptimizedbuild(flags)\nreturn flags.Optimize or flags.OptimizeSize or flags.OptimizeSpeed\nend\n", @@ -78,7 +77,7 @@ const char* builtin_scripts[] = { " entries and apply their usage project data\n -- to the given configuration. It will copy compiling information for the projects that are\n -- not listed as linkage-only. It will copy the linking information for projects only if\n -- the source project is not a static library. It won't copy linking information\n -- if the project is in this solution; instead it will add that project to the configuration's\n -- links field, expecting that Premake will handle the rest.\n --\n local function copyusagedata(cfg, cfgname, linkToProjs)\n local myPrj = cfg.project;\n local bIsStaticLib = (getCfgKind(cfg) == \"StaticLib\");\n for prjName, prjEntry in pairs(linkToProjs) do\n local srcPrj = prjEntry.usageProj;\n local srcCfg = srcPrj.__configs[cfgname];\n for name, field in pairs(premake.fields) do\n if(srcCfg[name]) then\n if(field.usagecopy) then\n if(not prjEntry.bLinkageOnly) then\n copydependentfield(srcCfg, cfg, name)\n end\n elseif(field.linkagecopy) then\n --Copy the linkage data if we're buil" "ding a non-static thing\n --and this is a pure usage project. If it's not pure-usage, then\n --we will simply put the project's name in the links field later.\n if((not bIsStaticLib) and (not prjEntry.proj)) then\n copydependentfield(srcCfg, cfg, name)\n end\n end\n end\n end\n if((not bIsStaticLib) and prjEntry.proj) then\n table.insert(cfg.links, prjEntry.proj.name);\n end\n end\n end\nfunction premake.bake.buildconfigs()\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nprj.location = prj.location or sln.location or prj.basedir\nadjustpaths(prj.location, prj)\nfor _, blk in ipairs(prj.blocks) do\nadjustpaths(prj.location, blk)\nend\nend\nsln.location = sln.location or sln.basedir\nend\nfor sln in premake.solution.each() do\nlocal basis = collapse(sln)\nfor _, prj in ipairs(sln.projects) do\nprj.__configs = collapse(prj, basis)\nfor _, cfg in pairs(prj.__configs) do\nbake.postprocess(prj, cfg)\nend\nend\nend\nfor sln in premake.solution.each() do\nfor prjIx, prj in i" "pairs(sln.projects) do\nif(not prj.usage) then\nfor cfgname, cfg in pairs(prj.__configs) do\nlocal usesPrjs = getprojectsconnections(cfg, cfgname);\ncopyusagedata(cfg, cfgname, usesPrjs)\nend\nend\nend\nend\nfor sln in premake.solution.each() do\nlocal removeList = {};\nfor index, prj in ipairs(sln.projects) do\nif(prj.usage) then\ntable.insert(removeList, 1, index); --Add in reverse order.\nend\nend\nfor _, index in ipairs(removeList) do\ntable.remove(sln.projects, index);\nend\nend\nbuilduniquedirs()\nbuildtargets(cfg)\nend\nfunction premake.bake.postprocess(prj, cfg)\ncfg.project = prj\ncfg.shortname = premake.getconfigname(cfg.name, cfg.platform, true)\ncfg.longname = premake.getconfigname(cfg.name, cfg.platform)\ncfg.location = cfg.location or cfg.basedir\nlocal platform = premake.platforms[cfg.platform]\nif platform.iscrosscompiler then\ncfg.system = cfg.platform\nelse\ncfg.system = os.get()\nend\nif cfg.kind == \"SharedLib\" and platform.nosharedlibs then\ncfg.kind = \"StaticLib\"\nend\nlocal removef" - "iles = cfg.removefiles\nif _ACTION == 'gmake' then\nremovefiles = table.join(removefiles, cfg.excludes)\nend\nlocal files = {}\nfor _, fname in ipairs(cfg.files) do\nif not table.icontains(removefiles, fname) then\ntable.insert(files, fname)\nend\nend\ncfg.files = files\nfor name, field in pairs(premake.fields) do\nif field.isflags then\nlocal values = cfg[name]\nfor _, flag in ipairs(values) do values[flag] = true end\nend\nend\ncfg.__fileconfigs = { }\nfor _, fname in ipairs(cfg.files) do\ncfg.terms.required = fname:lower()\nlocal fcfg = {}\nfor _, blk in ipairs(cfg.project.blocks) do\nif (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then\nmergeobject(fcfg, blk)\nend\nend\nfcfg.name = fname\ncfg.__fileconfigs[fname] = fcfg\ntable.insert(cfg.__fileconfigs, fcfg)\nend\nend\n", + "iles = cfg.removefiles\nif _ACTION == 'gmake' then\nremovefiles = table.join(removefiles, cfg.excludes)\nend\nlocal files = {}\nfor _, fname in ipairs(cfg.files) do\nif not table.icontains(removefiles, fname) then\ntable.insert(files, fname)\nend\nend\ncfg.files = files\nfor name, field in pairs(premake.fields) do\nif field.isflags then\nlocal values = cfg[name]\nfor _, flag in ipairs(values) do values[flag] = true end\nend\nend\ncfg.__fileconfigs = { }\nfor _, fname in ipairs(cfg.files) do\nlocal fcfg = {}\nif premake._filelevelconfig then\ncfg.terms.required = fname:lower()\nfor _, blk in ipairs(cfg.project.blocks) do\nif (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then\nmergeobject(fcfg, blk)\nend\nend\nend\nfcfg.name = fname\ncfg.__fileconfigs[fname] = fcfg\ntable.insert(cfg.__fileconfigs, fcfg)\nend\nend\n", /* base/api.lua */ "premake.fields =\n{\narchivesplit_size =\n{\nkind = \"string\",\nscope = \"config\",\n},\nbasedir =\n{\nkind = \"path\",\nscope = \"container\",\n},\nbuildaction =\n{\nkind = \"string\",\nscope = \"config\",\nallowed = {\n\"Compile\",\n\"Copy\",\n\"Embed\",\n\"None\"\n}\n},\nbuildoptions =\n{\nkind = \"list\",\nscope = \"config\",\n},\nbuildoptions_c =\n{\nkind = \"list\",\nscope = \"config\",\n},\nbuildoptions_cpp =\n{\nkind = \"list\",\nscope = \"config\",\n},\nbuildoptions_objc =\n{\nkind = \"list\",\nscope = \"config\",\n},\nconfigurations =\n{\nkind = \"list\",\nscope = \"solution\",\n},\ncustombuildtask =\n{\nkind = \"table\",\nscope = \"config\",\n},\ndebugargs =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndebugdir =\n{\nkind = \"path\",\nscope = \"config\",\n},\ndebugenvs =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndefines =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndeploymentoptions =\n{\nkind = \"list\",\nscope = \"config\",\nusagecopy = true,\n},\ndependency =\n{\nkind = \"" @@ -96,11 +95,11 @@ const char* builtin_scripts[] = { "ontainer, err = premake.getobject(\"container\")\nif (not container) then\nerror(err, 2)\nend\nlocal cfg = { }\ncfg.terms = table.flatten({terms})\ntable.insert(container.blocks, cfg)\npremake.CurrentConfiguration = cfg\ncfg.keywords = { }\nfor _, word in ipairs(cfg.terms) do\ntable.insert(cfg.keywords, path.wildcards(word):lower())\nend\nfor name, field in pairs(premake.fields) do\nif (field.kind ~= \"string\" and field.kind ~= \"path\") then\ncfg[name] = { }\nend\nend\nreturn cfg\nend\nlocal function creategroup(name, sln, curpath, parent, inpath)\nlocal group = {}\nsetmetatable(group, {\n__type = \"group\"\n})\ntable.insert(sln.groups, group)\nsln.groups[inpath] = group\ngroup.solution = sln\ngroup.name = name\ngroup.uuid = os.uuid(curpath)\ngroup.parent = parent\nreturn group\nend\nlocal function creategroupsfrompath(inpath, sln)\nif inpath == nil then return nil end\ninpath = path.translate(inpath, \"/\")\nlocal groups = string.explode(inpath, \"/\")\nlocal curpath = \"\"\nlocal lastgroup = nil\nfor i, v " "in ipairs(groups) do\ncurpath = curpath .. \"/\" .. v:lower()\nlocal group = sln.groups[curpath]\nif group == nil then\ngroup = creategroup(v, sln, curpath, lastgroup, curpath)\nend\nlastgroup = group\nend\nreturn lastgroup\nend\nlocal function createproject(name, sln, isUsage)\nlocal prj = {}\nsetmetatable(prj, {\n__type = \"project\",\n})\ntable.insert(sln.projects, prj)\nif(isUsage) then\nif(sln.projects[name]) then\nsln.projects[name].usageProj = prj;\nelse\nsln.projects[name] = prj\nend\nelse\nif(sln.projects[name]) then\nprj.usageProj = sln.projects[name];\nend\nsln.projects[name] = prj\nend\nlocal group = creategroupsfrompath(premake.CurrentGroup, sln)\nprj.solution = sln\nprj.name = name\nprj.basedir = os.getcwd()\nprj.uuid = os.uuid(prj.name)\nprj.blocks = { }\nprj.usage = isUsage\nprj.group = group\nreturn prj;\nend\nfunction usage(name)\nif (not name) then\nif(type(premake.CurrentContainer) ~= \"project\") then return nil end\nif(not premake" ".CurrentContainer.usage) then return nil end\nreturn premake.CurrentContainer\nend\nlocal sln\nif (type(premake.CurrentContainer) == \"project\") then\nsln = premake.CurrentContainer.solution\nelse\nsln = premake.CurrentContainer\nend\nif (type(sln) ~= \"solution\") then\nerror(\"no active solution\", 2)\nend\nif((not sln.projects[name]) or\n((not sln.projects[name].usage) and (not sln.projects[name].usageProj))) then\npremake.CurrentContainer = createproject(name, sln, true)\nelse\npremake.CurrentContainer = iff(sln.projects[name].usage,\nsln.projects[name], sln.projects[name].usageProj)\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction project(name)\nif (not name) then\nif(type(premake.CurrentContainer) ~= \"project\") then return nil end\nif(premake.CurrentContainer.usage) then return nil end\nreturn premake.CurrentContainer\nend\nlocal sln\nif (type(premake.CurrentContainer) == \"project\") then\nsln = premake.CurrentContainer.solution\nelse\nsln = premake.CurrentContainer\nend\nif (t" - "ype(sln) ~= \"solution\") then\nerror(\"no active solution\", 2)\nend\nif((not sln.projects[name]) or sln.projects[name].usage) then\npremake.CurrentContainer = createproject(name, sln)\nelse\npremake.CurrentContainer = sln.projects[name];\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction solution(name)\nif not name then\nif type(premake.CurrentContainer) == \"project\" then\nreturn premake.CurrentContainer.solution\nelse\nreturn premake.CurrentContainer\nend\nend\npremake.CurrentContainer = premake.solution.get(name)\nif (not premake.CurrentContainer) then\npremake.CurrentContainer = premake.solution.new(name)\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction group(name)\nif not name then\nreturn premake.CurrentGroup\nend\npremake.CurrentGroup = name\nreturn premake.CurrentGroup\nend\nfunction newaction(a)\npremake.action.add(a)\nend\nfunction newoption(opt)\npremake.option.add(opt)\nend\n", + "ype(sln) ~= \"solution\") then\nerror(\"no active solution\", 2)\nend\nif((not sln.projects[name]) or sln.projects[name].usage) then\npremake.CurrentContainer = createproject(name, sln)\nelse\npremake.CurrentContainer = sln.projects[name];\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction solution(name)\nif not name then\nif type(premake.CurrentContainer) == \"project\" then\nreturn premake.CurrentContainer.solution\nelse\nreturn premake.CurrentContainer\nend\nend\npremake.CurrentContainer = premake.solution.get(name)\nif (not premake.CurrentContainer) then\npremake.CurrentContainer = premake.solution.new(name)\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction group(name)\nif not name then\nreturn premake.CurrentGroup\nend\npremake.CurrentGroup = name\nreturn premake.CurrentGroup\nend\nfunction newaction(a)\npremake.action.add(a)\nend\nfunction newoption(opt)\npremake.option.add(opt)\nend\nfunction enablefilelevelconfig()\npremake._filelevelconfig = true\nend\n", /* base/cmdline.lua */ "newoption\n{\ntrigger = \"cc\",\nvalue = \"VALUE\",\ndescription = \"Choose a C/C++ compiler set\",\nallowed = {\n{ \"gcc\", \"GNU GCC (gcc/g++)\" },\n{ \"ow\", \"OpenWatcom\" },\n{ \"ghs\", \"Green Hills Software\" },\n}\n}\nnewoption\n{\ntrigger = \"dotnet\",\nvalue = \"VALUE\",\ndescription = \"Choose a .NET compiler set\",\nallowed = {\n{ \"msnet\", \"Microsoft .NET (csc)\" },\n{ \"mono\", \"Novell Mono (mcs)\" },\n{ \"pnet\", \"Portable.NET (cscc)\" },\n}\n}\nnewoption\n{\ntrigger = \"file\",\nvalue = \"FILE\",\ndescription = \"Read FILE as a Premake script; default is 'premake4.lua'\"\n}\nnewoption\n{\ntrigger = \"help\",\ndescription = \"Display this information\"\n}\nnewoption\n{\ntrigger = \"os\",\nvalue = \"VALUE\",\ndescription = \"Generate files for a different operating system\",\nallowed = {\n{ \"bsd\", \"OpenBSD, NetBSD, or FreeBSD\" },\n{ \"linux\", \"Linux\" },\n{ \"macosx\", \"Apple Mac OS X\" },\n{ \"solaris\", \"Sola" - "ris\" },\n{ \"windows\", \"Microsoft Windows\" },\n}\n}\nnewoption\n{\ntrigger = \"platform\",\nvalue = \"VALUE\",\ndescription = \"Add target architecture (if supported by action)\",\nallowed = {\n{ \"x32\", \"32-bit\" },\n{ \"x64\", \"64-bit\" },\n{ \"universal\", \"Mac OS X Universal, 32- and 64-bit\" },\n{ \"universal32\", \"Mac OS X Universal, 32-bit only\" },\n{ \"universal64\", \"Mac OS X Universal, 64-bit only\" },\n{ \"ps3\", \"Playstation 3\" },\n{ \"orbis\", \"Playstation 4\" },\n{ \"xbox360\", \"Xbox 360\" },\n{ \"durango\", \"Xbox One\" },\n{ \"ARM\", \"ARM\" },\n{ \"PowerPC\", \"PowerPC\" },\n}\n}\nnewoption\n{\ntrigger = \"scripts\",\nvalue = \"path\",\ndescription = \"Search for additional scripts on the given path\"\n}\nnewoption\n{\ntrigger = \"version\",\ndescription = \"Display version information\"\n}\n", + "ris\" },\n{ \"windows\", \"Microsoft Windows\" },\n}\n}\nnewoption\n{\ntrigger = \"platform\",\nvalue = \"VALUE\",\ndescription = \"Add target architecture (if supported by action)\",\nallowed = {\n{ \"x32\", \"32-bit\" },\n{ \"x64\", \"64-bit\" },\n{ \"universal\", \"Mac OS X Universal, 32- and 64-bit\" },\n{ \"universal32\", \"Mac OS X Universal, 32-bit only\" },\n{ \"universal64\", \"Mac OS X Universal, 64-bit only\" },\n{ \"ps3\", \"Playstation 3\" },\n{ \"orbis\", \"Playstation 4\" },\n{ \"xbox360\", \"Xbox 360\" },\n{ \"durango\", \"Xbox One\" },\n{ \"ARM\", \"ARM\" },\n{ \"PowerPC\", \"PowerPC\" },\n}\n}\nnewoption\n{\ntrigger = \"scripts\",\nvalue = \"path\",\ndescription = \"Search for additional scripts on the given path\"\n}\nnewoption\n{\ntrigger = \"debug-profiler\",\ndescription = \"GENie script generation profiler.\"\n}\nnewoption\n{\ntrigger = \"version\",\ndescription = \"Display version information\"\n}\n", /* base/inspect.lua */ "-- Copyright (c) 2013 Enrique García Cota\nlocal function smartQuote(str)\n if str:match('\"') and not str:match(\"'\") then\n return \"'\" .. str .. \"'\"\n end\n return '\"' .. str:gsub('\"', '\\\\\"') .. '\"'\nend\nlocal controlCharsTranslation = {\n [\"\\a\"] = \"\\\\a\", [\"\\b\"] = \"\\\\b\", [\"\\f\"] = \"\\\\f\", [\"\\n\"] = \"\\\\n\",\n [\"\\r\"] = \"\\\\r\", [\"\\t\"] = \"\\\\t\", [\"\\v\"] = \"\\\\v\"\n}\nlocal function escapeChar(c) return controlCharsTranslation[c] end\nlocal function escape(str)\n local result = str:gsub(\"\\\\\", \"\\\\\\\\\"):gsub(\"(%c)\", escapeChar)\n return result\nend\nlocal function isIdentifier(str)\n return type(str) == 'string' and str:match( \"^[_%a][_%a%d]*$\" )\nend\nlocal function isArrayKey(k, length)\n return type(k) == 'number' and 1 <= k and k <= length\nend\nlocal function isDictionaryKey(k, length)\n return not isArrayKey(k, length)\nend\nlocal defaultTypeOrders = {\n ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,\n ['fu" @@ -111,6 +110,20 @@ const char* builtin_scripts[] = { "puts('{...}')\n else\n if tableAppearances[t] > 1 then puts('<', getId(t), '>') end\n local dictKeys = getDictionaryKeys(t)\n local length = #t\n local mt = getmetatable(t)\n local to_string_result = getToStringResultSafely(t, mt)\n puts('{')\n down(function()\n if to_string_result then\n puts(' -- ', escape(to_string_result))\n if length >= 1 then tabify() end -- tabify the array values\n end\n local needsComma = false\n for i=1, length do\n needsComma = commaControl(needsComma)\n puts(' ')\n putValue(t[i], makePath(path, i))\n end\n for _,k in ipairs(dictKeys) do\n needsComma = commaControl(needsComma)\n tabify()\n putKey(k)\n puts(' = ')\n putValue(t[k], makePath(path, k))\n end\n if mt then\n needsComma = commaControl(needsComma)\n tabify()\n puts(' = '" ")\n putValue(mt, makePath(path, ''))\n end\n end)\n if #dictKeys > 0 or mt then -- dictionary table. Justify closing }\n tabify()\n elseif length > 0 then -- array tables have one extra space before closing }\n puts(' ')\n end\n puts('}')\n end\n end\n -- putvalue is forward-declared before putTable & putKey\n putValue = function(v, path)\n if filter(v, path) then\n puts('')\n else\n local tv = type(v)\n if tv == 'string' then\n puts(smartQuote(escape(v)))\n elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then\n puts(tostring(v))\n elseif tv == 'table' then\n putTable(v, path)\n else\n puts('<',tv,' ',getId(v),'>')\n end\n end\n end\n putValue(rootObject, {})\n return table.concat(buffer)\nend\nfunction printtable(name, table)\nprint(\"table: \", name, inspect(table), \"\\n\")\nend\nfunction printstack()\nprint(debug.traceback(), \"\\n\")\nend\n", + /* base/profiler.lua */ + "_profiler = {}\nfunction newProfiler(variant, sampledelay)\nif _profiler.running then\nprint(\"Profiler already running.\")\nreturn\nend\nvariant = variant or \"time\"\nif variant ~= \"time\" and variant ~= \"call\" then\nprint(\"Profiler method must be 'time' or 'call'.\")\nreturn\nend\nlocal newprof = {}\nfor k,v in pairs(_profiler) do\nnewprof[k] = v\nend\nnewprof.variant = variant\nnewprof.sampledelay = sampledelay or 100000\nreturn newprof\nend\nfunction _profiler.start(self)\nif _profiler.running then\nreturn\nend\n_profiler.running = self\nself.rawstats = {}\nself.callstack = {}\nif self.variant == \"time\" then\nself.lastclock = os.clock()\ndebug.sethook( _profiler_hook_wrapper_by_time, \"\", self.sampledelay )\nelseif self.variant == \"call\" then\ndebug.sethook( _profiler_hook_wrapper_by_call, \"cr\" )\nelse\nprint(\"Profiler method must be 'time' or 'call'.\")\nsys.exit(1)\nend\nend\nfunction _profiler.stop(self)\nif _profiler.running ~= self then\nreturn\nend\ndebug.sethook( nil )\n_profiler.runnin" + "g = nil\nend\nfunction _profiler_hook_wrapper_by_call(action)\nif _profiler.running == nil then\ndebug.sethook( nil )\nend\n_profiler.running:_internal_profile_by_call(action)\nend\nfunction _profiler_hook_wrapper_by_time(action)\nif _profiler.running == nil then\ndebug.sethook( nil )\nend\n_profiler.running:_internal_profile_by_time(action)\nend\nfunction _profiler._internal_profile_by_call(self,action)\nlocal caller_info = debug.getinfo( 3 )\nif caller_info == nil then\nprint \"No caller_info\"\nreturn\nend\nlocal latest_ar = nil\nif table.getn(self.callstack) > 0 then\nlatest_ar = self.callstack[table.getn(self.callstack)]\nend\nlocal should_not_profile = 0\nfor k,v in pairs(self.prevented_functions) do\nif k == caller_info.func then\nshould_not_profile = v\nend\nend\nif latest_ar then\nif latest_ar.should_not_profile == 2 then\nshould_not_profile = 2\nend\nend\nif action == \"call\" then\nlocal this_ar = {}\nthis_ar.should_not_profile = should_not_profile\nthis_ar.parent_ar = latest_ar\nthis_ar.anon_child " + "= 0\nthis_ar.name_child = 0\nthis_ar.children = {}\nthis_ar.children_time = {}\nthis_ar.clock_start = os.clock()\ntable.insert( self.callstack, this_ar )\nelse\nlocal this_ar = latest_ar\nif this_ar == nil then\nreturn -- No point in doing anything if no upper activation record\nend\nthis_ar.clock_end = os.clock()\nthis_ar.this_time = this_ar.clock_end - this_ar.clock_start\nif this_ar.parent_ar then\nthis_ar.parent_ar.children[caller_info.func] =\n(this_ar.parent_ar.children[caller_info.func] or 0) + 1\nthis_ar.parent_ar.children_time[caller_info.func] =\n(this_ar.parent_ar.children_time[caller_info.func] or 0 ) +\nthis_ar.this_time\nif caller_info.name == nil then\nthis_ar.parent_ar.anon_child =\nthis_ar.parent_ar.anon_child + this_ar.this_time\nelse\nthis_ar.parent_ar.name_child =\nthis_ar.parent_ar.name_child + this_ar.this_time\nend\nend\nif this_ar.should_not_profile == 0 then\nlocal inforec = self:_get_func_rec(caller_info.func,1)\ninforec.count = inforec.count + 1\ninforec.time = inforec.time + this_ar" + ".this_time\ninforec.anon_child_time = inforec.anon_child_time + this_ar.anon_child\ninforec.name_child_time = inforec.name_child_time + this_ar.name_child\ninforec.func_info = caller_info\nfor k,v in pairs(this_ar.children) do\ninforec.children[k] = (inforec.children[k] or 0) + v\ninforec.children_time[k] =\n(inforec.children_time[k] or 0) + this_ar.children_time[k]\nend\nend\ntable.remove( self.callstack, table.getn( self.callstack ) )\nend\nend\nfunction _profiler._internal_profile_by_time(self,action)\nlocal timetaken = os.clock() - self.lastclock\nlocal depth = 3\nlocal at_top = true\nlocal last_caller\nlocal caller = debug.getinfo(depth)\nwhile caller do\nif not caller.func then caller.func = \"(tail call)\" end\nif self.prevented_functions[caller.func] == nil then\nlocal info = self:_get_func_rec(caller.func, 1, caller)\ninfo.count = info.count + 1\ninfo.time = info.time + timetaken\nif last_caller then\nif last_caller.name then\ninfo.name_child_time = info.name_child_time + timetaken\nelse\ninfo.anon_ch" + "ild_time = info.anon_child_time + timetaken\nend\ninfo.children[last_caller.func] =\n(info.children[last_caller.func] or 0) + 1\ninfo.children_time[last_caller.func] =\n(info.children_time[last_caller.func] or 0) + timetaken\nend\nend\ndepth = depth + 1\nlast_caller = caller\ncaller = debug.getinfo(depth)\nend\nself.lastclock = os.clock()\nend\nfunction _profiler._get_func_rec(self,func,force,info)\nlocal ret = self.rawstats[func]\nif ret == nil and force ~= 1 then\nreturn nil\nend\nif ret == nil then\nret = {}\nret.func = func\nret.count = 0\nret.time = 0\nret.anon_child_time = 0\nret.name_child_time = 0\nret.children = {}\nret.children_time = {}\nret.func_info = info\nself.rawstats[func] = ret\nend\nreturn ret\nend\nfunction _profiler.report( self, outfile, sort_by_total_time )\noutfile:write\n[[Lua Profile output created by profiler.lua. Copyright Pepperfish 2002+\n]]\nlocal terms = {}\nif self.variant == \"time\" then\nterms.capitalized = \"Sample\"\nterms.single = \"sample\"\nterms.pastverb = \"sampled\"" + "\nelseif self.variant == \"call\" then\nterms.capitalized = \"Call\"\nterms.single = \"call\"\nterms.pastverb = \"called\"\nelse\nassert(false)\nend\nlocal total_time = 0\nlocal ordering = {}\nfor func,record in pairs(self.rawstats) do\ntable.insert(ordering, func)\nend\nif sort_by_total_time then\ntable.sort( ordering,\nfunction(a,b) return self.rawstats[a].time > self.rawstats[b].time end\n)\nelse\ntable.sort( ordering,\nfunction(a,b)\nlocal arec = self.rawstats[a]\nlocal brec = self.rawstats[b]\nlocal atime = arec.time - (arec.anon_child_time + arec.name_child_time)\nlocal btime = brec.time - (brec.anon_child_time + brec.name_child_time)\nreturn atime > btime\nend\n)\nend\nfor i=1,#ordering do\nlocal func = ordering[i]\nlocal record = self.rawstats[func]\nlocal thisfuncname = \" \" .. self:_pretty_name(func) .. \" \"\nif string.len( thisfuncname ) < 42 then\nthisfuncname = string.rep( \"-\", math.floor((42 - string.len(thisfuncname))/2) ) .. thisfuncname\nthisfuncname = thisfuncname .. string.rep( \"-\", 42" + " - string.len(thisfuncname) )\nend\ntotal_time = total_time + ( record.time - ( record.anon_child_time +\nrecord.name_child_time ) )\noutfile:write( string.rep( \"-\", 19 ) .. thisfuncname ..\nstring.rep( \"-\", 19 ) .. \"\\n\" )\noutfile:write( terms.capitalized..\" count: \" ..\nstring.format( \"%4d\", record.count ) .. \"\\n\" )\noutfile:write( \"Time spend total: \" ..\nstring.format( \"%4.3f\", record.time ) .. \"s\\n\" )\noutfile:write( \"Time spent in children: \" ..\nstring.format(\"%4.3f\",record.anon_child_time+record.name_child_time) ..\n\"s\\n\" )\nlocal timeinself =\nrecord.time - (record.anon_child_time + record.name_child_time)\noutfile:write( \"Time spent in self: \" ..\nstring.format(\"%4.3f\", timeinself) .. \"s\\n\" )\noutfile:write( \"Time spent per \" .. terms.single .. \": \" ..\nstring.format(\"%4.5f\", record.time/record.count) ..\n\"s/\" .. terms.single .. \"\\n\" )\noutfile:write( \"Time spent in self per \"..terms.single..\": \" ..\nstring.format( \"%4.5f\", timein" + "self/record.count ) .. \"s/\" ..\nterms.single..\"\\n\" )\nlocal added_blank = 0\nfor k,v in pairs(record.children) do\nif self.prevented_functions[k] == nil or\nself.prevented_functions[k] == 0\nthen\nif added_blank == 0 then\noutfile:write( \"\\n\" ) -- extra separation line\nadded_blank = 1\nend\noutfile:write( \"Child \" .. self:_pretty_name(k) ..\nstring.rep( \" \", 41-string.len(self:_pretty_name(k)) ) .. \" \" ..\nterms.pastverb..\" \" .. string.format(\"%6d\", v) )\noutfile:write( \" times. Took \" ..\nstring.format(\"%4.2f\", record.children_time[k] ) .. \"s\\n\" )\nend\nend\noutfile:write( \"\\n\" ) -- extra separation line\noutfile:flush()\nend\noutfile:write( \"\\n\\n\" )\noutfile:write( \"Total time spent in profiled functions: \" ..\nstring.format(\"%5.3g\",total_time) .. \"s\\n\" )\noutfile:write( [[\nEND\n]] )\noutfile:flush()\nend\nfunction _profiler.lua_report(self,outfile)\nlocal ordering = {}\nlocal functonum = {}\nfor func,record in pairs(self.rawstats) do\ntable.insert(ordering, func)\nfu" + "nctonum[func] = table.getn(ordering)\nend\noutfile:write(\n\"-- Profile generated by profiler.lua Copyright Pepperfish 2002+\\n\\n\" )\noutfile:write( \"-- Function names\\nfuncnames = {}\\n\" )\nfor i=1,table.getn(ordering) do\nlocal thisfunc = ordering[i]\noutfile:write( \"funcnames[\" .. i .. \"] = \" ..\nstring.format(\"%q\", self:_pretty_name(thisfunc)) .. \"\\n\" )\nend\noutfile:write( \"\\n\" )\noutfile:write( \"-- Function times\\nfunctimes = {}\\n\" )\nfor i=1,table.getn(ordering) do\nlocal thisfunc = ordering[i]\nlocal record = self.rawstats[thisfunc]\noutfile:write( \"functimes[\" .. i .. \"] = { \" )\noutfile:write( \"tot=\" .. record.time .. \", \" )\noutfile:write( \"achild=\" .. record.anon_child_time .. \", \" )\noutfile:write( \"nchild=\" .. record.name_child_time .. \", \" )\noutfile:write( \"count=\" .. record.count .. \" }\\n\" )\nend\noutfile:write( \"\\n\" )\noutfile:write( \"-- Child links\\nchildren = {}\\n\" )\nfor i=1,table.getn(ordering) do\nlocal thisfunc = ordering[i]\nlocal record" + " = self.rawstats[thisfunc]\noutfile:write( \"children[\" .. i .. \"] = { \" )\nfor k,v in pairs(record.children) do\nif functonum[k] then -- non-recorded functions will be ignored now\noutfile:write( functonum[k] .. \", \" )\nend\nend\noutfile:write( \"}\\n\" )\nend\noutfile:write( \"\\n\" )\noutfile:write( \"-- Child call counts\\nchildcounts = {}\\n\" )\nfor i=1,table.getn(ordering) do\nlocal thisfunc = ordering[i]\nlocal record = self.rawstats[thisfunc]\noutfile:write( \"children[\" .. i .. \"] = { \" )\nfor k,v in record.children do\nif functonum[k] then -- non-recorded functions will be ignored now\noutfile:write( v .. \", \" )\nend\nend\noutfile:write( \"}\\n\" )\nend\noutfile:write( \"\\n\" )\noutfile:write( \"-- Child call time\\nchildtimes = {}\\n\" )\nfor i=1,table.getn(ordering) do\nlocal thisfunc = ordering[i]\nlocal record = self.rawstats[thisfunc];\noutfile:write( \"children[\" .. i .. \"] = { \" )\nfor k,v in pairs(record.children) do\nif functonum[k] then -- non-recorded functions will be ignor" + "ed now\noutfile:write( record.children_time[k] .. \", \" )\nend\nend\noutfile:write( \"}\\n\" )\nend\noutfile:write( \"\\n\\n-- That is all.\\n\\n\" )\noutfile:flush()\nend\nfunction _profiler._pretty_name(self,func)\nlocal info = self.rawstats[ func ].func_info\nlocal name = \"\"\nif info.what == \"Lua\" then\nname = \"L:\"\nend\nif info.what == \"C\" then\nname = \"C:\"\nend\nif info.what == \"main\" then\nname = \" :\"\nend\nif info.name == nil then\nname = name .. \"<\"..tostring(func) .. \">\"\nelse\nname = name .. info.name\nend\nif info.source then\nname = name .. \"@\" .. info.source\nelse\nif info.what == \"C\" then\nname = name .. \"@?\"\nelse\nname = name .. \"@\"\nend\nend\nname = name .. \":\"\nif info.what == \"C\" then\nname = name .. \"?\"\nelse\nname = name .. info.linedefined\nend\nreturn name\nend\nfunction _profiler.prevent(self, func, level)\nself.prevented_functions[func] = (level or 1)\nend\n_profiler.prevented_functions = {\n[_profiler.start] = 2,\n[_profiler.stop] = 2,\n[_profi" + "ler._internal_profile_by_time] = 2,\n[_profiler._internal_profile_by_call] = 2,\n[_profiler_hook_wrapper_by_time] = 2,\n[_profiler_hook_wrapper_by_call] = 2,\n[_profiler.prevent] = 2,\n[_profiler._get_func_rec] = 2,\n[_profiler.report] = 2,\n[_profiler.lua_report] = 2,\n[_profiler._pretty_name] = 2\n}\n", + /* tools/dotnet.lua */ "premake.dotnet = { }\npremake.dotnet.namestyle = \"windows\"\nlocal flags =\n{\nFatalWarning = \"/warnaserror\",\nOptimize = \"/optimize\",\nOptimizeSize = \"/optimize\",\nOptimizeSpeed = \"/optimize\",\nSymbols = \"/debug\",\nUnsafe = \"/unsafe\"\n}\nfunction premake.dotnet.getbuildaction(fcfg)\nlocal ext = path.getextension(fcfg.name):lower()\nif fcfg.buildaction == \"Compile\" or ext == \".cs\" then\nreturn \"Compile\"\nelseif fcfg.buildaction == \"Embed\" or ext == \".resx\" then\nreturn \"EmbeddedResource\"\nelseif fcfg.buildaction == \"Copy\" or ext == \".asax\" or ext == \".aspx\" then\nreturn \"Content\"\nelse\nreturn \"None\"\nend\nend\nfunction premake.dotnet.getcompilervar(cfg)\nif (_OPTIONS.dotnet == \"msnet\") then\nreturn \"csc\"\nelseif (_OPTIONS.dotnet == \"mono\") then\nif (cfg.framework <= \"1.1\") then\nreturn \"mcs\"\nelseif (cfg.framework >= \"4.0\") then\nreturn \"dmcs\"\nelse \nreturn \"gmcs\"\nend\nelse\nreturn \"cscc\"\nend\nend\nfunction premake.dotnet.getfla" "gs(cfg)\nlocal result = table.translate(cfg.flags, flags)\nreturn result\nend\nfunction premake.dotnet.getkind(cfg)\nif (cfg.kind == \"ConsoleApp\") then\nreturn \"Exe\"\nelseif (cfg.kind == \"WindowedApp\") then\nreturn \"WinExe\"\nelseif (cfg.kind == \"SharedLib\") then\nreturn \"Library\"\nend\nend", @@ -148,7 +161,7 @@ const char* builtin_scripts[] = { "function premake.showhelp()\nprintf(\"\")\nprintf(\"Usage: genie [options] action [arguments]\")\nprintf(\"\")\nprintf(\"OPTIONS\")\nprintf(\"\")\nfor option in premake.option.each() do\nlocal trigger = option.trigger\nlocal description = option.description\nif (option.value) then trigger = trigger .. \"=\" .. option.value end\nif (option.allowed) then description = description .. \"; one of:\" end\nprintf(\" --%-15s %s\", trigger, description)\nif (option.allowed) then\nfor _, value in ipairs(option.allowed) do\nprintf(\" %-14s %s\", value[1], value[2])\nend\nend\nprintf(\"\")\nend\nprintf(\"ACTIONS\")\nprintf(\"\")\nfor action in premake.action.each() do\nprintf(\" %-17s %s\", action.trigger, action.description)\nend\nprintf(\"\")\nprintf(\"For additional information, see https://github.com/bkaradzic/genie\")\nend\n", /* base/premake.lua */ - "function premake.generate(obj, filename, callback)\nfilename = premake.project.getfilename(obj, filename)\nprintf(\"Generating %s...\", filename)\nlocal f, err = io.open(filename, \"wb\")\nif (not f) then\nerror(err, 0)\nend\nio.output(f)\ncallback(obj)\nf:close()\nend\nfunction premake.findDefaultScript(dir, search_upwards)\nsearch_upwards = search_upwards or true\nlocal last = \"\"\nwhile dir ~= last do\nfor _, name in ipairs({ \"genie.lua\", \"solution.lua\", \"premake4.lua\" }) do\nlocal script0 = dir .. \"/\" .. name\nif (os.isfile(script0)) then\nreturn dir, name\nend\nlocal script1 = dir .. \"/scripts/\" .. name\nif (os.isfile(script1)) then\nreturn dir .. \"/scripts/\", name\nend\nend\nlast = dir\ndir = path.getabsolute(dir .. \"/..\")\nif dir == \".\" or not search_upwards then break end\nend\nreturn nil, nil\nend", + "premake._filelevelconfig = false\nfunction premake.generate(obj, filename, callback)\nfilename = premake.project.getfilename(obj, filename)\nprintf(\"Generating %s...\", filename)\nlocal f, err = io.open(filename, \"wb\")\nif (not f) then\nerror(err, 0)\nend\nio.output(f)\ncallback(obj)\nf:close()\nend\nfunction premake.findDefaultScript(dir, search_upwards)\nsearch_upwards = search_upwards or true\nlocal last = \"\"\nwhile dir ~= last do\nfor _, name in ipairs({ \"genie.lua\", \"solution.lua\", \"premake4.lua\" }) do\nlocal script0 = dir .. \"/\" .. name\nif (os.isfile(script0)) then\nreturn dir, name\nend\nlocal script1 = dir .. \"/scripts/\" .. name\nif (os.isfile(script1)) then\nreturn dir .. \"/scripts/\", name\nend\nend\nlast = dir\ndir = path.getabsolute(dir .. \"/..\")\nif dir == \".\" or not search_upwards then break end\nend\nreturn nil, nil\nend\n", /* actions/codeblocks/_codeblocks.lua */ "premake.codeblocks = { }\nnewaction {\ntrigger = \"codeblocks\",\nshortname = \"Code::Blocks\",\ndescription = \"Generate Code::Blocks project files\",\nvalid_kinds = { \"ConsoleApp\", \"WindowedApp\", \"StaticLib\", \"SharedLib\" },\nvalid_languages = { \"C\", \"C++\" },\nvalid_tools = {\ncc = { \"gcc\", \"ow\" },\n},\nonsolution = function(sln)\npremake.generate(sln, \"%%.workspace\", premake.codeblocks.workspace)\nend,\nonproject = function(prj)\npremake.generate(prj, \"%%.cbp\", premake.codeblocks.cbp)\nend,\noncleansolution = function(sln)\npremake.clean.file(sln, \"%%.workspace\")\nend,\noncleanproject = function(prj)\npremake.clean.file(prj, \"%%.cbp\")\npremake.clean.file(prj, \"%%.depend\")\npremake.clean.file(prj, \"%%.layout\")\nend\n}\n", @@ -364,8 +377,8 @@ const char* builtin_scripts[] = { /* _premake_main.lua */ "_WORKING_DIR = os.getcwd()\nlocal function injectplatform(platform)\nif not platform then return true end\nplatform = premake.checkvalue(platform, premake.fields.platforms.allowed)\nfor sln in premake.solution.each() do\nlocal platforms = sln.platforms or { }\nif #platforms == 0 then\ntable.insert(platforms, \"Native\")\nend\nif not table.contains(platforms, \"Native\") then\nreturn false, sln.name .. \" does not target native platform\\nNative platform settings are required for the --platform feature.\"\nend\nif not table.contains(platforms, platform) then\ntable.insert(platforms, platform)\nend\nsln.platforms = platforms\nend\nreturn true\nend\nfunction _premake_main(scriptpath)\nif (scriptpath) then\nlocal scripts = dofile(scriptpath .. \"/_manifest.lua\")\nfor _,v in ipairs(scripts) do\ndofile(scriptpath .. \"/\" .. v)\nend\nend\n_PREMAKE_COMMAND = path.getabsolute(_PREMAKE_COMMAND)\npremake.action.set(_ACTION)\nmath.randomseed(os.time())\nif (nil ~= _OPTIONS[\"file\"]) then\nlocal fname = _OPTIONS" - "[\"file\"]\nif (os.isfile(fname)) then\ndofile(fname)\nelse\nerror(\"No genie script '\" .. fname .. \"' found!\", 2)\nend\nelse\nlocal dir, name = premake.findDefaultScript(path.getabsolute(\"./\"))\nif dir ~= nil then\nos.chdir(dir)\ndofile(name)\nend\nend\nif (_OPTIONS[\"version\"] or _OPTIONS[\"help\"] or not _ACTION) then\nprintf(\"GENie - Project generator tool %s\", _GENIE_VERSION_STR)\nprintf(\"https://github.com/bkaradzic/genie\")\nif (not _OPTIONS[\"version\"]) then\npremake.showhelp()\nend\nreturn 1\nend\naction = premake.action.current()\nif (not action) then\nerror(\"Error: no such action '\" .. _ACTION .. \"'\", 0)\nend\nok, err = premake.option.validate(_OPTIONS)\nif (not ok) then error(\"Error: \" .. err, 0) end\nok, err = premake.checktools()\nif (not ok) then error(\"Error: \" .. err, 0) end\nok, err = injectplatform(_OPTIONS[\"platform\"])\nif (not ok) then error(\"Error: \" .. err, 0) end\nprint(\"Building configurations...\")\npremake.bake.buildconfigs()\nok, err = premake.checkprojects()" - "\nif (not ok) then error(\"Error: \" .. err, 0) end\nprintf(\"Running action '%s'...\", action.trigger)\npremake.action.call(action.trigger)\nprint(\"Done.\")\nreturn 0\nend\n", + "[\"file\"]\nif (os.isfile(fname)) then\ndofile(fname)\nelse\nerror(\"No genie script '\" .. fname .. \"' found!\", 2)\nend\nelse\nlocal dir, name = premake.findDefaultScript(path.getabsolute(\"./\"))\nif dir ~= nil then\nos.chdir(dir)\ndofile(name)\nend\nend\nif (_OPTIONS[\"version\"] or _OPTIONS[\"help\"] or not _ACTION) then\nprintf(\"GENie - Project generator tool %s\", _GENIE_VERSION_STR)\nprintf(\"https://github.com/bkaradzic/GENie\")\nif (not _OPTIONS[\"version\"]) then\npremake.showhelp()\nend\nreturn 1\nend\naction = premake.action.current()\nif (not action) then\nerror(\"Error: no such action '\" .. _ACTION .. \"'\", 0)\nend\nok, err = premake.option.validate(_OPTIONS)\nif (not ok) then error(\"Error: \" .. err, 0) end\nok, err = premake.checktools()\nif (not ok) then error(\"Error: \" .. err, 0) end\nok, err = injectplatform(_OPTIONS[\"platform\"])\nif (not ok) then error(\"Error: \" .. err, 0) end\nlocal profiler = newProfiler()\nif (nil ~= _OPTIONS[\"debug-profiler\"]) then\nprofiler:start()\nend\n" + "print(\"Building configurations...\")\npremake.bake.buildconfigs()\nif (nil ~= _OPTIONS[\"debug-profiler\"]) then\nprofiler:stop()\nlocal filePath = path.getabsolute(\"GENie-profiler-bake.txt\")\nprint(\"Writing debug-profiler report \" .. filePath .. \".\")\nlocal outfile = io.open(filePath, \"w+\")\nprofiler:report(outfile)\noutfile:close()\nend\nok, err = premake.checkprojects()\nif (not ok) then error(\"Error: \" .. err, 0) end\nprintf(\"Running action '%s'...\", action.trigger)\npremake.action.call(action.trigger)\nprint(\"Done.\")\nreturn 0\nend\n", 0 }; diff --git a/3rdparty/googletest/googlemock/docs/CookBook.md b/3rdparty/googletest/googlemock/docs/CookBook.md index c215b55121e..c52f1009d1d 100644 --- a/3rdparty/googletest/googlemock/docs/CookBook.md +++ b/3rdparty/googletest/googlemock/docs/CookBook.md @@ -2103,7 +2103,7 @@ For better readability, Google Mock also gives you: * `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument. As you may have realized, `InvokeWithoutArgs(...)` is just syntactic -sugar for `WithoutArgs(Inovke(...))`. +sugar for `WithoutArgs(Invoke(...))`. Here are more tips: diff --git a/3rdparty/googletest/googletest/docs/AdvancedGuide.md b/3rdparty/googletest/googletest/docs/AdvancedGuide.md index 7ba8d1219bd..93a65200dad 100644 --- a/3rdparty/googletest/googletest/docs/AdvancedGuide.md +++ b/3rdparty/googletest/googletest/docs/AdvancedGuide.md @@ -1571,15 +1571,14 @@ For technical reasons, there are some caveats: 1. _statement_ in `EXPECT_FATAL_FAILURE()` cannot reference local non-static variables or non-static members of `this` object. 1. _statement_ in `EXPECT_FATAL_FAILURE()` cannot return a value. -_Note:_ Google Test is designed with threads in mind. Once the +_Note:_ Google Test is designed with threads in mind. Once the synchronization primitives in `"gtest/internal/gtest-port.h"` have been implemented, Google Test will become thread-safe, meaning that -you can then use assertions in multiple threads concurrently. Before - -that, however, Google Test only supports single-threaded usage. Once +you can then use assertions in multiple threads concurrently. Before +that, however, Google Test only supports single-threaded usage. Once thread-safe, `EXPECT_FATAL_FAILURE()` and `EXPECT_NONFATAL_FAILURE()` will capture failures in the current thread only. If _statement_ -creates new threads, failures in these threads will be ignored. If +creates new threads, failures in these threads will be ignored. If you want to capture failures from all threads instead, you should use the following macros: diff --git a/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h b/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h index 7d6e4658194..0094ed5077e 100644 --- a/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h +++ b/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h @@ -2546,10 +2546,9 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value); // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); -const char* StringFromGTestEnv(const char* flag, const char* default_val); +std::string StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ - diff --git a/3rdparty/googletest/googletest/src/gtest-port.cc b/3rdparty/googletest/googletest/src/gtest-port.cc index 0162fac44be..e5bf3dd2be4 100644 --- a/3rdparty/googletest/googletest/src/gtest-port.cc +++ b/3rdparty/googletest/googletest/src/gtest-port.cc @@ -1226,13 +1226,33 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. -const char* StringFromGTestEnv(const char* flag, const char* default_value) { +std::string StringFromGTestEnv(const char* flag, const char* default_value) { #if defined(GTEST_GET_STRING_FROM_ENV_) return GTEST_GET_STRING_FROM_ENV_(flag, default_value); #endif // defined(GTEST_GET_STRING_FROM_ENV_) const std::string env_var = FlagToEnvVar(flag); - const char* const value = posix::GetEnv(env_var.c_str()); - return value == NULL ? default_value : value; + const char* value = posix::GetEnv(env_var.c_str()); + if (value != NULL) { + return value; + } + + // As a special case for the 'output' flag, if GTEST_OUTPUT is not + // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build + // system. The value of XML_OUTPUT_FILE is a filename without the + // "xml:" prefix of GTEST_OUTPUT. + // + // The net priority order after flag processing is thus: + // --gtest_output command line flag + // GTEST_OUTPUT environment variable + // XML_OUTPUT_FILE environment variable + // 'default_value' + if (strcmp(flag, "output") == 0) { + value = posix::GetEnv("XML_OUTPUT_FILE"); + if (value != NULL) { + return std::string("xml:") + value; + } + } + return default_value; } } // namespace internal diff --git a/3rdparty/googletest/googletest/test/gtest_env_var_test.py b/3rdparty/googletest/googletest/test/gtest_env_var_test.py index 1fc6ebe5f59..424075cfa37 100644 --- a/3rdparty/googletest/googletest/test/gtest_env_var_test.py +++ b/3rdparty/googletest/googletest/test/gtest_env_var_test.py @@ -87,6 +87,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') TestFlag('filter', 'FooTest.Bar', '*') + SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') @@ -98,6 +99,19 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('death_test_use_fork', '1', '0') TestFlag('stack_trace_depth', '0', '100') + def testXmlOutputFile(self): + """Tests that $XML_OUTPUT_FILE affects the output flag.""" + + SetEnvVar('GTEST_OUTPUT', None) + SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') + AssertEq('xml:tmp/bar.xml', GetFlag('output')) + + def testXmlOutputFileOverride(self): + """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT""" + + SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml') + SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') + AssertEq('xml:tmp/foo.xml', GetFlag('output')) if __name__ == '__main__': gtest_test_utils.Main() diff --git a/3rdparty/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json b/3rdparty/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json index a72739321a2..dbe5c758ee3 100644 --- a/3rdparty/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json +++ b/3rdparty/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json @@ -1,3 +1,3 @@ -{ - "type": "integer" +{ + "type": "integer" } \ No newline at end of file diff --git a/3rdparty/rapidjson/bin/jsonschema/remotes/integer.json b/3rdparty/rapidjson/bin/jsonschema/remotes/integer.json index a72739321a2..dbe5c758ee3 100644 --- a/3rdparty/rapidjson/bin/jsonschema/remotes/integer.json +++ b/3rdparty/rapidjson/bin/jsonschema/remotes/integer.json @@ -1,3 +1,3 @@ -{ - "type": "integer" +{ + "type": "integer" } \ No newline at end of file diff --git a/3rdparty/rapidjson/bin/jsonschema/remotes/subSchemas.json b/3rdparty/rapidjson/bin/jsonschema/remotes/subSchemas.json index 307669c4a0d..8b6d8f842fc 100644 --- a/3rdparty/rapidjson/bin/jsonschema/remotes/subSchemas.json +++ b/3rdparty/rapidjson/bin/jsonschema/remotes/subSchemas.json @@ -1,8 +1,8 @@ -{ - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/integer" - } +{ + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" + } } \ No newline at end of file diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json index dda27d4f108..6d4bff51cf3 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json @@ -1,82 +1,82 @@ -[ - { - "description": "additionalItems as schema", - "schema": { - "items": [], - "additionalItems": {"type": "integer"} - }, - "tests": [ - { - "description": "additional items match schema", - "data": [ 1, 2, 3, 4 ], - "valid": true - }, - { - "description": "additional items do not match schema", - "data": [ 1, 2, 3, "foo" ], - "valid": false - } - ] - }, - { - "description": "items is schema, no additionalItems", - "schema": { - "items": {}, - "additionalItems": false - }, - "tests": [ - { - "description": "all items match schema", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - } - ] - }, - { - "description": "array of items with no additionalItems", - "schema": { - "items": [{}, {}, {}], - "additionalItems": false - }, - "tests": [ - { - "description": "no additional items present", - "data": [ 1, 2, 3 ], - "valid": true - }, - { - "description": "additional items are not permitted", - "data": [ 1, 2, 3, 4 ], - "valid": false - } - ] - }, - { - "description": "additionalItems as false without items", - "schema": {"additionalItems": false}, - "tests": [ - { - "description": - "items defaults to empty schema so everything is valid", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - }, - { - "description": "ignores non-arrays", - "data": {"foo" : "bar"}, - "valid": true - } - ] - }, - { - "description": "additionalItems are allowed by default", - "schema": {"items": []}, - "tests": [ - { - "description": "only the first items are validated", - "data": [1, "foo", false], - "valid": true - } - ] - } -] +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ 1, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ 1, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": []}, + "tests": [ + { + "description": "only the first items are validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json index fc817daac47..40831f9e9aa 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json @@ -1,88 +1,88 @@ -[ - { - "description": - "additionalProperties being false does not allow other properties", - "schema": { - "properties": {"foo": {}, "bar": {}}, - "patternProperties": { "^v": {} }, - "additionalProperties": false - }, - "tests": [ - { - "description": "no additional properties is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "an additional property is invalid", - "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": [1, 2, 3], - "valid": true - }, - { - "description": "patternProperties are not additional properties", - "data": {"foo":1, "vroom": 2}, - "valid": true - } - ] - }, - { - "description": - "additionalProperties allows a schema which should validate", - "schema": { - "properties": {"foo": {}, "bar": {}}, - "additionalProperties": {"type": "boolean"} - }, - "tests": [ - { - "description": "no additional properties is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "an additional valid property is valid", - "data": {"foo" : 1, "bar" : 2, "quux" : true}, - "valid": true - }, - { - "description": "an additional invalid property is invalid", - "data": {"foo" : 1, "bar" : 2, "quux" : 12}, - "valid": false - } - ] - }, - { - "description": - "additionalProperties can exist by itself", - "schema": { - "additionalProperties": {"type": "boolean"} - }, - "tests": [ - { - "description": "an additional valid property is valid", - "data": {"foo" : true}, - "valid": true - }, - { - "description": "an additional invalid property is invalid", - "data": {"foo" : 1}, - "valid": false - } - ] - }, - { - "description": "additionalProperties are allowed by default", - "schema": {"properties": {"foo": {}, "bar": {}}}, - "tests": [ - { - "description": "additional properties are allowed", - "data": {"foo": 1, "bar": 2, "quux": true}, - "valid": true - } - ] - } -] +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/default.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/default.json index c2b76c62170..17629779fbe 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/default.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/default.json @@ -1,49 +1,49 @@ -[ - { - "description": "invalid type for default", - "schema": { - "properties": { - "foo": { - "type": "integer", - "default": [] - } - } - }, - "tests": [ - { - "description": "valid when property is specified", - "data": {"foo": 13}, - "valid": true - }, - { - "description": "still valid when the invalid default is used", - "data": {}, - "valid": true - } - ] - }, - { - "description": "invalid string value for default", - "schema": { - "properties": { - "bar": { - "type": "string", - "minLength": 4, - "default": "bad" - } - } - }, - "tests": [ - { - "description": "valid when property is specified", - "data": {"bar": "good"}, - "valid": true - }, - { - "description": "still valid when the invalid default is used", - "data": {}, - "valid": true - } - ] - } -] +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/dependencies.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/dependencies.json index 14b0cff8a76..2f6ae489aed 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/dependencies.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/dependencies.json @@ -1,108 +1,108 @@ -[ - { - "description": "dependencies", - "schema": { - "dependencies": {"bar": "foo"} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependant", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "with dependency", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": "foo", - "valid": true - } - ] - }, - { - "description": "multiple dependencies", - "schema": { - "dependencies": {"quux": ["foo", "bar"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependants", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "with dependencies", - "data": {"foo": 1, "bar": 2, "quux": 3}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"foo": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing other dependency", - "data": {"bar": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing both dependencies", - "data": {"quux": 1}, - "valid": false - } - ] - }, - { - "description": "multiple dependencies subschema", - "schema": { - "dependencies": { - "bar": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "integer"} - } - } - } - }, - "tests": [ - { - "description": "valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "wrong type", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "wrong type other", - "data": {"foo": 2, "bar": "quux"}, - "valid": false - }, - { - "description": "wrong type both", - "data": {"foo": "quux", "bar": "quux"}, - "valid": false - } - ] - } -] +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": "foo"} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/disallow.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/disallow.json index 75111afe7de..a5c9d90ccee 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/disallow.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/disallow.json @@ -1,80 +1,80 @@ -[ - { - "description": "disallow", - "schema": { - "disallow": "integer" - }, - "tests": [ - { - "description": "allowed", - "data": "foo", - "valid": true - }, - { - "description": "disallowed", - "data": 1, - "valid": false - } - ] - }, - { - "description": "multiple disallow", - "schema": { - "disallow": ["integer", "boolean"] - }, - "tests": [ - { - "description": "valid", - "data": "foo", - "valid": true - }, - { - "description": "mismatch", - "data": 1, - "valid": false - }, - { - "description": "other mismatch", - "data": true, - "valid": false - } - ] - }, - { - "description": "multiple disallow subschema", - "schema": { - "disallow": - ["string", - { - "type": "object", - "properties": { - "foo": { - "type": "string" - } - } - }] - }, - "tests": [ - { - "description": "match", - "data": 1, - "valid": true - }, - { - "description": "other match", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "mismatch", - "data": "foo", - "valid": false - }, - { - "description": "other mismatch", - "data": {"foo": "bar"}, - "valid": false - } - ] - } -] +[ + { + "description": "disallow", + "schema": { + "disallow": "integer" + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "multiple disallow", + "schema": { + "disallow": ["integer", "boolean"] + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "multiple disallow subschema", + "schema": { + "disallow": + ["string", + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + }] + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": "foo", + "valid": false + }, + { + "description": "other mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json index a9623989839..ef7cc148902 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json @@ -1,60 +1,60 @@ -[ - { - "description": "by int", - "schema": {"divisibleBy": 2}, - "tests": [ - { - "description": "int by int", - "data": 10, - "valid": true - }, - { - "description": "int by int fail", - "data": 7, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "foo", - "valid": true - } - ] - }, - { - "description": "by number", - "schema": {"divisibleBy": 1.5}, - "tests": [ - { - "description": "zero is divisible by anything (except 0)", - "data": 0, - "valid": true - }, - { - "description": "4.5 is divisible by 1.5", - "data": 4.5, - "valid": true - }, - { - "description": "35 is not divisible by 1.5", - "data": 35, - "valid": false - } - ] - }, - { - "description": "by small number", - "schema": {"divisibleBy": 0.0001}, - "tests": [ - { - "description": "0.0075 is divisible by 0.0001", - "data": 0.0075, - "valid": true - }, - { - "description": "0.00751 is not divisible by 0.0001", - "data": 0.00751, - "valid": false - } - ] - } -] +[ + { + "description": "by int", + "schema": {"divisibleBy": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"divisibleBy": 1.5}, + "tests": [ + { + "description": "zero is divisible by anything (except 0)", + "data": 0, + "valid": true + }, + { + "description": "4.5 is divisible by 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not divisible by 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"divisibleBy": 0.0001}, + "tests": [ + { + "description": "0.0075 is divisible by 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not divisible by 0.0001", + "data": 0.00751, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/enum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/enum.json index 01e8882de51..0c83f0804d0 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/enum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/enum.json @@ -1,71 +1,71 @@ -[ - { - "description": "simple enum validation", - "schema": {"enum": [1, 2, 3]}, - "tests": [ - { - "description": "one of the enum is valid", - "data": 1, - "valid": true - }, - { - "description": "something else is invalid", - "data": 4, - "valid": false - } - ] - }, - { - "description": "heterogeneous enum validation", - "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, - "tests": [ - { - "description": "one of the enum is valid", - "data": [], - "valid": true - }, - { - "description": "something else is invalid", - "data": null, - "valid": false - }, - { - "description": "objects are deep compared", - "data": {"foo": false}, - "valid": false - } - ] - }, - { - "description": "enums in properties", - "schema": { - "type":"object", - "properties": { - "foo": {"enum":["foo"]}, - "bar": {"enum":["bar"], "required":true} - } - }, - "tests": [ - { - "description": "both properties are valid", - "data": {"foo":"foo", "bar":"bar"}, - "valid": true - }, - { - "description": "missing optional property is valid", - "data": {"bar":"bar"}, - "valid": true - }, - { - "description": "missing required property is invalid", - "data": {"foo":"foo"}, - "valid": false - }, - { - "description": "missing all properties is invalid", - "data": {}, - "valid": false - } - ] - } -] +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"], "required":true} + } + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/extends.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/extends.json index c595184893e..909bce575ae 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/extends.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/extends.json @@ -1,94 +1,94 @@ -[ - { - "description": "extends", - "schema": { - "properties": {"bar": {"type": "integer", "required": true}}, - "extends": { - "properties": { - "foo": {"type": "string", "required": true} - } - } - }, - "tests": [ - { - "description": "extends", - "data": {"foo": "baz", "bar": 2}, - "valid": true - }, - { - "description": "mismatch extends", - "data": {"foo": "baz"}, - "valid": false - }, - { - "description": "mismatch extended", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "wrong type", - "data": {"foo": "baz", "bar": "quux"}, - "valid": false - } - ] - }, - { - "description": "multiple extends", - "schema": { - "properties": {"bar": {"type": "integer", "required": true}}, - "extends" : [ - { - "properties": { - "foo": {"type": "string", "required": true} - } - }, - { - "properties": { - "baz": {"type": "null", "required": true} - } - } - ] - }, - "tests": [ - { - "description": "valid", - "data": {"foo": "quux", "bar": 2, "baz": null}, - "valid": true - }, - { - "description": "mismatch first extends", - "data": {"bar": 2, "baz": null}, - "valid": false - }, - { - "description": "mismatch second extends", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "mismatch both", - "data": {"bar": 2}, - "valid": false - } - ] - }, - { - "description": "extends simple types", - "schema": { - "minimum": 20, - "extends": {"maximum": 30} - }, - "tests": [ - { - "description": "valid", - "data": 25, - "valid": true - }, - { - "description": "mismatch extends", - "data": 35, - "valid": false - } - ] - } -] +[ + { + "description": "extends", + "schema": { + "properties": {"bar": {"type": "integer", "required": true}}, + "extends": { + "properties": { + "foo": {"type": "string", "required": true} + } + } + }, + "tests": [ + { + "description": "extends", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch extends", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch extended", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "multiple extends", + "schema": { + "properties": {"bar": {"type": "integer", "required": true}}, + "extends" : [ + { + "properties": { + "foo": {"type": "string", "required": true} + } + }, + { + "properties": { + "baz": {"type": "null", "required": true} + } + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch first extends", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second extends", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "extends simple types", + "schema": { + "minimum": 20, + "extends": {"maximum": 30} + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch extends", + "data": 35, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/items.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/items.json index 1683e440f9a..f5e18a13848 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/items.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/items.json @@ -1,46 +1,46 @@ -[ - { - "description": "a schema given for items", - "schema": { - "items": {"type": "integer"} - }, - "tests": [ - { - "description": "valid items", - "data": [ 1, 2, 3 ], - "valid": true - }, - { - "description": "wrong type of items", - "data": [1, "x"], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": {"foo" : "bar"}, - "valid": true - } - ] - }, - { - "description": "an array of schemas for items", - "schema": { - "items": [ - {"type": "integer"}, - {"type": "string"} - ] - }, - "tests": [ - { - "description": "correct types", - "data": [ 1, "foo" ], - "valid": true - }, - { - "description": "wrong types", - "data": [ "foo", 1 ], - "valid": false - } - ] - } -] +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxItems.json index 5f5c963b656..3b53a6b371a 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxItems.json @@ -1,28 +1,28 @@ -[ - { - "description": "maxItems validation", - "schema": {"maxItems": 2}, - "tests": [ - { - "description": "shorter is valid", - "data": [1], - "valid": true - }, - { - "description": "exact length is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "too long is invalid", - "data": [1, 2, 3], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": "foobar", - "valid": true - } - ] - } -] +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxLength.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxLength.json index 5c5fd71708a..4de42bcaba0 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxLength.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maxLength.json @@ -1,33 +1,33 @@ -[ - { - "description": "maxLength validation", - "schema": {"maxLength": 2}, - "tests": [ - { - "description": "shorter is valid", - "data": "f", - "valid": true - }, - { - "description": "exact length is valid", - "data": "fo", - "valid": true - }, - { - "description": "too long is invalid", - "data": "foo", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 10, - "valid": true - }, - { - "description": "two supplementary Unicode code points is long enough", - "data": "\uD83D\uDCA9\uD83D\uDCA9", - "valid": true - } - ] - } -] +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 10, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maximum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maximum.json index 6c069bb29b4..86c7b89c9a9 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maximum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/maximum.json @@ -1,42 +1,42 @@ -[ - { - "description": "maximum validation", - "schema": {"maximum": 3.0}, - "tests": [ - { - "description": "below the maximum is valid", - "data": 2.6, - "valid": true - }, - { - "description": "above the maximum is invalid", - "data": 3.5, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "x", - "valid": true - } - ] - }, - { - "description": "exclusiveMaximum validation", - "schema": { - "maximum": 3.0, - "exclusiveMaximum": true - }, - "tests": [ - { - "description": "below the maximum is still valid", - "data": 2.2, - "valid": true - }, - { - "description": "boundary point is invalid", - "data": 3.0, - "valid": false - } - ] - } -] +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minItems.json index df8e0981c40..ed5118815ee 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minItems.json @@ -1,28 +1,28 @@ -[ - { - "description": "minItems validation", - "schema": {"minItems": 1}, - "tests": [ - { - "description": "longer is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "exact length is valid", - "data": [1], - "valid": true - }, - { - "description": "too short is invalid", - "data": [], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": "", - "valid": true - } - ] - } -] +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minLength.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minLength.json index 96fa0c662f7..3f09158deef 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minLength.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minLength.json @@ -1,33 +1,33 @@ -[ - { - "description": "minLength validation", - "schema": {"minLength": 2}, - "tests": [ - { - "description": "longer is valid", - "data": "foo", - "valid": true - }, - { - "description": "exact length is valid", - "data": "fo", - "valid": true - }, - { - "description": "too short is invalid", - "data": "f", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 1, - "valid": true - }, - { - "description": "one supplementary Unicode code point is not long enough", - "data": "\uD83D\uDCA9", - "valid": false - } - ] - } -] +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minimum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minimum.json index 0c87f45a9c3..d5bf000bcc6 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minimum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/minimum.json @@ -1,42 +1,42 @@ -[ - { - "description": "minimum validation", - "schema": {"minimum": 1.1}, - "tests": [ - { - "description": "above the minimum is valid", - "data": 2.6, - "valid": true - }, - { - "description": "below the minimum is invalid", - "data": 0.6, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "x", - "valid": true - } - ] - }, - { - "description": "exclusiveMinimum validation", - "schema": { - "minimum": 1.1, - "exclusiveMinimum": true - }, - "tests": [ - { - "description": "above the minimum is still valid", - "data": 1.2, - "valid": true - }, - { - "description": "boundary point is invalid", - "data": 1.1, - "valid": false - } - ] - } -] +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json index 31df120efe7..ccc7c17fe8d 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json @@ -1,107 +1,107 @@ -[ - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "a bignum is an integer", - "data": 12345678910111213141516171819202122232425262728293031, - "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "a negative bignum is an integer", - "data": -12345678910111213141516171819202122232425262728293031, - "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a negative bignum is a number", - "data": -98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "string", - "schema": {"type": "string"}, - "tests": [ - { - "description": "a bignum is not a string", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": false - } - ] - }, - { - "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, - "tests": [ - { - "description": "comparison works for high numbers", - "data": 18446744073709551600, - "valid": true - } - ] - }, - { - "description": "float comparison with high precision", - "schema": { - "maximum": 972783798187987123879878123.18878137, - "exclusiveMaximum": true - }, - "tests": [ - { - "description": "comparison works for high numbers", - "data": 972783798187987123879878123.188781371, - "valid": false - } - ] - }, - { - "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, - "tests": [ - { - "description": "comparison works for very negative numbers", - "data": -18446744073709551600, - "valid": true - } - ] - }, - { - "description": "float comparison with high precision on negative numbers", - "schema": { - "minimum": -972783798187987123879878123.18878137, - "exclusiveMinimum": true - }, - "tests": [ - { - "description": "comparison works for very negative numbers", - "data": -972783798187987123879878123.188781371, - "valid": false - } - ] - } -] +[ + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": {"type": "string"}, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"maximum": 18446744073709551615}, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "maximum": 972783798187987123879878123.18878137, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"minimum": -18446744073709551615}, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "minimum": -972783798187987123879878123.18878137, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/format.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/format.json index 4708088b7d7..3ca7319dda0 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/format.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/format.json @@ -1,222 +1,222 @@ -[ - { - "description": "validation of regular expressions", - "schema": {"format": "regex"}, - "tests": [ - { - "description": "a valid regular expression", - "data": "([abc])+\\s+$", - "valid": true - }, - { - "description": "a regular expression with unclosed parens is invalid", - "data": "^(abc]", - "valid": false - } - ] - }, - { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, - "tests": [ - { - "description": "a valid date-time string", - "data": "1963-06-19T08:30:06.283185Z", - "valid": true - }, - { - "description": "an invalid date-time string", - "data": "06/19/1963 08:30:06 PST", - "valid": false - }, - { - "description": "only RFC3339 not all of ISO 8601 are valid", - "data": "2013-350T01:01:01", - "valid": false - } - ] - }, - { - "description": "validation of date strings", - "schema": {"format": "date"}, - "tests": [ - { - "description": "a valid date string", - "data": "1963-06-19", - "valid": true - }, - { - "description": "an invalid date string", - "data": "06/19/1963", - "valid": false - } - ] - }, - { - "description": "validation of time strings", - "schema": {"format": "time"}, - "tests": [ - { - "description": "a valid time string", - "data": "08:30:06", - "valid": true - }, - { - "description": "an invalid time string", - "data": "8:30 AM", - "valid": false - } - ] - }, - { - "description": "validation of URIs", - "schema": {"format": "uri"}, - "tests": [ - { - "description": "a valid URI", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid protocol-relative URI", - "data": "//foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "an invalid URI", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "an invalid URI though valid URI reference", - "data": "abc", - "valid": false - } - ] - }, - { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, - "tests": [ - { - "description": "a valid e-mail address", - "data": "joe.bloggs@example.com", - "valid": true - }, - { - "description": "an invalid e-mail address", - "data": "2962", - "valid": false - } - ] - }, - { - "description": "validation of IP addresses", - "schema": {"format": "ip-address"}, - "tests": [ - { - "description": "a valid IP address", - "data": "192.168.0.1", - "valid": true - }, - { - "description": "an IP address with too many components", - "data": "127.0.0.0.1", - "valid": false - }, - { - "description": "an IP address with out-of-range values", - "data": "256.256.256.256", - "valid": false - } - ] - }, - { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, - "tests": [ - { - "description": "a valid IPv6 address", - "data": "::1", - "valid": true - }, - { - "description": "an IPv6 address with out-of-range values", - "data": "12345::", - "valid": false - }, - { - "description": "an IPv6 address with too many components", - "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", - "valid": false - }, - { - "description": "an IPv6 address containing illegal characters", - "data": "::laptop", - "valid": false - } - ] - }, - { - "description": "validation of host names", - "schema": {"format": "host-name"}, - "tests": [ - { - "description": "a valid host name", - "data": "www.example.com", - "valid": true - }, - { - "description": "a host name starting with an illegal character", - "data": "-a-host-name-that-starts-with--", - "valid": false - }, - { - "description": "a host name containing illegal characters", - "data": "not_a_valid_host_name", - "valid": false - }, - { - "description": "a host name with a component too long", - "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", - "valid": false - } - ] - }, - { - "description": "validation of CSS colors", - "schema": {"format": "color"}, - "tests": [ - { - "description": "a valid CSS color name", - "data": "fuchsia", - "valid": true - }, - { - "description": "a valid six-digit CSS color code", - "data": "#CC8899", - "valid": true - }, - { - "description": "a valid three-digit CSS color code", - "data": "#C89", - "valid": true - }, - { - "description": "an invalid CSS color code", - "data": "#00332520", - "valid": false - }, - { - "description": "an invalid CSS color name", - "data": "puce", - "valid": false - }, - { - "description": "a CSS color name containing invalid characters", - "data": "light_grayish_red-violet", - "valid": false - } - ] - } -] +[ + { + "description": "validation of regular expressions", + "schema": {"format": "regex"}, + "tests": [ + { + "description": "a valid regular expression", + "data": "([abc])+\\s+$", + "valid": true + }, + { + "description": "a regular expression with unclosed parens is invalid", + "data": "^(abc]", + "valid": false + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + } + ] + }, + { + "description": "validation of date strings", + "schema": {"format": "date"}, + "tests": [ + { + "description": "a valid date string", + "data": "1963-06-19", + "valid": true + }, + { + "description": "an invalid date string", + "data": "06/19/1963", + "valid": false + } + ] + }, + { + "description": "validation of time strings", + "schema": {"format": "time"}, + "tests": [ + { + "description": "a valid time string", + "data": "08:30:06", + "valid": true + }, + { + "description": "an invalid time string", + "data": "8:30 AM", + "valid": false + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ip-address"}, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + } + ] + }, + { + "description": "validation of host names", + "schema": {"format": "host-name"}, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + } + ] + }, + { + "description": "validation of CSS colors", + "schema": {"format": "color"}, + "tests": [ + { + "description": "a valid CSS color name", + "data": "fuchsia", + "valid": true + }, + { + "description": "a valid six-digit CSS color code", + "data": "#CC8899", + "valid": true + }, + { + "description": "a valid three-digit CSS color code", + "data": "#C89", + "valid": true + }, + { + "description": "an invalid CSS color code", + "data": "#00332520", + "valid": false + }, + { + "description": "an invalid CSS color name", + "data": "puce", + "valid": false + }, + { + "description": "a CSS color name containing invalid characters", + "data": "light_grayish_red-violet", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json index 8c28e4af5af..03fe97724c0 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json @@ -1,18 +1,18 @@ -[ - { - "description": "ECMA 262 regex dialect recognition", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "[^] is a valid regex", - "data": "[^]", - "valid": true - }, - { - "description": "ECMA 262 has no support for lookbehind", - "data": "(?<=foo)bar", - "valid": false - } - ] - } -] +[ + { + "description": "ECMA 262 regex dialect recognition", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "[^] is a valid regex", + "data": "[^]", + "valid": true + }, + { + "description": "ECMA 262 has no support for lookbehind", + "data": "(?<=foo)bar", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json index 445fffc5d61..9b50ea27769 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json @@ -1,15 +1,15 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float is not an integer even without fractional part", - "data": 1.0, - "valid": false - } - ] - } -] +[ + { + "description": "some languages do not distinguish between different types of numeric value", + "schema": { + "type": "integer" + }, + "tests": [ + { + "description": "a float is not an integer even without fractional part", + "data": 1.0, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/pattern.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/pattern.json index 70b5e10950a..25e72997314 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/pattern.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/pattern.json @@ -1,34 +1,34 @@ -[ - { - "description": "pattern validation", - "schema": {"pattern": "^a*$"}, - "tests": [ - { - "description": "a matching pattern is valid", - "data": "aaa", - "valid": true - }, - { - "description": "a non-matching pattern is invalid", - "data": "abc", - "valid": false - }, - { - "description": "ignores non-strings", - "data": true, - "valid": true - } - ] - }, - { - "description": "pattern is not anchored", - "schema": {"pattern": "a+"}, - "tests": [ - { - "description": "matches a substring", - "data": "xxaayy", - "valid": true - } - ] - } -] +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json index 8d7cea77577..18586e5daba 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json @@ -1,110 +1,110 @@ -[ - { - "description": - "patternProperties validates properties matching a regex", - "schema": { - "patternProperties": { - "f.*o": {"type": "integer"} - } - }, - "tests": [ - { - "description": "a single valid match is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "multiple valid matches is valid", - "data": {"foo": 1, "foooooo" : 2}, - "valid": true - }, - { - "description": "a single invalid match is invalid", - "data": {"foo": "bar", "fooooo": 2}, - "valid": false - }, - { - "description": "multiple invalid matches is invalid", - "data": {"foo": "bar", "foooooo" : "baz"}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": 12, - "valid": true - } - ] - }, - { - "description": "multiple simultaneous patternProperties are validated", - "schema": { - "patternProperties": { - "a*": {"type": "integer"}, - "aaa*": {"maximum": 20} - } - }, - "tests": [ - { - "description": "a single valid match is valid", - "data": {"a": 21}, - "valid": true - }, - { - "description": "a simultaneous match is valid", - "data": {"aaaa": 18}, - "valid": true - }, - { - "description": "multiple matches is valid", - "data": {"a": 21, "aaaa": 18}, - "valid": true - }, - { - "description": "an invalid due to one is invalid", - "data": {"a": "bar"}, - "valid": false - }, - { - "description": "an invalid due to the other is invalid", - "data": {"aaaa": 31}, - "valid": false - }, - { - "description": "an invalid due to both is invalid", - "data": {"aaa": "foo", "aaaa": 31}, - "valid": false - } - ] - }, - { - "description": "regexes are not anchored by default and are case sensitive", - "schema": { - "patternProperties": { - "[0-9]{2,}": { "type": "boolean" }, - "X_": { "type": "string" } - } - }, - "tests": [ - { - "description": "non recognized members are ignored", - "data": { "answer 1": "42" }, - "valid": true - }, - { - "description": "recognized members are accounted for", - "data": { "a31b": null }, - "valid": false - }, - { - "description": "regexes are case sensitive", - "data": { "a_x_3": 3 }, - "valid": true - }, - { - "description": "regexes are case sensitive, 2", - "data": { "a_X_3": 3 }, - "valid": false - } - ] - } -] +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/properties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/properties.json index 8bda460ce16..cd1644dcd91 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/properties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/properties.json @@ -1,92 +1,92 @@ -[ - { - "description": "object properties validation", - "schema": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "string"} - } - }, - "tests": [ - { - "description": "both properties present and valid is valid", - "data": {"foo": 1, "bar": "baz"}, - "valid": true - }, - { - "description": "one property invalid is invalid", - "data": {"foo": 1, "bar": {}}, - "valid": false - }, - { - "description": "both properties invalid is invalid", - "data": {"foo": [], "bar": {}}, - "valid": false - }, - { - "description": "doesn't invalidate other properties", - "data": {"quux": []}, - "valid": true - }, - { - "description": "ignores non-objects", - "data": [], - "valid": true - } - ] - }, - { - "description": - "properties, patternProperties, additionalProperties interaction", - "schema": { - "properties": { - "foo": {"type": "array", "maxItems": 3}, - "bar": {"type": "array"} - }, - "patternProperties": {"f.o": {"minItems": 2}}, - "additionalProperties": {"type": "integer"} - }, - "tests": [ - { - "description": "property validates property", - "data": {"foo": [1, 2]}, - "valid": true - }, - { - "description": "property invalidates property", - "data": {"foo": [1, 2, 3, 4]}, - "valid": false - }, - { - "description": "patternProperty invalidates property", - "data": {"foo": []}, - "valid": false - }, - { - "description": "patternProperty validates nonproperty", - "data": {"fxo": [1, 2]}, - "valid": true - }, - { - "description": "patternProperty invalidates nonproperty", - "data": {"fxo": []}, - "valid": false - }, - { - "description": "additionalProperty ignores property", - "data": {"bar": []}, - "valid": true - }, - { - "description": "additionalProperty validates others", - "data": {"quux": 3}, - "valid": true - }, - { - "description": "additionalProperty invalidates others", - "data": {"quux": "foo"}, - "valid": false - } - ] - } -] +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/ref.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/ref.json index 124edf6b41c..903ecb6bce1 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/ref.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/ref.json @@ -1,159 +1,159 @@ -[ - { - "description": "root pointer ref", - "schema": { - "properties": { - "foo": {"$ref": "#"} - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "match", - "data": {"foo": false}, - "valid": true - }, - { - "description": "recursive match", - "data": {"foo": {"foo": false}}, - "valid": true - }, - { - "description": "mismatch", - "data": {"bar": false}, - "valid": false - }, - { - "description": "recursive mismatch", - "data": {"foo": {"bar": false}}, - "valid": false - } - ] - }, - { - "description": "relative pointer ref to object", - "schema": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"$ref": "#/properties/foo"} - } - }, - "tests": [ - { - "description": "match", - "data": {"bar": 3}, - "valid": true - }, - { - "description": "mismatch", - "data": {"bar": true}, - "valid": false - } - ] - }, - { - "description": "relative pointer ref to array", - "schema": { - "items": [ - {"type": "integer"}, - {"$ref": "#/items/0"} - ] - }, - "tests": [ - { - "description": "match array", - "data": [1, 2], - "valid": true - }, - { - "description": "mismatch array", - "data": [1, "foo"], - "valid": false - } - ] - }, - { - "description": "escaped pointer ref", - "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, - "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} - } - }, - "tests": [ - { - "description": "slash invalid", - "data": {"slash": "aoeu"}, - "valid": false - }, - { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, - "valid": false - }, - { - "description": "percent invalid", - "data": {"percent": "aoeu"}, - "valid": false - }, - { - "description": "slash valid", - "data": {"slash": 123}, - "valid": true - }, - { - "description": "tilda valid", - "data": {"tilda": 123}, - "valid": true - }, - { - "description": "percent valid", - "data": {"percent": 123}, - "valid": true - } - ] - }, - { - "description": "nested refs", - "schema": { - "definitions": { - "a": {"type": "integer"}, - "b": {"$ref": "#/definitions/a"}, - "c": {"$ref": "#/definitions/b"} - }, - "$ref": "#/definitions/c" - }, - "tests": [ - { - "description": "nested ref valid", - "data": 5, - "valid": true - }, - { - "description": "nested ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "remote ref, containing refs itself", - "schema": {"$ref": "http://json-schema.org/draft-03/schema#"}, - "tests": [ - { - "description": "remote ref valid", - "data": {"items": {"type": "integer"}}, - "valid": true - }, - { - "description": "remote ref invalid", - "data": {"items": {"type": 1}}, - "valid": false - } - ] - } -] +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "items": [ + {"type": "integer"}, + {"$ref": "#/items/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda invalid", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilda valid", + "data": {"tilda": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": {"$ref": "http://json-schema.org/draft-03/schema#"}, + "tests": [ + { + "description": "remote ref valid", + "data": {"items": {"type": "integer"}}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"items": {"type": 1}}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/refRemote.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/refRemote.json index 85d136c8400..4ca804732c9 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/refRemote.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/refRemote.json @@ -1,74 +1,74 @@ -[ - { - "description": "remote ref", - "schema": {"$ref": "http://localhost:1234/integer.json"}, - "tests": [ - { - "description": "remote ref valid", - "data": 1, - "valid": true - }, - { - "description": "remote ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, - "tests": [ - { - "description": "remote fragment valid", - "data": 1, - "valid": true - }, - { - "description": "remote fragment invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "ref within remote ref", - "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" - }, - "tests": [ - { - "description": "ref within ref valid", - "data": 1, - "valid": true - }, - { - "description": "ref within ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "change resolution scope", - "schema": { - "id": "http://localhost:1234/", - "items": { - "id": "folder/", - "items": {"$ref": "folderInteger.json"} - } - }, - "tests": [ - { - "description": "changed scope ref valid", - "data": [[1]], - "valid": true - }, - { - "description": "changed scope ref invalid", - "data": [["a"]], - "valid": false - } - ] - } -] +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "change resolution scope", + "schema": { + "id": "http://localhost:1234/", + "items": { + "id": "folder/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "changed scope ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "changed scope ref invalid", + "data": [["a"]], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/required.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/required.json index 6f71c77d235..aaaf0242737 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/required.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/required.json @@ -1,53 +1,53 @@ -[ - { - "description": "required validation", - "schema": { - "properties": { - "foo": {"required" : true}, - "bar": {} - } - }, - "tests": [ - { - "description": "present required property is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "non-present required property is invalid", - "data": {"bar": 1}, - "valid": false - } - ] - }, - { - "description": "required default validation", - "schema": { - "properties": { - "foo": {} - } - }, - "tests": [ - { - "description": "not required by default", - "data": {}, - "valid": true - } - ] - }, - { - "description": "required explicitly false validation", - "schema": { - "properties": { - "foo": {"required": false} - } - }, - "tests": [ - { - "description": "not required if required is false", - "data": {}, - "valid": true - } - ] - } -] +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {"required" : true}, + "bar": {} + } + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required explicitly false validation", + "schema": { + "properties": { + "foo": {"required": false} + } + }, + "tests": [ + { + "description": "not required if required is false", + "data": {}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/type.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/type.json index e0495af9d03..337da1206da 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/type.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/type.json @@ -1,474 +1,474 @@ -[ - { - "description": "integer type matches integers", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "an integer is an integer", - "data": 1, - "valid": true - }, - { - "description": "a float is not an integer", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an integer", - "data": "foo", - "valid": false - }, - { - "description": "an object is not an integer", - "data": {}, - "valid": false - }, - { - "description": "an array is not an integer", - "data": [], - "valid": false - }, - { - "description": "a boolean is not an integer", - "data": true, - "valid": false - }, - { - "description": "null is not an integer", - "data": null, - "valid": false - } - ] - }, - { - "description": "number type matches numbers", - "schema": {"type": "number"}, - "tests": [ - { - "description": "an integer is a number", - "data": 1, - "valid": true - }, - { - "description": "a float is a number", - "data": 1.1, - "valid": true - }, - { - "description": "a string is not a number", - "data": "foo", - "valid": false - }, - { - "description": "an object is not a number", - "data": {}, - "valid": false - }, - { - "description": "an array is not a number", - "data": [], - "valid": false - }, - { - "description": "a boolean is not a number", - "data": true, - "valid": false - }, - { - "description": "null is not a number", - "data": null, - "valid": false - } - ] - }, - { - "description": "string type matches strings", - "schema": {"type": "string"}, - "tests": [ - { - "description": "1 is not a string", - "data": 1, - "valid": false - }, - { - "description": "a float is not a string", - "data": 1.1, - "valid": false - }, - { - "description": "a string is a string", - "data": "foo", - "valid": true - }, - { - "description": "an object is not a string", - "data": {}, - "valid": false - }, - { - "description": "an array is not a string", - "data": [], - "valid": false - }, - { - "description": "a boolean is not a string", - "data": true, - "valid": false - }, - { - "description": "null is not a string", - "data": null, - "valid": false - } - ] - }, - { - "description": "object type matches objects", - "schema": {"type": "object"}, - "tests": [ - { - "description": "an integer is not an object", - "data": 1, - "valid": false - }, - { - "description": "a float is not an object", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an object", - "data": "foo", - "valid": false - }, - { - "description": "an object is an object", - "data": {}, - "valid": true - }, - { - "description": "an array is not an object", - "data": [], - "valid": false - }, - { - "description": "a boolean is not an object", - "data": true, - "valid": false - }, - { - "description": "null is not an object", - "data": null, - "valid": false - } - ] - }, - { - "description": "array type matches arrays", - "schema": {"type": "array"}, - "tests": [ - { - "description": "an integer is not an array", - "data": 1, - "valid": false - }, - { - "description": "a float is not an array", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an array", - "data": "foo", - "valid": false - }, - { - "description": "an object is not an array", - "data": {}, - "valid": false - }, - { - "description": "an array is an array", - "data": [], - "valid": true - }, - { - "description": "a boolean is not an array", - "data": true, - "valid": false - }, - { - "description": "null is not an array", - "data": null, - "valid": false - } - ] - }, - { - "description": "boolean type matches booleans", - "schema": {"type": "boolean"}, - "tests": [ - { - "description": "an integer is not a boolean", - "data": 1, - "valid": false - }, - { - "description": "a float is not a boolean", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not a boolean", - "data": "foo", - "valid": false - }, - { - "description": "an object is not a boolean", - "data": {}, - "valid": false - }, - { - "description": "an array is not a boolean", - "data": [], - "valid": false - }, - { - "description": "a boolean is a boolean", - "data": true, - "valid": true - }, - { - "description": "null is not a boolean", - "data": null, - "valid": false - } - ] - }, - { - "description": "null type matches only the null object", - "schema": {"type": "null"}, - "tests": [ - { - "description": "an integer is not null", - "data": 1, - "valid": false - }, - { - "description": "a float is not null", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not null", - "data": "foo", - "valid": false - }, - { - "description": "an object is not null", - "data": {}, - "valid": false - }, - { - "description": "an array is not null", - "data": [], - "valid": false - }, - { - "description": "a boolean is not null", - "data": true, - "valid": false - }, - { - "description": "null is null", - "data": null, - "valid": true - } - ] - }, - { - "description": "any type matches any type", - "schema": {"type": "any"}, - "tests": [ - { - "description": "any type includes integers", - "data": 1, - "valid": true - }, - { - "description": "any type includes float", - "data": 1.1, - "valid": true - }, - { - "description": "any type includes string", - "data": "foo", - "valid": true - }, - { - "description": "any type includes object", - "data": {}, - "valid": true - }, - { - "description": "any type includes array", - "data": [], - "valid": true - }, - { - "description": "any type includes boolean", - "data": true, - "valid": true - }, - { - "description": "any type includes null", - "data": null, - "valid": true - } - ] - }, - { - "description": "multiple types can be specified in an array", - "schema": {"type": ["integer", "string"]}, - "tests": [ - { - "description": "an integer is valid", - "data": 1, - "valid": true - }, - { - "description": "a string is valid", - "data": "foo", - "valid": true - }, - { - "description": "a float is invalid", - "data": 1.1, - "valid": false - }, - { - "description": "an object is invalid", - "data": {}, - "valid": false - }, - { - "description": "an array is invalid", - "data": [], - "valid": false - }, - { - "description": "a boolean is invalid", - "data": true, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - } - ] - }, - { - "description": "types can include schemas", - "schema": { - "type": [ - "array", - {"type": "object"} - ] - }, - "tests": [ - { - "description": "an integer is invalid", - "data": 1, - "valid": false - }, - { - "description": "a string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "a float is invalid", - "data": 1.1, - "valid": false - }, - { - "description": "an object is valid", - "data": {}, - "valid": true - }, - { - "description": "an array is valid", - "data": [], - "valid": true - }, - { - "description": "a boolean is invalid", - "data": true, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - } - ] - }, - { - "description": - "when types includes a schema it should fully validate the schema", - "schema": { - "type": [ - "integer", - { - "properties": { - "foo": {"type": "null"} - } - } - ] - }, - "tests": [ - { - "description": "an integer is valid", - "data": 1, - "valid": true - }, - { - "description": "an object is valid only if it is fully valid", - "data": {"foo": null}, - "valid": true - }, - { - "description": "an object is invalid otherwise", - "data": {"foo": "bar"}, - "valid": false - } - ] - }, - { - "description": "types from separate schemas are merged", - "schema": { - "type": [ - {"type": ["string"]}, - {"type": ["array", "null"]} - ] - }, - "tests": [ - { - "description": "an integer is invalid", - "data": 1, - "valid": false - }, - { - "description": "a string is valid", - "data": "foo", - "valid": true - }, - { - "description": "an array is valid", - "data": [1, 2, 3], - "valid": true - } - ] - } -] +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "any type matches any type", + "schema": {"type": "any"}, + "tests": [ + { + "description": "any type includes integers", + "data": 1, + "valid": true + }, + { + "description": "any type includes float", + "data": 1.1, + "valid": true + }, + { + "description": "any type includes string", + "data": "foo", + "valid": true + }, + { + "description": "any type includes object", + "data": {}, + "valid": true + }, + { + "description": "any type includes array", + "data": [], + "valid": true + }, + { + "description": "any type includes boolean", + "data": true, + "valid": true + }, + { + "description": "any type includes null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "types can include schemas", + "schema": { + "type": [ + "array", + {"type": "object"} + ] + }, + "tests": [ + { + "description": "an integer is invalid", + "data": 1, + "valid": false + }, + { + "description": "a string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is valid", + "data": {}, + "valid": true + }, + { + "description": "an array is valid", + "data": [], + "valid": true + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": + "when types includes a schema it should fully validate the schema", + "schema": { + "type": [ + "integer", + { + "properties": { + "foo": {"type": "null"} + } + } + ] + }, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "an object is valid only if it is fully valid", + "data": {"foo": null}, + "valid": true + }, + { + "description": "an object is invalid otherwise", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "types from separate schemas are merged", + "schema": { + "type": [ + {"type": ["string"]}, + {"type": ["array", "null"]} + ] + }, + "tests": [ + { + "description": "an integer is invalid", + "data": 1, + "valid": false + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "an array is valid", + "data": [1, 2, 3], + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json index f54133987e4..c1f4ab99c9a 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json @@ -1,79 +1,79 @@ -[ - { - "description": "uniqueItems validation", - "schema": {"uniqueItems": true}, - "tests": [ - { - "description": "unique array of integers is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "non-unique array of integers is invalid", - "data": [1, 1], - "valid": false - }, - { - "description": "numbers are unique if mathematically unequal", - "data": [1.0, 1.00, 1], - "valid": false - }, - { - "description": "unique array of objects is valid", - "data": [{"foo": "bar"}, {"foo": "baz"}], - "valid": true - }, - { - "description": "non-unique array of objects is invalid", - "data": [{"foo": "bar"}, {"foo": "bar"}], - "valid": false - }, - { - "description": "unique array of nested objects is valid", - "data": [ - {"foo": {"bar" : {"baz" : true}}}, - {"foo": {"bar" : {"baz" : false}}} - ], - "valid": true - }, - { - "description": "non-unique array of nested objects is invalid", - "data": [ - {"foo": {"bar" : {"baz" : true}}}, - {"foo": {"bar" : {"baz" : true}}} - ], - "valid": false - }, - { - "description": "unique array of arrays is valid", - "data": [["foo"], ["bar"]], - "valid": true - }, - { - "description": "non-unique array of arrays is invalid", - "data": [["foo"], ["foo"]], - "valid": false - }, - { - "description": "1 and true are unique", - "data": [1, true], - "valid": true - }, - { - "description": "0 and false are unique", - "data": [0, false], - "valid": true - }, - { - "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], - "valid": true - }, - { - "description": "non-unique heterogeneous types are invalid", - "data": [{}, [1], true, null, {}, 1], - "valid": false - } - ] - } -] +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json index ceb42549c2c..521745c8d6e 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json @@ -1,82 +1,82 @@ -[ - { - "description": "additionalItems as schema", - "schema": { - "items": [{}], - "additionalItems": {"type": "integer"} - }, - "tests": [ - { - "description": "additional items match schema", - "data": [ null, 2, 3, 4 ], - "valid": true - }, - { - "description": "additional items do not match schema", - "data": [ null, 2, 3, "foo" ], - "valid": false - } - ] - }, - { - "description": "items is schema, no additionalItems", - "schema": { - "items": {}, - "additionalItems": false - }, - "tests": [ - { - "description": "all items match schema", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - } - ] - }, - { - "description": "array of items with no additionalItems", - "schema": { - "items": [{}, {}, {}], - "additionalItems": false - }, - "tests": [ - { - "description": "no additional items present", - "data": [ 1, 2, 3 ], - "valid": true - }, - { - "description": "additional items are not permitted", - "data": [ 1, 2, 3, 4 ], - "valid": false - } - ] - }, - { - "description": "additionalItems as false without items", - "schema": {"additionalItems": false}, - "tests": [ - { - "description": - "items defaults to empty schema so everything is valid", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - }, - { - "description": "ignores non-arrays", - "data": {"foo" : "bar"}, - "valid": true - } - ] - }, - { - "description": "additionalItems are allowed by default", - "schema": {"items": [{"type": "integer"}]}, - "tests": [ - { - "description": "only the first item is validated", - "data": [1, "foo", false], - "valid": true - } - ] - } -] +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [{}], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ null, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ null, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json index fc817daac47..40831f9e9aa 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json @@ -1,88 +1,88 @@ -[ - { - "description": - "additionalProperties being false does not allow other properties", - "schema": { - "properties": {"foo": {}, "bar": {}}, - "patternProperties": { "^v": {} }, - "additionalProperties": false - }, - "tests": [ - { - "description": "no additional properties is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "an additional property is invalid", - "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": [1, 2, 3], - "valid": true - }, - { - "description": "patternProperties are not additional properties", - "data": {"foo":1, "vroom": 2}, - "valid": true - } - ] - }, - { - "description": - "additionalProperties allows a schema which should validate", - "schema": { - "properties": {"foo": {}, "bar": {}}, - "additionalProperties": {"type": "boolean"} - }, - "tests": [ - { - "description": "no additional properties is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "an additional valid property is valid", - "data": {"foo" : 1, "bar" : 2, "quux" : true}, - "valid": true - }, - { - "description": "an additional invalid property is invalid", - "data": {"foo" : 1, "bar" : 2, "quux" : 12}, - "valid": false - } - ] - }, - { - "description": - "additionalProperties can exist by itself", - "schema": { - "additionalProperties": {"type": "boolean"} - }, - "tests": [ - { - "description": "an additional valid property is valid", - "data": {"foo" : true}, - "valid": true - }, - { - "description": "an additional invalid property is invalid", - "data": {"foo" : 1}, - "valid": false - } - ] - }, - { - "description": "additionalProperties are allowed by default", - "schema": {"properties": {"foo": {}, "bar": {}}}, - "tests": [ - { - "description": "additional properties are allowed", - "data": {"foo": 1, "bar": 2, "quux": true}, - "valid": true - } - ] - } -] +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/allOf.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/allOf.json index db4d6b8e8ec..bbb5f89e4bc 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/allOf.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/allOf.json @@ -1,112 +1,112 @@ -[ - { - "description": "allOf", - "schema": { - "allOf": [ - { - "properties": { - "bar": {"type": "integer"} - }, - "required": ["bar"] - }, - { - "properties": { - "foo": {"type": "string"} - }, - "required": ["foo"] - } - ] - }, - "tests": [ - { - "description": "allOf", - "data": {"foo": "baz", "bar": 2}, - "valid": true - }, - { - "description": "mismatch second", - "data": {"foo": "baz"}, - "valid": false - }, - { - "description": "mismatch first", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "wrong type", - "data": {"foo": "baz", "bar": "quux"}, - "valid": false - } - ] - }, - { - "description": "allOf with base schema", - "schema": { - "properties": {"bar": {"type": "integer"}}, - "required": ["bar"], - "allOf" : [ - { - "properties": { - "foo": {"type": "string"} - }, - "required": ["foo"] - }, - { - "properties": { - "baz": {"type": "null"} - }, - "required": ["baz"] - } - ] - }, - "tests": [ - { - "description": "valid", - "data": {"foo": "quux", "bar": 2, "baz": null}, - "valid": true - }, - { - "description": "mismatch base schema", - "data": {"foo": "quux", "baz": null}, - "valid": false - }, - { - "description": "mismatch first allOf", - "data": {"bar": 2, "baz": null}, - "valid": false - }, - { - "description": "mismatch second allOf", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "mismatch both", - "data": {"bar": 2}, - "valid": false - } - ] - }, - { - "description": "allOf simple types", - "schema": { - "allOf": [ - {"maximum": 30}, - {"minimum": 20} - ] - }, - "tests": [ - { - "description": "valid", - "data": 25, - "valid": true - }, - { - "description": "mismatch one", - "data": 35, - "valid": false - } - ] - } -] +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/anyOf.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/anyOf.json index 636a6474105..a58714afd89 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/anyOf.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/anyOf.json @@ -1,68 +1,68 @@ -[ - { - "description": "anyOf", - "schema": { - "anyOf": [ - { - "type": "integer" - }, - { - "minimum": 2 - } - ] - }, - "tests": [ - { - "description": "first anyOf valid", - "data": 1, - "valid": true - }, - { - "description": "second anyOf valid", - "data": 2.5, - "valid": true - }, - { - "description": "both anyOf valid", - "data": 3, - "valid": true - }, - { - "description": "neither anyOf valid", - "data": 1.5, - "valid": false - } - ] - }, - { - "description": "anyOf with base schema", - "schema": { - "type": "string", - "anyOf" : [ - { - "maxLength": 2 - }, - { - "minLength": 4 - } - ] - }, - "tests": [ - { - "description": "mismatch base schema", - "data": 3, - "valid": false - }, - { - "description": "one anyOf valid", - "data": "foobar", - "valid": true - }, - { - "description": "both anyOf invalid", - "data": "foo", - "valid": false - } - ] - } -] +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/default.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/default.json index c2b76c62170..17629779fbe 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/default.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/default.json @@ -1,49 +1,49 @@ -[ - { - "description": "invalid type for default", - "schema": { - "properties": { - "foo": { - "type": "integer", - "default": [] - } - } - }, - "tests": [ - { - "description": "valid when property is specified", - "data": {"foo": 13}, - "valid": true - }, - { - "description": "still valid when the invalid default is used", - "data": {}, - "valid": true - } - ] - }, - { - "description": "invalid string value for default", - "schema": { - "properties": { - "bar": { - "type": "string", - "minLength": 4, - "default": "bad" - } - } - }, - "tests": [ - { - "description": "valid when property is specified", - "data": {"bar": "good"}, - "valid": true - }, - { - "description": "still valid when the invalid default is used", - "data": {}, - "valid": true - } - ] - } -] +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/definitions.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/definitions.json index 520068c141f..cf935a32153 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/definitions.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/definitions.json @@ -1,32 +1,32 @@ -[ - { - "description": "valid definition", - "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, - "tests": [ - { - "description": "valid definition schema", - "data": { - "definitions": { - "foo": {"type": "integer"} - } - }, - "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, - "tests": [ - { - "description": "invalid definition schema", - "data": { - "definitions": { - "foo": {"type": 1} - } - }, - "valid": false - } - ] - } -] +[ + { + "description": "valid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "valid definition schema", + "data": { + "definitions": { + "foo": {"type": "integer"} + } + }, + "valid": true + } + ] + }, + { + "description": "invalid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "invalid definition schema", + "data": { + "definitions": { + "foo": {"type": 1} + } + }, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/dependencies.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/dependencies.json index decf3e0f4c5..7b9b16a7e12 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/dependencies.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/dependencies.json @@ -1,113 +1,113 @@ -[ - { - "description": "dependencies", - "schema": { - "dependencies": {"bar": ["foo"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependant", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "with dependency", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": "foo", - "valid": true - } - ] - }, - { - "description": "multiple dependencies", - "schema": { - "dependencies": {"quux": ["foo", "bar"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependants", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "with dependencies", - "data": {"foo": 1, "bar": 2, "quux": 3}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"foo": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing other dependency", - "data": {"bar": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing both dependencies", - "data": {"quux": 1}, - "valid": false - } - ] - }, - { - "description": "multiple dependencies subschema", - "schema": { - "dependencies": { - "bar": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "integer"} - } - } - } - }, - "tests": [ - { - "description": "valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "no dependency", - "data": {"foo": "quux"}, - "valid": true - }, - { - "description": "wrong type", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "wrong type other", - "data": {"foo": 2, "bar": "quux"}, - "valid": false - }, - { - "description": "wrong type both", - "data": {"foo": "quux", "bar": "quux"}, - "valid": false - } - ] - } -] +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": ["foo"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/enum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/enum.json index a2cabcbc6a8..f124436a7d9 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/enum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/enum.json @@ -1,72 +1,72 @@ -[ - { - "description": "simple enum validation", - "schema": {"enum": [1, 2, 3]}, - "tests": [ - { - "description": "one of the enum is valid", - "data": 1, - "valid": true - }, - { - "description": "something else is invalid", - "data": 4, - "valid": false - } - ] - }, - { - "description": "heterogeneous enum validation", - "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, - "tests": [ - { - "description": "one of the enum is valid", - "data": [], - "valid": true - }, - { - "description": "something else is invalid", - "data": null, - "valid": false - }, - { - "description": "objects are deep compared", - "data": {"foo": false}, - "valid": false - } - ] - }, - { - "description": "enums in properties", - "schema": { - "type":"object", - "properties": { - "foo": {"enum":["foo"]}, - "bar": {"enum":["bar"]} - }, - "required": ["bar"] - }, - "tests": [ - { - "description": "both properties are valid", - "data": {"foo":"foo", "bar":"bar"}, - "valid": true - }, - { - "description": "missing optional property is valid", - "data": {"bar":"bar"}, - "valid": true - }, - { - "description": "missing required property is invalid", - "data": {"foo":"foo"}, - "valid": false - }, - { - "description": "missing all properties is invalid", - "data": {}, - "valid": false - } - ] - } -] +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"]} + }, + "required": ["bar"] + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/items.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/items.json index 1683e440f9a..f5e18a13848 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/items.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/items.json @@ -1,46 +1,46 @@ -[ - { - "description": "a schema given for items", - "schema": { - "items": {"type": "integer"} - }, - "tests": [ - { - "description": "valid items", - "data": [ 1, 2, 3 ], - "valid": true - }, - { - "description": "wrong type of items", - "data": [1, "x"], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": {"foo" : "bar"}, - "valid": true - } - ] - }, - { - "description": "an array of schemas for items", - "schema": { - "items": [ - {"type": "integer"}, - {"type": "string"} - ] - }, - "tests": [ - { - "description": "correct types", - "data": [ 1, "foo" ], - "valid": true - }, - { - "description": "wrong types", - "data": [ "foo", 1 ], - "valid": false - } - ] - } -] +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxItems.json index 5f5c963b656..3b53a6b371a 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxItems.json @@ -1,28 +1,28 @@ -[ - { - "description": "maxItems validation", - "schema": {"maxItems": 2}, - "tests": [ - { - "description": "shorter is valid", - "data": [1], - "valid": true - }, - { - "description": "exact length is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "too long is invalid", - "data": [1, 2, 3], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": "foobar", - "valid": true - } - ] - } -] +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxLength.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxLength.json index a2e4c95b099..811d35b253c 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxLength.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxLength.json @@ -1,33 +1,33 @@ -[ - { - "description": "maxLength validation", - "schema": {"maxLength": 2}, - "tests": [ - { - "description": "shorter is valid", - "data": "f", - "valid": true - }, - { - "description": "exact length is valid", - "data": "fo", - "valid": true - }, - { - "description": "too long is invalid", - "data": "foo", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - }, - { - "description": "two supplementary Unicode code points is long enough", - "data": "\uD83D\uDCA9\uD83D\uDCA9", - "valid": true - } - ] - } -] +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json index 7725029a122..d282446ad69 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json @@ -1,28 +1,28 @@ -[ - { - "description": "maxProperties validation", - "schema": {"maxProperties": 2}, - "tests": [ - { - "description": "shorter is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "exact length is valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "too long is invalid", - "data": {"foo": 1, "bar": 2, "baz": 3}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": "foobar", - "valid": true - } - ] - } -] +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maximum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maximum.json index 6c069bb29b4..86c7b89c9a9 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maximum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/maximum.json @@ -1,42 +1,42 @@ -[ - { - "description": "maximum validation", - "schema": {"maximum": 3.0}, - "tests": [ - { - "description": "below the maximum is valid", - "data": 2.6, - "valid": true - }, - { - "description": "above the maximum is invalid", - "data": 3.5, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "x", - "valid": true - } - ] - }, - { - "description": "exclusiveMaximum validation", - "schema": { - "maximum": 3.0, - "exclusiveMaximum": true - }, - "tests": [ - { - "description": "below the maximum is still valid", - "data": 2.2, - "valid": true - }, - { - "description": "boundary point is invalid", - "data": 3.0, - "valid": false - } - ] - } -] +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minItems.json index df8e0981c40..ed5118815ee 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minItems.json @@ -1,28 +1,28 @@ -[ - { - "description": "minItems validation", - "schema": {"minItems": 1}, - "tests": [ - { - "description": "longer is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "exact length is valid", - "data": [1], - "valid": true - }, - { - "description": "too short is invalid", - "data": [], - "valid": false - }, - { - "description": "ignores non-arrays", - "data": "", - "valid": true - } - ] - } -] +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minLength.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minLength.json index 96fa0c662f7..3f09158deef 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minLength.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minLength.json @@ -1,33 +1,33 @@ -[ - { - "description": "minLength validation", - "schema": {"minLength": 2}, - "tests": [ - { - "description": "longer is valid", - "data": "foo", - "valid": true - }, - { - "description": "exact length is valid", - "data": "fo", - "valid": true - }, - { - "description": "too short is invalid", - "data": "f", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 1, - "valid": true - }, - { - "description": "one supplementary Unicode code point is not long enough", - "data": "\uD83D\uDCA9", - "valid": false - } - ] - } -] +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minProperties.json index 350b4fa00e8..a72c7d293e6 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minProperties.json @@ -1,28 +1,28 @@ -[ - { - "description": "minProperties validation", - "schema": {"minProperties": 1}, - "tests": [ - { - "description": "longer is valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "exact length is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "too short is invalid", - "data": {}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": "", - "valid": true - } - ] - } -] +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minimum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minimum.json index 0c87f45a9c3..d5bf000bcc6 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minimum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/minimum.json @@ -1,42 +1,42 @@ -[ - { - "description": "minimum validation", - "schema": {"minimum": 1.1}, - "tests": [ - { - "description": "above the minimum is valid", - "data": 2.6, - "valid": true - }, - { - "description": "below the minimum is invalid", - "data": 0.6, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "x", - "valid": true - } - ] - }, - { - "description": "exclusiveMinimum validation", - "schema": { - "minimum": 1.1, - "exclusiveMinimum": true - }, - "tests": [ - { - "description": "above the minimum is still valid", - "data": 1.2, - "valid": true - }, - { - "description": "boundary point is invalid", - "data": 1.1, - "valid": false - } - ] - } -] +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json index cba96043b6c..ca3b7618053 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json @@ -1,60 +1,60 @@ -[ - { - "description": "by int", - "schema": {"multipleOf": 2}, - "tests": [ - { - "description": "int by int", - "data": 10, - "valid": true - }, - { - "description": "int by int fail", - "data": 7, - "valid": false - }, - { - "description": "ignores non-numbers", - "data": "foo", - "valid": true - } - ] - }, - { - "description": "by number", - "schema": {"multipleOf": 1.5}, - "tests": [ - { - "description": "zero is multiple of anything", - "data": 0, - "valid": true - }, - { - "description": "4.5 is multiple of 1.5", - "data": 4.5, - "valid": true - }, - { - "description": "35 is not multiple of 1.5", - "data": 35, - "valid": false - } - ] - }, - { - "description": "by small number", - "schema": {"multipleOf": 0.0001}, - "tests": [ - { - "description": "0.0075 is multiple of 0.0001", - "data": 0.0075, - "valid": true - }, - { - "description": "0.00751 is not multiple of 0.0001", - "data": 0.00751, - "valid": false - } - ] - } -] +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/not.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/not.json index ee81f06afa8..cbb7f46bf8b 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/not.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/not.json @@ -1,96 +1,96 @@ -[ - { - "description": "not", - "schema": { - "not": {"type": "integer"} - }, - "tests": [ - { - "description": "allowed", - "data": "foo", - "valid": true - }, - { - "description": "disallowed", - "data": 1, - "valid": false - } - ] - }, - { - "description": "not multiple types", - "schema": { - "not": {"type": ["integer", "boolean"]} - }, - "tests": [ - { - "description": "valid", - "data": "foo", - "valid": true - }, - { - "description": "mismatch", - "data": 1, - "valid": false - }, - { - "description": "other mismatch", - "data": true, - "valid": false - } - ] - }, - { - "description": "not more complex schema", - "schema": { - "not": { - "type": "object", - "properties": { - "foo": { - "type": "string" - } - } - } - }, - "tests": [ - { - "description": "match", - "data": 1, - "valid": true - }, - { - "description": "other match", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "mismatch", - "data": {"foo": "bar"}, - "valid": false - } - ] - }, - { - "description": "forbidden property", - "schema": { - "properties": { - "foo": { - "not": {} - } - } - }, - "tests": [ - { - "description": "property present", - "data": {"foo": 1, "bar": 2}, - "valid": false - }, - { - "description": "property absent", - "data": {"bar": 1, "baz": 2}, - "valid": true - } - ] - } - -] +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "forbidden property", + "schema": { + "properties": { + "foo": { + "not": {} + } + } + }, + "tests": [ + { + "description": "property present", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "property absent", + "data": {"bar": 1, "baz": 2}, + "valid": true + } + ] + } + +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/oneOf.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/oneOf.json index 349aeb6becb..1eaa4e47949 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/oneOf.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/oneOf.json @@ -1,68 +1,68 @@ -[ - { - "description": "oneOf", - "schema": { - "oneOf": [ - { - "type": "integer" - }, - { - "minimum": 2 - } - ] - }, - "tests": [ - { - "description": "first oneOf valid", - "data": 1, - "valid": true - }, - { - "description": "second oneOf valid", - "data": 2.5, - "valid": true - }, - { - "description": "both oneOf valid", - "data": 3, - "valid": false - }, - { - "description": "neither oneOf valid", - "data": 1.5, - "valid": false - } - ] - }, - { - "description": "oneOf with base schema", - "schema": { - "type": "string", - "oneOf" : [ - { - "minLength": 2 - }, - { - "maxLength": 4 - } - ] - }, - "tests": [ - { - "description": "mismatch base schema", - "data": 3, - "valid": false - }, - { - "description": "one oneOf valid", - "data": "foobar", - "valid": true - }, - { - "description": "both oneOf valid", - "data": "foo", - "valid": false - } - ] - } -] +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json index 31df120efe7..ccc7c17fe8d 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json @@ -1,107 +1,107 @@ -[ - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "a bignum is an integer", - "data": 12345678910111213141516171819202122232425262728293031, - "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "a negative bignum is an integer", - "data": -12345678910111213141516171819202122232425262728293031, - "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a negative bignum is a number", - "data": -98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "string", - "schema": {"type": "string"}, - "tests": [ - { - "description": "a bignum is not a string", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": false - } - ] - }, - { - "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, - "tests": [ - { - "description": "comparison works for high numbers", - "data": 18446744073709551600, - "valid": true - } - ] - }, - { - "description": "float comparison with high precision", - "schema": { - "maximum": 972783798187987123879878123.18878137, - "exclusiveMaximum": true - }, - "tests": [ - { - "description": "comparison works for high numbers", - "data": 972783798187987123879878123.188781371, - "valid": false - } - ] - }, - { - "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, - "tests": [ - { - "description": "comparison works for very negative numbers", - "data": -18446744073709551600, - "valid": true - } - ] - }, - { - "description": "float comparison with high precision on negative numbers", - "schema": { - "minimum": -972783798187987123879878123.18878137, - "exclusiveMinimum": true - }, - "tests": [ - { - "description": "comparison works for very negative numbers", - "data": -972783798187987123879878123.188781371, - "valid": false - } - ] - } -] +[ + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": {"type": "string"}, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"maximum": 18446744073709551615}, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "maximum": 972783798187987123879878123.18878137, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"minimum": -18446744073709551615}, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "minimum": -972783798187987123879878123.18878137, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/format.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/format.json index 6b0e98771d6..aacfd119843 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/format.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/format.json @@ -1,148 +1,148 @@ -[ - { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, - "tests": [ - { - "description": "a valid date-time string", - "data": "1963-06-19T08:30:06.283185Z", - "valid": true - }, - { - "description": "an invalid date-time string", - "data": "06/19/1963 08:30:06 PST", - "valid": false - }, - { - "description": "only RFC3339 not all of ISO 8601 are valid", - "data": "2013-350T01:01:01", - "valid": false - } - ] - }, - { - "description": "validation of URIs", - "schema": {"format": "uri"}, - "tests": [ - { - "description": "a valid URI", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid protocol-relative URI", - "data": "//foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "an invalid URI", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "an invalid URI though valid URI reference", - "data": "abc", - "valid": false - } - ] - }, - { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, - "tests": [ - { - "description": "a valid e-mail address", - "data": "joe.bloggs@example.com", - "valid": true - }, - { - "description": "an invalid e-mail address", - "data": "2962", - "valid": false - } - ] - }, - { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, - "tests": [ - { - "description": "a valid IP address", - "data": "192.168.0.1", - "valid": true - }, - { - "description": "an IP address with too many components", - "data": "127.0.0.0.1", - "valid": false - }, - { - "description": "an IP address with out-of-range values", - "data": "256.256.256.256", - "valid": false - }, - { - "description": "an IP address without 4 components", - "data": "127.0", - "valid": false - }, - { - "description": "an IP address as an integer", - "data": "0x7f000001", - "valid": false - } - ] - }, - { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, - "tests": [ - { - "description": "a valid IPv6 address", - "data": "::1", - "valid": true - }, - { - "description": "an IPv6 address with out-of-range values", - "data": "12345::", - "valid": false - }, - { - "description": "an IPv6 address with too many components", - "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", - "valid": false - }, - { - "description": "an IPv6 address containing illegal characters", - "data": "::laptop", - "valid": false - } - ] - }, - { - "description": "validation of host names", - "schema": {"format": "hostname"}, - "tests": [ - { - "description": "a valid host name", - "data": "www.example.com", - "valid": true - }, - { - "description": "a host name starting with an illegal character", - "data": "-a-host-name-that-starts-with--", - "valid": false - }, - { - "description": "a host name containing illegal characters", - "data": "not_a_valid_host_name", - "valid": false - }, - { - "description": "a host name with a component too long", - "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", - "valid": false - } - ] - } -] +[ + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + } + ] + }, + { + "description": "validation of host names", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json index 445fffc5d61..9b50ea27769 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json @@ -1,15 +1,15 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float is not an integer even without fractional part", - "data": 1.0, - "valid": false - } - ] - } -] +[ + { + "description": "some languages do not distinguish between different types of numeric value", + "schema": { + "type": "integer" + }, + "tests": [ + { + "description": "a float is not an integer even without fractional part", + "data": 1.0, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/pattern.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/pattern.json index 70b5e10950a..25e72997314 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/pattern.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/pattern.json @@ -1,34 +1,34 @@ -[ - { - "description": "pattern validation", - "schema": {"pattern": "^a*$"}, - "tests": [ - { - "description": "a matching pattern is valid", - "data": "aaa", - "valid": true - }, - { - "description": "a non-matching pattern is invalid", - "data": "abc", - "valid": false - }, - { - "description": "ignores non-strings", - "data": true, - "valid": true - } - ] - }, - { - "description": "pattern is not anchored", - "schema": {"pattern": "a+"}, - "tests": [ - { - "description": "matches a substring", - "data": "xxaayy", - "valid": true - } - ] - } -] +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json index 8d7cea77577..18586e5daba 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json @@ -1,110 +1,110 @@ -[ - { - "description": - "patternProperties validates properties matching a regex", - "schema": { - "patternProperties": { - "f.*o": {"type": "integer"} - } - }, - "tests": [ - { - "description": "a single valid match is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "multiple valid matches is valid", - "data": {"foo": 1, "foooooo" : 2}, - "valid": true - }, - { - "description": "a single invalid match is invalid", - "data": {"foo": "bar", "fooooo": 2}, - "valid": false - }, - { - "description": "multiple invalid matches is invalid", - "data": {"foo": "bar", "foooooo" : "baz"}, - "valid": false - }, - { - "description": "ignores non-objects", - "data": 12, - "valid": true - } - ] - }, - { - "description": "multiple simultaneous patternProperties are validated", - "schema": { - "patternProperties": { - "a*": {"type": "integer"}, - "aaa*": {"maximum": 20} - } - }, - "tests": [ - { - "description": "a single valid match is valid", - "data": {"a": 21}, - "valid": true - }, - { - "description": "a simultaneous match is valid", - "data": {"aaaa": 18}, - "valid": true - }, - { - "description": "multiple matches is valid", - "data": {"a": 21, "aaaa": 18}, - "valid": true - }, - { - "description": "an invalid due to one is invalid", - "data": {"a": "bar"}, - "valid": false - }, - { - "description": "an invalid due to the other is invalid", - "data": {"aaaa": 31}, - "valid": false - }, - { - "description": "an invalid due to both is invalid", - "data": {"aaa": "foo", "aaaa": 31}, - "valid": false - } - ] - }, - { - "description": "regexes are not anchored by default and are case sensitive", - "schema": { - "patternProperties": { - "[0-9]{2,}": { "type": "boolean" }, - "X_": { "type": "string" } - } - }, - "tests": [ - { - "description": "non recognized members are ignored", - "data": { "answer 1": "42" }, - "valid": true - }, - { - "description": "recognized members are accounted for", - "data": { "a31b": null }, - "valid": false - }, - { - "description": "regexes are case sensitive", - "data": { "a_x_3": 3 }, - "valid": true - }, - { - "description": "regexes are case sensitive, 2", - "data": { "a_X_3": 3 }, - "valid": false - } - ] - } -] +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/properties.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/properties.json index 8bda460ce16..cd1644dcd91 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/properties.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/properties.json @@ -1,92 +1,92 @@ -[ - { - "description": "object properties validation", - "schema": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "string"} - } - }, - "tests": [ - { - "description": "both properties present and valid is valid", - "data": {"foo": 1, "bar": "baz"}, - "valid": true - }, - { - "description": "one property invalid is invalid", - "data": {"foo": 1, "bar": {}}, - "valid": false - }, - { - "description": "both properties invalid is invalid", - "data": {"foo": [], "bar": {}}, - "valid": false - }, - { - "description": "doesn't invalidate other properties", - "data": {"quux": []}, - "valid": true - }, - { - "description": "ignores non-objects", - "data": [], - "valid": true - } - ] - }, - { - "description": - "properties, patternProperties, additionalProperties interaction", - "schema": { - "properties": { - "foo": {"type": "array", "maxItems": 3}, - "bar": {"type": "array"} - }, - "patternProperties": {"f.o": {"minItems": 2}}, - "additionalProperties": {"type": "integer"} - }, - "tests": [ - { - "description": "property validates property", - "data": {"foo": [1, 2]}, - "valid": true - }, - { - "description": "property invalidates property", - "data": {"foo": [1, 2, 3, 4]}, - "valid": false - }, - { - "description": "patternProperty invalidates property", - "data": {"foo": []}, - "valid": false - }, - { - "description": "patternProperty validates nonproperty", - "data": {"fxo": [1, 2]}, - "valid": true - }, - { - "description": "patternProperty invalidates nonproperty", - "data": {"fxo": []}, - "valid": false - }, - { - "description": "additionalProperty ignores property", - "data": {"bar": []}, - "valid": true - }, - { - "description": "additionalProperty validates others", - "data": {"quux": 3}, - "valid": true - }, - { - "description": "additionalProperty invalidates others", - "data": {"quux": "foo"}, - "valid": false - } - ] - } -] +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/ref.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/ref.json index fa95df466f3..7e805522492 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/ref.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/ref.json @@ -1,159 +1,159 @@ -[ - { - "description": "root pointer ref", - "schema": { - "properties": { - "foo": {"$ref": "#"} - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "match", - "data": {"foo": false}, - "valid": true - }, - { - "description": "recursive match", - "data": {"foo": {"foo": false}}, - "valid": true - }, - { - "description": "mismatch", - "data": {"bar": false}, - "valid": false - }, - { - "description": "recursive mismatch", - "data": {"foo": {"bar": false}}, - "valid": false - } - ] - }, - { - "description": "relative pointer ref to object", - "schema": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"$ref": "#/properties/foo"} - } - }, - "tests": [ - { - "description": "match", - "data": {"bar": 3}, - "valid": true - }, - { - "description": "mismatch", - "data": {"bar": true}, - "valid": false - } - ] - }, - { - "description": "relative pointer ref to array", - "schema": { - "items": [ - {"type": "integer"}, - {"$ref": "#/items/0"} - ] - }, - "tests": [ - { - "description": "match array", - "data": [1, 2], - "valid": true - }, - { - "description": "mismatch array", - "data": [1, "foo"], - "valid": false - } - ] - }, - { - "description": "escaped pointer ref", - "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, - "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} - } - }, - "tests": [ - { - "description": "slash invalid", - "data": {"slash": "aoeu"}, - "valid": false - }, - { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, - "valid": false - }, - { - "description": "percent invalid", - "data": {"percent": "aoeu"}, - "valid": false - }, - { - "description": "slash valid", - "data": {"slash": 123}, - "valid": true - }, - { - "description": "tilda valid", - "data": {"tilda": 123}, - "valid": true - }, - { - "description": "percent valid", - "data": {"percent": 123}, - "valid": true - } - ] - }, - { - "description": "nested refs", - "schema": { - "definitions": { - "a": {"type": "integer"}, - "b": {"$ref": "#/definitions/a"}, - "c": {"$ref": "#/definitions/b"} - }, - "$ref": "#/definitions/c" - }, - "tests": [ - { - "description": "nested ref valid", - "data": 5, - "valid": true - }, - { - "description": "nested ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "remote ref, containing refs itself", - "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, - "tests": [ - { - "description": "remote ref valid", - "data": {"minLength": 1}, - "valid": true - }, - { - "description": "remote ref invalid", - "data": {"minLength": -1}, - "valid": false - } - ] - } -] +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "items": [ + {"type": "integer"}, + {"$ref": "#/items/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda invalid", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilda valid", + "data": {"tilda": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "remote ref valid", + "data": {"minLength": 1}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"minLength": -1}, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/refRemote.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/refRemote.json index 85d136c8400..4ca804732c9 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/refRemote.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/refRemote.json @@ -1,74 +1,74 @@ -[ - { - "description": "remote ref", - "schema": {"$ref": "http://localhost:1234/integer.json"}, - "tests": [ - { - "description": "remote ref valid", - "data": 1, - "valid": true - }, - { - "description": "remote ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, - "tests": [ - { - "description": "remote fragment valid", - "data": 1, - "valid": true - }, - { - "description": "remote fragment invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "ref within remote ref", - "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" - }, - "tests": [ - { - "description": "ref within ref valid", - "data": 1, - "valid": true - }, - { - "description": "ref within ref invalid", - "data": "a", - "valid": false - } - ] - }, - { - "description": "change resolution scope", - "schema": { - "id": "http://localhost:1234/", - "items": { - "id": "folder/", - "items": {"$ref": "folderInteger.json"} - } - }, - "tests": [ - { - "description": "changed scope ref valid", - "data": [[1]], - "valid": true - }, - { - "description": "changed scope ref invalid", - "data": [["a"]], - "valid": false - } - ] - } -] +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "change resolution scope", + "schema": { + "id": "http://localhost:1234/", + "items": { + "id": "folder/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "changed scope ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "changed scope ref invalid", + "data": [["a"]], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/required.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/required.json index 4e9735dc429..612f73f3472 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/required.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/required.json @@ -1,39 +1,39 @@ -[ - { - "description": "required validation", - "schema": { - "properties": { - "foo": {}, - "bar": {} - }, - "required": ["foo"] - }, - "tests": [ - { - "description": "present required property is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "non-present required property is invalid", - "data": {"bar": 1}, - "valid": false - } - ] - }, - { - "description": "required default validation", - "schema": { - "properties": { - "foo": {} - } - }, - "tests": [ - { - "description": "not required by default", - "data": {}, - "valid": true - } - ] - } -] +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/type.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/type.json index eaa48ccb8f0..db42a44d3fa 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/type.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/type.json @@ -1,330 +1,330 @@ -[ - { - "description": "integer type matches integers", - "schema": {"type": "integer"}, - "tests": [ - { - "description": "an integer is an integer", - "data": 1, - "valid": true - }, - { - "description": "a float is not an integer", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an integer", - "data": "foo", - "valid": false - }, - { - "description": "an object is not an integer", - "data": {}, - "valid": false - }, - { - "description": "an array is not an integer", - "data": [], - "valid": false - }, - { - "description": "a boolean is not an integer", - "data": true, - "valid": false - }, - { - "description": "null is not an integer", - "data": null, - "valid": false - } - ] - }, - { - "description": "number type matches numbers", - "schema": {"type": "number"}, - "tests": [ - { - "description": "an integer is a number", - "data": 1, - "valid": true - }, - { - "description": "a float is a number", - "data": 1.1, - "valid": true - }, - { - "description": "a string is not a number", - "data": "foo", - "valid": false - }, - { - "description": "an object is not a number", - "data": {}, - "valid": false - }, - { - "description": "an array is not a number", - "data": [], - "valid": false - }, - { - "description": "a boolean is not a number", - "data": true, - "valid": false - }, - { - "description": "null is not a number", - "data": null, - "valid": false - } - ] - }, - { - "description": "string type matches strings", - "schema": {"type": "string"}, - "tests": [ - { - "description": "1 is not a string", - "data": 1, - "valid": false - }, - { - "description": "a float is not a string", - "data": 1.1, - "valid": false - }, - { - "description": "a string is a string", - "data": "foo", - "valid": true - }, - { - "description": "an object is not a string", - "data": {}, - "valid": false - }, - { - "description": "an array is not a string", - "data": [], - "valid": false - }, - { - "description": "a boolean is not a string", - "data": true, - "valid": false - }, - { - "description": "null is not a string", - "data": null, - "valid": false - } - ] - }, - { - "description": "object type matches objects", - "schema": {"type": "object"}, - "tests": [ - { - "description": "an integer is not an object", - "data": 1, - "valid": false - }, - { - "description": "a float is not an object", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an object", - "data": "foo", - "valid": false - }, - { - "description": "an object is an object", - "data": {}, - "valid": true - }, - { - "description": "an array is not an object", - "data": [], - "valid": false - }, - { - "description": "a boolean is not an object", - "data": true, - "valid": false - }, - { - "description": "null is not an object", - "data": null, - "valid": false - } - ] - }, - { - "description": "array type matches arrays", - "schema": {"type": "array"}, - "tests": [ - { - "description": "an integer is not an array", - "data": 1, - "valid": false - }, - { - "description": "a float is not an array", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not an array", - "data": "foo", - "valid": false - }, - { - "description": "an object is not an array", - "data": {}, - "valid": false - }, - { - "description": "an array is an array", - "data": [], - "valid": true - }, - { - "description": "a boolean is not an array", - "data": true, - "valid": false - }, - { - "description": "null is not an array", - "data": null, - "valid": false - } - ] - }, - { - "description": "boolean type matches booleans", - "schema": {"type": "boolean"}, - "tests": [ - { - "description": "an integer is not a boolean", - "data": 1, - "valid": false - }, - { - "description": "a float is not a boolean", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not a boolean", - "data": "foo", - "valid": false - }, - { - "description": "an object is not a boolean", - "data": {}, - "valid": false - }, - { - "description": "an array is not a boolean", - "data": [], - "valid": false - }, - { - "description": "a boolean is a boolean", - "data": true, - "valid": true - }, - { - "description": "null is not a boolean", - "data": null, - "valid": false - } - ] - }, - { - "description": "null type matches only the null object", - "schema": {"type": "null"}, - "tests": [ - { - "description": "an integer is not null", - "data": 1, - "valid": false - }, - { - "description": "a float is not null", - "data": 1.1, - "valid": false - }, - { - "description": "a string is not null", - "data": "foo", - "valid": false - }, - { - "description": "an object is not null", - "data": {}, - "valid": false - }, - { - "description": "an array is not null", - "data": [], - "valid": false - }, - { - "description": "a boolean is not null", - "data": true, - "valid": false - }, - { - "description": "null is null", - "data": null, - "valid": true - } - ] - }, - { - "description": "multiple types can be specified in an array", - "schema": {"type": ["integer", "string"]}, - "tests": [ - { - "description": "an integer is valid", - "data": 1, - "valid": true - }, - { - "description": "a string is valid", - "data": "foo", - "valid": true - }, - { - "description": "a float is invalid", - "data": 1.1, - "valid": false - }, - { - "description": "an object is invalid", - "data": {}, - "valid": false - }, - { - "description": "an array is invalid", - "data": [], - "valid": false - }, - { - "description": "a boolean is invalid", - "data": true, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - } - ] - } -] +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json index f54133987e4..c1f4ab99c9a 100644 --- a/3rdparty/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json +++ b/3rdparty/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json @@ -1,79 +1,79 @@ -[ - { - "description": "uniqueItems validation", - "schema": {"uniqueItems": true}, - "tests": [ - { - "description": "unique array of integers is valid", - "data": [1, 2], - "valid": true - }, - { - "description": "non-unique array of integers is invalid", - "data": [1, 1], - "valid": false - }, - { - "description": "numbers are unique if mathematically unequal", - "data": [1.0, 1.00, 1], - "valid": false - }, - { - "description": "unique array of objects is valid", - "data": [{"foo": "bar"}, {"foo": "baz"}], - "valid": true - }, - { - "description": "non-unique array of objects is invalid", - "data": [{"foo": "bar"}, {"foo": "bar"}], - "valid": false - }, - { - "description": "unique array of nested objects is valid", - "data": [ - {"foo": {"bar" : {"baz" : true}}}, - {"foo": {"bar" : {"baz" : false}}} - ], - "valid": true - }, - { - "description": "non-unique array of nested objects is invalid", - "data": [ - {"foo": {"bar" : {"baz" : true}}}, - {"foo": {"bar" : {"baz" : true}}} - ], - "valid": false - }, - { - "description": "unique array of arrays is valid", - "data": [["foo"], ["bar"]], - "valid": true - }, - { - "description": "non-unique array of arrays is invalid", - "data": [["foo"], ["foo"]], - "valid": false - }, - { - "description": "1 and true are unique", - "data": [1, true], - "valid": true - }, - { - "description": "0 and false are unique", - "data": [0, false], - "valid": true - }, - { - "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], - "valid": true - }, - { - "description": "non-unique heterogeneous types are invalid", - "data": [{}, [1], true, null, {}, 1], - "valid": false - } - ] - } -] +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/3rdparty/rapidjson/doc/dom.md b/3rdparty/rapidjson/doc/dom.md index cb25fc4f3af..79b68175f6d 100644 --- a/3rdparty/rapidjson/doc/dom.md +++ b/3rdparty/rapidjson/doc/dom.md @@ -116,6 +116,7 @@ Parse flags | Meaning `kParseStopWhenDoneFlag` | After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate `kParseErrorDocumentRootNotSingular` error. Using this flag for parsing multiple JSONs in the same stream. `kParseFullPrecisionFlag` | Parse number in full precision (slower). If this flag is not set, the normal precision (faster) is used. Normal precision has maximum 3 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) error. `kParseCommentsFlag` | Allow one-line `// ...` and multi-line `/* ... */` comments (relaxed JSON syntax). +`kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax). By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time. diff --git a/3rdparty/rapidjson/include/rapidjson/document.h b/3rdparty/rapidjson/include/rapidjson/document.h index 855543effe6..e1b1fbcb218 100644 --- a/3rdparty/rapidjson/include/rapidjson/document.h +++ b/3rdparty/rapidjson/include/rapidjson/document.h @@ -2509,8 +2509,8 @@ public: bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } #endif template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } - MemberIterator FindMember(const Ch* name) const { value_.FindMember(name); } - template MemberIterator FindMember(const GenericValue& name) const { value_.FindMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } #if RAPIDJSON_HAS_STDSTRING MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } #endif diff --git a/3rdparty/rapidjson/include/rapidjson/pointer.h b/3rdparty/rapidjson/include/rapidjson/pointer.h index eddeab427ea..94449381f32 100644 --- a/3rdparty/rapidjson/include/rapidjson/pointer.h +++ b/3rdparty/rapidjson/include/rapidjson/pointer.h @@ -987,11 +987,11 @@ private: src_++; Ch c = 0; for (int j = 0; j < 2; j++) { - c <<= 4; + c = static_cast(c << 4); Ch h = *src_; - if (h >= '0' && h <= '9') c += h - '0'; - else if (h >= 'A' && h <= 'F') c += h - 'A' + 10; - else if (h >= 'a' && h <= 'f') c += h - 'a' + 10; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); else { valid_ = false; return 0; diff --git a/3rdparty/rapidjson/include/rapidjson/prettywriter.h b/3rdparty/rapidjson/include/rapidjson/prettywriter.h index 5ec4ccc3f75..75dc474f4c1 100644 --- a/3rdparty/rapidjson/include/rapidjson/prettywriter.h +++ b/3rdparty/rapidjson/include/rapidjson/prettywriter.h @@ -24,6 +24,14 @@ RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_NAMESPACE_BEGIN +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + //! Writer with indentation and spacing. /*! \tparam OutputStream Type of ouptut os. @@ -43,7 +51,7 @@ public: \param levelDepth Initial capacity of stack. */ explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : @@ -61,6 +69,14 @@ public: return *this; } + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + /*! @name Implementation of Handler \see Handler */ @@ -130,7 +146,7 @@ public: RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; - if (!empty) { + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { Base::os_->Put('\n'); WriteIndent(); } @@ -173,11 +189,14 @@ protected: if (level->inArray) { if (level->valueCount > 0) { Base::os_->Put(','); // add comma if it is not the first element in array - Base::os_->Put('\n'); + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); } - else + + if (!(formatOptions_ & kFormatSingleLineArray)) { Base::os_->Put('\n'); - WriteIndent(); + WriteIndent(); + } } else { // in object if (level->valueCount > 0) { @@ -213,6 +232,7 @@ protected: Ch indentChar_; unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; private: // Prohibit copy constructor & assignment operator. diff --git a/3rdparty/rapidjson/include/rapidjson/reader.h b/3rdparty/rapidjson/include/rapidjson/reader.h index 3d7bb634743..6f45571755f 100644 --- a/3rdparty/rapidjson/include/rapidjson/reader.h +++ b/3rdparty/rapidjson/include/rapidjson/reader.h @@ -1,5 +1,5 @@ // Tencent is pleased to support the open source community by making RapidJSON available. -// +// // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. // // Licensed under the MIT License (the "License"); you may not use this file except @@ -7,9 +7,9 @@ // // http://opensource.org/licenses/MIT // -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #ifndef RAPIDJSON_READER_H_ @@ -127,7 +127,7 @@ RAPIDJSON_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// // ParseFlag -/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS \ingroup RAPIDJSON_CONFIG \brief User-defined kParseDefaultFlags definition. @@ -149,6 +149,7 @@ enum ParseFlag { kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS }; @@ -157,7 +158,7 @@ enum ParseFlag { /*! \class rapidjson::Handler \brief Concept for receiving events from GenericReader upon parsing. - The functions return true if no error occurs. If they return false, + The functions return true if no error occurs. If they return false, the event publisher should terminate the process. \code concept Handler { @@ -424,7 +425,7 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { #ifdef RAPIDJSON_SIMD //! Template function specialization for InsituStringStream -template<> inline void SkipWhitespace(InsituStringStream& is) { +template<> inline void SkipWhitespace(InsituStringStream& is) { is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); } @@ -442,17 +443,17 @@ template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& // GenericReader //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. -/*! GenericReader parses JSON text from a stream, and send events synchronously to an +/*! GenericReader parses JSON text from a stream, and send events synchronously to an object implementing Handler concept. - It needs to allocate a stack for storing a single decoded string during + It needs to allocate a stack for storing a single decoded string during non-destructive parsing. - For in-situ parsing, the decoded string is directly written to the source + For in-situ parsing, the decoded string is directly written to the source text string, no temporary buffer is required. A GenericReader object can be reused for parsing multiple JSON text. - + \tparam SourceEncoding Encoding of the input stream. \tparam TargetEncoding Encoding of the parse output. \tparam StackAllocator Allocator type for stack. @@ -524,7 +525,7 @@ public: //! Whether a parse error has occured in the last parsing. bool HasParseError() const { return parseResult_.IsError(); } - + //! Get the \ref ParseErrorCode of last parsing. ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } @@ -584,7 +585,7 @@ private: void ParseObject(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '{'); is.Take(); // Skip '{' - + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); @@ -627,15 +628,24 @@ private: SkipWhitespaceAndComments(is); RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; break; - case '}': + case '}': is.Take(); if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); return; - default: + default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } } } @@ -644,10 +654,10 @@ private: void ParseArray(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '['); is.Take(); // Skip '[' - + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - + SkipWhitespaceAndComments(is); RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; @@ -676,6 +686,15 @@ private: } else RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } } } @@ -761,7 +780,7 @@ private: *stack_.template Push() = c; ++length_; } - + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { length_ += count; return stack_.template Push(count); @@ -819,10 +838,10 @@ private: //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 static const char escape[256] = { - Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', - Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, - 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, - 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 }; #undef Z16 @@ -874,8 +893,8 @@ private: } else { size_t offset = is.Tell(); - if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? - !Transcoder::Validate(is, os) : + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : !Transcoder::Transcode(is, os)))) RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); } @@ -935,7 +954,7 @@ private: } _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); } - + is.src_ = p; } @@ -958,7 +977,7 @@ private: if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { is.src_ = p; is.dst_ = q; - return; + return; } else *q++ = *p++; @@ -1044,11 +1063,11 @@ private: } #endif - template + template class NumberStream; template - class NumberStream { + class NumberStream { public: typedef typename InputStream::Ch Ch; @@ -1071,10 +1090,10 @@ private: }; template - class NumberStream : public NumberStream { - typedef NumberStream Base; + class NumberStream : public NumberStream { + typedef NumberStream Base; public: - NumberStream(GenericReader& reader, InputStream& is) : NumberStream(reader, is), stackStream(reader.stack_) {} + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} ~NumberStream() {} RAPIDJSON_FORCEINLINE Ch TakePush() { @@ -1082,9 +1101,9 @@ private: return Base::is.Take(); } - RAPIDJSON_FORCEINLINE void Push(char c) { - stackStream.Put(c); - } + RAPIDJSON_FORCEINLINE void Push(char c) { + stackStream.Put(c); + } size_t Length() { return stackStream.Length(); } @@ -1097,13 +1116,25 @@ private: StackStream stackStream; }; + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + template void ParseNumber(InputStream& is, Handler& handler) { internal::StreamLocalCopy copy(is); NumberStream s(*this, copy.s); + ((parseFlags & kParseFullPrecisionFlag) != 0), + (parseFlags & kParseNumbersAsStringsFlag) != 0 && + (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s); size_t startOffset = s.Tell(); @@ -1154,7 +1185,7 @@ private: bool useDouble = false; double d = 0.0; if (use64bit) { - if (minus) + if (minus) while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { @@ -1191,9 +1222,6 @@ private: int expFrac = 0; size_t decimalPosition; if (Consume(s, '.')) { - if (((parseFlags & kParseNumbersAsStringsFlag) != 0) && ((parseFlags & kParseInsituFlag) == 0)) { - s.Push('.'); - } decimalPosition = s.Length(); if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) @@ -1204,7 +1232,7 @@ private: // Use i64 to store significand in 64-bit architecture if (!use64bit) i64 = i; - + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path break; @@ -1241,11 +1269,7 @@ private: // Parse exp = e [ minus / plus ] 1*DIGIT int exp = 0; if (Consume(s, 'e') || Consume(s, 'E')) { - if ( ((parseFlags & kParseNumbersAsStringsFlag) != 0) && ((parseFlags & kParseInsituFlag) == 0) ) { - s.Push( 'e' ); - } - - if (!useDouble) { + if (!useDouble) { d = static_cast(use64bit ? i64 : i); useDouble = true; } @@ -1297,14 +1321,15 @@ private: cont = handler.RawNumber(str, SizeType(length), false); } else { - StackStream stackStream(stack_); SizeType numCharsToCopy = static_cast(s.Length()); + StringStream srcStream(s.Pop()); + StackStream dstStream(stack_); while (numCharsToCopy--) { - Transcoder::Transcode(is, stackStream); + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); } - stackStream.Put('\0'); - const typename TargetEncoding::Ch* str = stackStream.Pop(); - const SizeType length = static_cast(stackStream.Length()) - 1; + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; cont = handler.RawNumber(str, SizeType(length), true); } } @@ -1350,10 +1375,10 @@ private: case '"': ParseString(is, handler); break; case '{': ParseObject(is, handler); break; case '[': ParseArray (is, handler); break; - default : + default : ParseNumber(is, handler); break; - + } } @@ -1425,7 +1450,7 @@ private: #undef N #undef N16 //!@endcond - + if (sizeof(Ch) == 1 || static_cast(c) < 256) return static_cast(tokenMap[static_cast(c)]); else @@ -1522,7 +1547,7 @@ private: IterativeParsingErrorState, // Left bracket IterativeParsingErrorState, // Right bracket IterativeParsingErrorState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket + IterativeParsingObjectFinishState, // Right curly bracket IterativeParsingErrorState, // Comma IterativeParsingErrorState, // Colon IterativeParsingMemberKeyState, // String @@ -1568,7 +1593,7 @@ private: // ElementDelimiter { IterativeParsingArrayInitialState, // Left bracket(push Element state) - IterativeParsingErrorState, // Right bracket + IterativeParsingArrayFinishState, // Right bracket IterativeParsingObjectInitialState, // Left curly bracket(push Element state) IterativeParsingErrorState, // Right curly bracket IterativeParsingErrorState, // Comma @@ -1670,6 +1695,11 @@ private: case IterativeParsingObjectFinishState: { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } // Get member count. SizeType c = *stack_.template Pop(1); // If the object is not empty, count the last member. @@ -1695,6 +1725,11 @@ private: case IterativeParsingArrayFinishState: { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } // Get element count. SizeType c = *stack_.template Pop(1); // If the array is not empty, count the last element. @@ -1746,7 +1781,7 @@ private: // Error flag has been set. return; } - + switch (src) { case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; @@ -1754,9 +1789,12 @@ private: case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); return; - } + } } template diff --git a/3rdparty/rapidjson/test/unittest/CMakeLists.txt b/3rdparty/rapidjson/test/unittest/CMakeLists.txt index 02c15327e6b..3f76a4f3c1c 100644 --- a/3rdparty/rapidjson/test/unittest/CMakeLists.txt +++ b/3rdparty/rapidjson/test/unittest/CMakeLists.txt @@ -38,6 +38,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything") + # If the user is running a newer version of Clang that includes the + # -Wdouble-promotion, we will ignore that warning. + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.7) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-double-promotion") + endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) endif() diff --git a/3rdparty/rapidjson/test/unittest/itoatest.cpp b/3rdparty/rapidjson/test/unittest/itoatest.cpp index 9c3107d4178..79db1c71dcd 100644 --- a/3rdparty/rapidjson/test/unittest/itoatest.cpp +++ b/3rdparty/rapidjson/test/unittest/itoatest.cpp @@ -93,7 +93,7 @@ static void u32toa_naive(uint32_t value, char* buffer) { char temp[10]; char *p = temp; do { - *p++ = char(value % 10) + '0'; + *p++ = static_cast(char(value % 10) + '0'); value /= 10; } while (value > 0); @@ -117,7 +117,7 @@ static void u64toa_naive(uint64_t value, char* buffer) { char temp[20]; char *p = temp; do { - *p++ = char(value % 10) + '0'; + *p++ = static_cast(char(value % 10) + '0'); value /= 10; } while (value > 0); diff --git a/3rdparty/rapidjson/test/unittest/prettywritertest.cpp b/3rdparty/rapidjson/test/unittest/prettywritertest.cpp index e05d710f8cb..a372f7986f8 100644 --- a/3rdparty/rapidjson/test/unittest/prettywritertest.cpp +++ b/3rdparty/rapidjson/test/unittest/prettywritertest.cpp @@ -39,6 +39,19 @@ static const char kPrettyJson[] = " \"i64\": -1234567890123456789\n" "}"; +static const char kPrettyJson_FormatOptions_SLA[] = +"{\n" +" \"hello\": \"world\",\n" +" \"t\": true,\n" +" \"f\": false,\n" +" \"n\": null,\n" +" \"i\": 123,\n" +" \"pi\": 3.1416,\n" +" \"a\": [1, 2, 3, -1],\n" +" \"u64\": 1234567890123456789,\n" +" \"i64\": -1234567890123456789\n" +"}"; + TEST(PrettyWriter, Basic) { StringBuffer buffer; PrettyWriter writer(buffer); @@ -48,6 +61,16 @@ TEST(PrettyWriter, Basic) { EXPECT_STREQ(kPrettyJson, buffer.GetString()); } +TEST(PrettyWriter, FormatOptions) { + StringBuffer buffer; + PrettyWriter writer(buffer); + writer.SetFormatOptions(kFormatSingleLineArray); + Reader reader; + StringStream s(kJson); + reader.Parse(s, writer); + EXPECT_STREQ(kPrettyJson_FormatOptions_SLA, buffer.GetString()); +} + TEST(PrettyWriter, SetIndent) { StringBuffer buffer; PrettyWriter writer(buffer); diff --git a/3rdparty/rapidjson/test/unittest/readertest.cpp b/3rdparty/rapidjson/test/unittest/readertest.cpp index 32af8a86eec..3f11fec8be3 100644 --- a/3rdparty/rapidjson/test/unittest/readertest.cpp +++ b/3rdparty/rapidjson/test/unittest/readertest.cpp @@ -1,5 +1,5 @@ // Tencent is pleased to support the open source community by making RapidJSON available. -// +// // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. // // Licensed under the MIT License (the "License"); you may not use this file except @@ -7,9 +7,9 @@ // // http://opensource.org/licenses/MIT // -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include "unittest.h" @@ -241,13 +241,13 @@ static void TestParseDouble() { TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form // Since - // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324 - // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324 + // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... �� 10^-324 + // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... �� 10 ^ -324 // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308 TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ // More closer to normal/subnormal boundary - // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308 + // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... �� 10^-308 TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308); TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308); @@ -297,7 +297,7 @@ static void TestParseDouble() { } // Cover trimming - TEST_DOUBLE(fullPrecision, + TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508" "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012" "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306" @@ -306,7 +306,7 @@ static void TestParseDouble() { "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844" "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042" "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901" -"e-308", +"e-308", 2.2250738585072014e-308); { @@ -457,12 +457,12 @@ template struct ParseStringHandler : BaseReaderHandler > { ParseStringHandler() : str_(0), length_(0), copy_() {} ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast(str_)); } - + ParseStringHandler(const ParseStringHandler&); ParseStringHandler& operator=(const ParseStringHandler&); bool Default() { ADD_FAILURE(); return false; } - bool String(const typename Encoding::Ch* str, size_t length, bool copy) { + bool String(const typename Encoding::Ch* str, size_t length, bool copy) { EXPECT_EQ(0, str_); if (copy) { str_ = static_cast(malloc((length + 1) * sizeof(typename Encoding::Ch))); @@ -470,7 +470,7 @@ struct ParseStringHandler : BaseReaderHandler= 128 are assigned to signed integer types. // Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch. @@ -650,7 +650,7 @@ TEST(Reader, ParseString_Error) { // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt - // 3 Malformed sequences + // 3 Malformed sequences // 3.1 Unexpected continuation bytes { @@ -684,19 +684,19 @@ TEST(Reader, ParseString_Error) { } } - // 4 Overlong sequences + // 4 Overlong sequences // 4.1 Examples of an overlong ASCII character TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0')); - // 4.2 Maximum overlong sequences + // 4.2 Maximum overlong sequences TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0')); - // 4.3 Overlong representation of the NUL character + // 4.3 Overlong representation of the NUL character TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0')); TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0')); @@ -778,6 +778,10 @@ TEST(Reader, ParseArray_Error) { TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1}", 2); TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1 2]", 3); + // Array cannot have a trailing comma (without kParseTrailingCommasFlag); + // a value must follow a comma + TEST_ARRAY_ERROR(kParseErrorValueInvalid, "[1,]", 3); + #undef TEST_ARRAY_ERROR } @@ -786,14 +790,14 @@ struct ParseObjectHandler : BaseReaderHandler, ParseObjectHandler> { bool Default() { ADD_FAILURE(); return false; } bool Null() { EXPECT_EQ(8u, step_); step_++; return true; } - bool Bool(bool b) { + bool Bool(bool b) { switch(step_) { case 4: EXPECT_TRUE(b); step_++; return true; case 6: EXPECT_FALSE(b); step_++; return true; default: ADD_FAILURE(); return false; } } - bool Int(int i) { + bool Int(int i) { switch(step_) { case 10: EXPECT_EQ(123, i); step_++; return true; case 15: EXPECT_EQ(1, i); step_++; return true; @@ -804,7 +808,7 @@ struct ParseObjectHandler : BaseReaderHandler, ParseObjectHandler> { } bool Uint(unsigned i) { return Int(static_cast(i)); } bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; } - bool String(const char* str, size_t, bool) { + bool String(const char* str, size_t, bool) { switch(step_) { case 1: EXPECT_STREQ("hello", str); step_++; return true; case 2: EXPECT_STREQ("world", str); step_++; return true; @@ -978,6 +982,10 @@ TEST(Reader, ParseObject_Error) { // Must be a comma or '}' after an object member TEST_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, "{\"a\":1]", 6); + // Object cannot have a trailing comma (without kParseTrailingCommasFlag); + // an object member name must follow a comma + TEST_ERROR(kParseErrorObjectMissName, "{\"a\":1,}", 7); + // This tests that MemoryStream is checking the length in Peek(). { MemoryStream ms("{\"a\"", 1); @@ -1037,7 +1045,7 @@ struct StreamTraits > { }; } // namespace rapidjson -#endif +#endif TEST(Reader, CustomStringStream) { const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } "; @@ -1061,7 +1069,7 @@ public: return c == std::char_traits::eof() ? '\0' : static_cast(c); } - Ch Take() { + Ch Take() { int c = is_.get(); return c == std::char_traits::eof() ? '\0' : static_cast(c); } @@ -1089,7 +1097,7 @@ TEST(Reader, Parse_IStreamWrapper_StringStream) { Reader reader; ParseArrayHandler<4> h; reader.Parse(is, h); - EXPECT_FALSE(reader.HasParseError()); + EXPECT_FALSE(reader.HasParseError()); } // Test iterative parsing. @@ -1119,6 +1127,16 @@ TEST(Reader, IterativeParsing_ErrorHandling) { TESTERRORHANDLING("{\"a\": 1", kParseErrorObjectMissCommaOrCurlyBracket, 7u); TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket, 3u); TESTERRORHANDLING("{\"a: 1", kParseErrorStringMissQuotationMark, 6u); + TESTERRORHANDLING("{\"a\":}", kParseErrorValueInvalid, 5u); + TESTERRORHANDLING("{\"a\":]", kParseErrorValueInvalid, 5u); + TESTERRORHANDLING("[1,2,}", kParseErrorValueInvalid, 5u); + TESTERRORHANDLING("[}]", kParseErrorValueInvalid, 1u); + TESTERRORHANDLING("[,]", kParseErrorValueInvalid, 1u); + TESTERRORHANDLING("[1,,]", kParseErrorValueInvalid, 3u); + + // Trailing commas are not allowed without kParseTrailingCommasFlag + TESTERRORHANDLING("{\"a\": 1,}", kParseErrorObjectMissName, 8u); + TESTERRORHANDLING("[1,2,3,]", kParseErrorValueInvalid, 7u); // Any JSON value can be a valid root element in RFC7159. TESTERRORHANDLING("\"ab", kParseErrorStringMissQuotationMark, 3u); @@ -1177,7 +1195,7 @@ struct IterativeParsingReaderHandler { bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; } bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; } - + bool EndObject(SizeType c) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_ENDOBJECT; @@ -1428,7 +1446,7 @@ TEST(Reader, ParseEmptyOnelineComment) { } TEST(Reader, ParseMultipleCommentsInARow) { - const char* json = + const char* json = "{/* first comment *//* second */\n" "/* third */ /*fourth*/// last one\n" "\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }"; @@ -1523,7 +1541,8 @@ struct NumbersAsStringsHandler { // 'str' is not null-terminated bool RawNumber(const char* str, SizeType length, bool) { EXPECT_TRUE(str != 0); - EXPECT_TRUE(strncmp(str, "3.1416", length) == 0); + EXPECT_TRUE(expected_len_ == length); + EXPECT_TRUE(strncmp(str, expected_, length) == 0); return true; } bool String(const char*, SizeType, bool) { return true; } @@ -1532,24 +1551,227 @@ struct NumbersAsStringsHandler { bool EndObject(SizeType) { return true; } bool StartArray() { return true; } bool EndArray(SizeType) { return true; } + + NumbersAsStringsHandler(const char* expected) + : expected_(expected) + , expected_len_(strlen(expected)) {} + + const char* expected_; + size_t expected_len_; }; TEST(Reader, NumbersAsStrings) { - { - const char* json = "{ \"pi\": 3.1416 } "; - StringStream s(json); - NumbersAsStringsHandler h; - Reader reader; - EXPECT_TRUE(reader.Parse(s, h)); - } - { - char* json = StrDup("{ \"pi\": 3.1416 } "); - InsituStringStream s(json); - NumbersAsStringsHandler h; - Reader reader; - EXPECT_TRUE(reader.Parse(s, h)); - free(json); - } + { + const char* json = "{ \"pi\": 3.1416 } "; + StringStream s(json); + NumbersAsStringsHandler h("3.1416"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + } + { + char* json = StrDup("{ \"pi\": 3.1416 } "); + InsituStringStream s(json); + NumbersAsStringsHandler h("3.1416"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + free(json); + } + { + const char* json = "{ \"gigabyte\": 1.0e9 } "; + StringStream s(json); + NumbersAsStringsHandler h("1.0e9"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + } + { + char* json = StrDup("{ \"gigabyte\": 1.0e9 } "); + InsituStringStream s(json); + NumbersAsStringsHandler h("1.0e9"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + free(json); + } + { + const char* json = "{ \"pi\": 314.159e-2 } "; + StringStream s(json); + NumbersAsStringsHandler h("314.159e-2"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + } + { + char* json = StrDup("{ \"gigabyte\": 314.159e-2 } "); + InsituStringStream s(json); + NumbersAsStringsHandler h("314.159e-2"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + free(json); + } + { + const char* json = "{ \"negative\": -1.54321 } "; + StringStream s(json); + NumbersAsStringsHandler h("-1.54321"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + } + { + char* json = StrDup("{ \"negative\": -1.54321 } "); + InsituStringStream s(json); + NumbersAsStringsHandler h("-1.54321"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + free(json); + } + { + const char* json = "{ \"pi\": 314.159e-2 } "; + std::stringstream ss(json); + IStreamWrapper s(ss); + NumbersAsStringsHandler h("314.159e-2"); + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + } +} + +template +void TestTrailingCommas() { + { + StringStream s("[1,2,3,]"); + ParseArrayHandler<3> h; + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + EXPECT_EQ(5u, h.step_); + } + { + const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false," + "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}"; + StringStream s(json); + ParseObjectHandler h; + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + EXPECT_EQ(20u, h.step_); + } + { + // whitespace around trailing commas + const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false," + "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3\n,\n]\n,\n} "; + StringStream s(json); + ParseObjectHandler h; + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + EXPECT_EQ(20u, h.step_); + } + { + // comments around trailing commas + const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null," + "\"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3/*test*/,/*test*/]/*test*/,/*test*/}"; + StringStream s(json); + ParseObjectHandler h; + Reader reader; + EXPECT_TRUE(reader.Parse(s, h)); + EXPECT_EQ(20u, h.step_); + } +} + +TEST(Reader, TrailingCommas) { + TestTrailingCommas(); +} + +TEST(Reader, TrailingCommasIterative) { + TestTrailingCommas(); +} + +template +void TestMultipleTrailingCommaErrors() { + // only a single trailing comma is allowed. + { + StringStream s("[1,2,3,,]"); + ParseArrayHandler<3> h; + Reader reader; + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorValueInvalid, r.Code()); + EXPECT_EQ(7u, r.Offset()); + } + { + const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false," + "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}"; + StringStream s(json); + ParseObjectHandler h; + Reader reader; + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorObjectMissName, r.Code()); + EXPECT_EQ(95u, r.Offset()); + } +} + +TEST(Reader, MultipleTrailingCommaErrors) { + TestMultipleTrailingCommaErrors(); +} + +TEST(Reader, MultipleTrailingCommaErrorsIterative) { + TestMultipleTrailingCommaErrors(); +} + +template +void TestEmptyExceptForCommaErrors() { + // not allowed even with trailing commas enabled; the + // trailing comma must follow a value. + { + StringStream s("[,]"); + ParseArrayHandler<3> h; + Reader reader; + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorValueInvalid, r.Code()); + EXPECT_EQ(1u, r.Offset()); + } + { + StringStream s("{,}"); + ParseObjectHandler h; + Reader reader; + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorObjectMissName, r.Code()); + EXPECT_EQ(1u, r.Offset()); + } +} + +TEST(Reader, EmptyExceptForCommaErrors) { + TestEmptyExceptForCommaErrors(); +} + +TEST(Reader, EmptyExceptForCommaErrorsIterative) { + TestEmptyExceptForCommaErrors(); +} + +template +void TestTrailingCommaHandlerTermination() { + { + HandlerTerminateAtEndArray h; + Reader reader; + StringStream s("[1,2,3,]"); + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorTermination, r.Code()); + EXPECT_EQ(7u, r.Offset()); + } + { + HandlerTerminateAtEndObject h; + Reader reader; + StringStream s("{\"t\": true, \"f\": false,}"); + ParseResult r = reader.Parse(s, h); + EXPECT_TRUE(reader.HasParseError()); + EXPECT_EQ(kParseErrorTermination, r.Code()); + EXPECT_EQ(23u, r.Offset()); + } +} + +TEST(Reader, TrailingCommaHandlerTermination) { + TestTrailingCommaHandlerTermination(); +} + +TEST(Reader, TrailingCommaHandlerTerminationIterative) { + TestTrailingCommaHandlerTermination(); } #ifdef __GNUC__ diff --git a/3rdparty/rapidjson/test/unittest/strtodtest.cpp b/3rdparty/rapidjson/test/unittest/strtodtest.cpp index a42d96e4a67..cde836c7eb7 100644 --- a/3rdparty/rapidjson/test/unittest/strtodtest.cpp +++ b/3rdparty/rapidjson/test/unittest/strtodtest.cpp @@ -42,7 +42,7 @@ TEST(Strtod, CheckApproximationCase) { u.u = 0x465a72e467d88 | ((static_cast(-149 + kExponentBias)) << kSignificandSize); const double b = u.d; const uint64_t bInt = (u.u & kSignificandMask) | kHiddenBit; - const int bExp = ((u.u & kExponentMask) >> kSignificandSize) - kExponentBias - kSignificandSize; + const int bExp = static_cast(((u.u & kExponentMask) >> kSignificandSize) - kExponentBias - kSignificandSize); EXPECT_DOUBLE_EQ(1.7864e-45, b); EXPECT_EQ(RAPIDJSON_UINT64_C2(0x001465a7, 0x2e467d88), bInt); EXPECT_EQ(-201, bExp); diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 5423c224127..f52e4b03fe6 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2029,8 +2029,6 @@ if (BUSES["TI99X"]~=null) then MAME_DIR .. "src/devices/bus/ti99x/datamux.h", MAME_DIR .. "src/devices/bus/ti99x/genboard.cpp", MAME_DIR .. "src/devices/bus/ti99x/genboard.h", - MAME_DIR .. "src/devices/bus/ti99x/grom.cpp", - MAME_DIR .. "src/devices/bus/ti99x/grom.h", MAME_DIR .. "src/devices/bus/ti99x/gromport.cpp", MAME_DIR .. "src/devices/bus/ti99x/gromport.h", MAME_DIR .. "src/devices/bus/ti99x/handset.cpp", diff --git a/src/devices/bus/abcbus/abc890.cpp b/src/devices/bus/abcbus/abc890.cpp index dc2b88106ae..a188c4f6e76 100644 --- a/src/devices/bus/abcbus/abc890.cpp +++ b/src/devices/bus/abcbus/abc890.cpp @@ -239,9 +239,9 @@ void abc890_t::device_start() void abc890_t::device_reset() { - for (device_t *device = first_subdevice(); device != nullptr; device = device->next()) + for (device_t &device : subdevices()) { - device->reset(); + device.reset(); } } diff --git a/src/devices/bus/ti99_peb/bwg.cpp b/src/devices/bus/ti99_peb/bwg.cpp index 4716ccedf8a..e06dfd5db23 100644 --- a/src/devices/bus/ti99_peb/bwg.cpp +++ b/src/devices/bus/ti99_peb/bwg.cpp @@ -625,10 +625,10 @@ void snug_bwg_device::device_config_complete() elem = nullptr; // Seems to be null when doing a "-listslots" - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->first_subdevice()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->first_subdevice()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->first_subdevice()); - if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->first_subdevice()); + if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); + if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); + if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); + if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->subdevices().first()); } INPUT_PORTS_START( bwg_fdc ) diff --git a/src/devices/bus/ti99_peb/pcode.cpp b/src/devices/bus/ti99_peb/pcode.cpp index 57ee6462874..ff0d9b4c9d5 100644 --- a/src/devices/bus/ti99_peb/pcode.cpp +++ b/src/devices/bus/ti99_peb/pcode.cpp @@ -92,43 +92,87 @@ #define ACTIVE_TAG "ACTIVE" -#define LOG logerror -#define VERBOSE 1 +#define TRACE_ROM 0 +#define TRACE_GROM 0 +#define TRACE_CRU 0 +#define TRACE_SWITCH 0 ti_pcode_card_device::ti_pcode_card_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: ti_expansion_card_device(mconfig, TI99_P_CODE, "TI-99 P-Code Card", tag, owner, clock, "ti99_pcode", __FILE__), m_rom(nullptr), m_bank_select(0), m_switch(false) +: ti_expansion_card_device(mconfig, TI99_P_CODE, "TI-99 P-Code Card", tag, owner, clock, "ti99_pcode", __FILE__), + m_rom(nullptr), + m_bank_select(0), + m_active(false), + m_clock_count(0), + m_clockhigh(false), + m_inDsrArea(false), + m_isrom0(false), + m_isrom12(false), + m_isgrom(false), + m_address(0) { } +SETADDRESS_DBIN_MEMBER( ti_pcode_card_device::setaddress_dbin ) +{ + // Do not allow setaddress for the debugger. It will mess up the + // setaddress/memory access pairs when the CPU enters wait states. + if (space.debugger_access()) return; + + m_address = offset; + m_inDsrArea = ((m_address & m_select_mask)==m_select_value); + + line_state a14 = ((m_address & 2)!=0)? ASSERT_LINE : CLEAR_LINE; + + m_isrom0 = ((m_address & 0xf000)==0x4000); + m_isrom12 = ((m_address & 0xf000)==0x5000); + + // Valid access (GROM write with DBIN=0 or read with DBIN=1) + bool validaccess = (state==CLEAR_LINE || (m_address & 0x0400)==0); + + // GROM access 0101 1011 1111 1100 + m_isgrom = ((m_address & 0xfbfd)==0x5bfc) && validaccess; + + if (validaccess) + { + int lines = (state==ASSERT_LINE)? 1 : 0; + if (a14==ASSERT_LINE) lines |= 2; + line_state select = m_isgrom? ASSERT_LINE : CLEAR_LINE; + + // always deliver to GROM so that the select line may be cleared + for (int i=0; i < 8; i++) + m_grom[i]->set_lines(space, lines, select); + } +} + READ8Z_MEMBER( ti_pcode_card_device::readz ) { - if (m_switch && m_selected && ((offset & m_select_mask)==m_select_value)) + if (m_active && m_inDsrArea && m_selected) { - // GROM access - if ((offset & GROMMASK)==GROMREAD) + if (m_isrom0) { - for (auto & elem : m_grom) elem->readz(space, offset, value, mem_mask); - if (VERBOSE>5) LOG("ti99_pcode: read from grom %04x: %02x\n", offset&0xffff, *value); + *value = m_rom[m_address & 0x0fff]; + if (TRACE_ROM) logerror("Read from rom %04x: %02x\n", offset&0xffff, *value); } else { - if ((offset & 0x1000) == 0x0000) + if (m_isgrom) { - /* Accesses ROM 4732 (4K) */ - // 0000 xxxx xxxx xxxx - *value = m_rom[offset & 0x0fff]; - if (VERBOSE>5) LOG("ti99_pcode: read from rom %04x: %02x\n", offset&0xffff, *value); + for (auto& elem : m_grom) elem->readz(space, m_address, value); + if (TRACE_GROM) logerror("Read from grom %04x: %02x\n", m_address&0xffff, *value); } else { - // Accesses ROM 4764 (2*4K) - // We have two banks here which are activated according - // to the setting of CRU bit 4 - // Bank 0 is the ROM above - // 0001 xxxx xxxx xxxx Bank 1 - // 0010 xxxx xxxx xxxx Bank 2 - *value = m_rom[(m_bank_select<<12) | (offset & 0x0fff)]; - if (VERBOSE>5) LOG("ti99_pcode: read from rom %04x (%02x): %02x\n", offset&0xffff, m_bank_select, *value); + if (m_isrom12) + { + // Accesses ROM 4764 (2*4K) + // We have two banks here which are activated according + // to the setting of CRU bit 4 + // Bank 0 is the ROM above + // 0001 xxxx xxxx xxxx Bank 1 + // 0010 xxxx xxxx xxxx Bank 2 + *value = m_rom[(m_bank_select<<12) | (m_address & 0x0fff)]; + if (TRACE_ROM) logerror("Read from rom %04x (%02x): %02x\n", m_address&0xffff, m_bank_select, *value); + } } } } @@ -140,34 +184,36 @@ READ8Z_MEMBER( ti_pcode_card_device::readz ) */ WRITE8_MEMBER( ti_pcode_card_device::write ) { - if (m_switch && m_selected) + if (m_active && m_isgrom && m_selected) { - if ((offset & m_select_mask)==m_select_value) - { - if (VERBOSE>5) LOG("ti99_pcode: write to address %04x: %02x\n", offset & 0xffff, data); - // 0101 1111 1111 11x0 - if ((offset & GROMMASK) == GROMWRITE) - { - for (auto & elem : m_grom) elem->write(space, offset, data, mem_mask); - } - } + for (auto & elem : m_grom) elem->write(space, m_address, data); } } /* Common READY* line from the GROMs. - At this time we do not emulate GROM READY* since the CPU emulation does - not yet process READY*. If it did, however, we would have to do a similar - handling as in peribox (with INTA*): The common READY* line is a logical - AND of all single READY lines. If any GROM pulls it down, the line goes - down, and only if all GROMs release it, it pulls up again. We should think - about a general solution. */ WRITE_LINE_MEMBER( ti_pcode_card_device::ready_line ) { m_slot->set_ready(state); } +/* + CLKOUT line from the CPU. This line is divided by 8 to generate a 375 Khz + clock input for the GROMs, which are thus running at a lower rate than + those in the console driven by the VDP (477 kHz). +*/ +WRITE_LINE_MEMBER( ti_pcode_card_device::clock_in) +{ + m_clock_count = (m_clock_count+1) & 0x03; // four pulses high, four pulses low + if (m_clock_count==0) + { + // Toggle + m_clockhigh = !m_clockhigh; + for (auto & elem : m_grom) elem->gclock_in(m_clockhigh? ASSERT_LINE : CLEAR_LINE); + } +} + /* CRU read handler. The P-Code card does not offer CRU read lines, so we just ignore any request. (Note that CRU lines are not like memory; you @@ -198,55 +244,22 @@ WRITE8_MEMBER(ti_pcode_card_device::cruwrite) if (addr==0x80) // Bit 4 is on address line 8 { m_bank_select = (data+1); // we're calling this bank 1 and bank 2 - if (VERBOSE>5) LOG("ti99_pcode: select rom bank %d\n", m_bank_select); + if (TRACE_CRU) logerror("Select rom bank %d\n", m_bank_select); } } } -static GROM_CONFIG(pgrom0_config) -{ - false, 0, PCODE_GROM_TAG, 0x0000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom1_config) -{ - false, 1, PCODE_GROM_TAG, 0x2000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom2_config) -{ - false, 2, PCODE_GROM_TAG, 0x4000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom3_config) -{ - false, 3, PCODE_GROM_TAG, 0x6000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom4_config) -{ - false, 4, PCODE_GROM_TAG, 0x8000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom5_config) -{ - false, 5, PCODE_GROM_TAG, 0xa000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom6_config) -{ - false, 6, PCODE_GROM_TAG, 0xc000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(pgrom7_config) -{ - false, 7, PCODE_GROM_TAG, 0xe000, 0x1800, GROMFREQ -}; - void ti_pcode_card_device::device_start() { m_cru_base = 0x1f00; - m_grom[0] = static_cast(subdevice(PGROM0_TAG)); - m_grom[1] = static_cast(subdevice(PGROM1_TAG)); - m_grom[2] = static_cast(subdevice(PGROM2_TAG)); - m_grom[3] = static_cast(subdevice(PGROM3_TAG)); - m_grom[4] = static_cast(subdevice(PGROM4_TAG)); - m_grom[5] = static_cast(subdevice(PGROM5_TAG)); - m_grom[6] = static_cast(subdevice(PGROM6_TAG)); - m_grom[7] = static_cast(subdevice(PGROM7_TAG)); + m_grom[0] = downcast(subdevice(PGROM0_TAG)); + m_grom[1] = downcast(subdevice(PGROM1_TAG)); + m_grom[2] = downcast(subdevice(PGROM2_TAG)); + m_grom[3] = downcast(subdevice(PGROM3_TAG)); + m_grom[4] = downcast(subdevice(PGROM4_TAG)); + m_grom[5] = downcast(subdevice(PGROM5_TAG)); + m_grom[6] = downcast(subdevice(PGROM6_TAG)); + m_grom[7] = downcast(subdevice(PGROM7_TAG)); m_rom = memregion(PCODE_ROM_TAG)->base(); } @@ -264,8 +277,15 @@ void ti_pcode_card_device::device_reset() } m_bank_select = 1; m_selected = false; + m_clock_count = 0; + m_clockhigh = false; - m_switch = ioport(ACTIVE_TAG)->read(); + m_active = ioport(ACTIVE_TAG)->read(); + + m_isrom0 = false; + m_isrom12 = false; + m_isgrom = false; + m_address = 0; } void ti_pcode_card_device::device_config_complete() @@ -274,28 +294,20 @@ void ti_pcode_card_device::device_config_complete() INPUT_CHANGED_MEMBER( ti_pcode_card_device::switch_changed ) { - if (VERBOSE>7) LOG("ti_pcode_card_device: switch changed to %d\n", newval); - m_switch = (newval != 0); + if (TRACE_SWITCH) logerror("Switch changed to %d\n", newval); + m_active = (newval != 0); } MACHINE_CONFIG_FRAGMENT( ti99_pcode ) - MCFG_GROM_ADD( PGROM0_TAG, pgrom0_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM1_TAG, pgrom1_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM2_TAG, pgrom2_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM3_TAG, pgrom3_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM4_TAG, pgrom4_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM5_TAG, pgrom5_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM6_TAG, pgrom6_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) - MCFG_GROM_ADD( PGROM7_TAG, pgrom7_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM0_TAG, 0, PCODE_GROM_TAG, 0x0000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM1_TAG, 1, PCODE_GROM_TAG, 0x2000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM2_TAG, 2, PCODE_GROM_TAG, 0x4000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM3_TAG, 3, PCODE_GROM_TAG, 0x6000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM4_TAG, 4, PCODE_GROM_TAG, 0x8000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM5_TAG, 5, PCODE_GROM_TAG, 0xa000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM6_TAG, 6, PCODE_GROM_TAG, 0xc000, WRITELINE(ti_pcode_card_device, ready_line)) + MCFG_GROM_ADD( PGROM7_TAG, 7, PCODE_GROM_TAG, 0xe000, WRITELINE(ti_pcode_card_device, ready_line)) MACHINE_CONFIG_END INPUT_PORTS_START( ti99_pcode ) diff --git a/src/devices/bus/ti99_peb/pcode.h b/src/devices/bus/ti99_peb/pcode.h index c2a81a1395c..71664682261 100644 --- a/src/devices/bus/ti99_peb/pcode.h +++ b/src/devices/bus/ti99_peb/pcode.h @@ -17,7 +17,7 @@ #include "emu.h" #include "peribox.h" -#include "bus/ti99x/grom.h" +#include "machine/tmc0430.h" extern const device_type TI99_P_CODE; @@ -29,6 +29,9 @@ public: DECLARE_WRITE8_MEMBER(write) override; DECLARE_READ8Z_MEMBER(crureadz) override; DECLARE_WRITE8_MEMBER(cruwrite) override; + DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin) override; + + DECLARE_WRITE_LINE_MEMBER(clock_in) override; DECLARE_WRITE_LINE_MEMBER( ready_line ); DECLARE_INPUT_CHANGED_MEMBER( switch_changed ); @@ -42,10 +45,22 @@ protected: virtual ioport_constructor device_input_ports() const override; private: - ti99_grom_device* m_grom[8]; + tmc0430_device* m_grom[8]; UINT8* m_rom; int m_bank_select; - bool m_switch; + bool m_active; + int m_clock_count; + bool m_clockhigh; + + // Address in card area + bool m_inDsrArea; + + bool m_isrom0; + bool m_isrom12; + bool m_isgrom; + + // Recent address + int m_address; }; #endif diff --git a/src/devices/bus/ti99_peb/peribox.cpp b/src/devices/bus/ti99_peb/peribox.cpp index f91622742d1..52274505533 100644 --- a/src/devices/bus/ti99_peb/peribox.cpp +++ b/src/devices/bus/ti99_peb/peribox.cpp @@ -235,7 +235,7 @@ peribox_device::peribox_device(const machine_config &mconfig, device_type type, : bus8z_device(mconfig, type, name, tag, owner, clock, shortname, source), m_console_inta(*this), m_console_intb(*this), - m_datamux_ready(*this), m_inta_flag(0), m_intb_flag(0), m_ready_flag(0), m_address_prefix(0) + m_datamux_ready(*this), m_inta_flag(0), m_intb_flag(0), m_ready_flag(0), m_address_prefix(0), m_msast(false), m_memen(false) { for (int i=2; i <= 8; i++) m_slot[i] = nullptr; } @@ -258,6 +258,9 @@ WRITE8_MEMBER(peribox_device::write) SETADDRESS_DBIN_MEMBER(peribox_device::setaddress_dbin) { + // Ignore the address when the TI-99/8 transmits the high-order 8 bits + if (!m_memen) return; + for (int i=2; i <= 8; i++) { if (m_slot[i]!=nullptr) m_slot[i]->setaddress_dbin(space, offset | m_address_prefix, state); @@ -300,6 +303,34 @@ WRITE_LINE_MEMBER(peribox_device::senilb) } } +/* + MEMEN input. Used to start the external memory access cycle. +*/ +WRITE_LINE_MEMBER(peribox_device::memen_in) +{ + m_memen = (state==ASSERT_LINE); +} + +/* + MSAST input. Defined by TI-99/8; we ignore this part in the PEB. +*/ +WRITE_LINE_MEMBER(peribox_device::msast_in) +{ + m_msast = (state==ASSERT_LINE); +} + +/* + CLKOUT line +*/ + +WRITE_LINE_MEMBER(peribox_device::clock_in) +{ + for (int i=2; i <= 8; i++) + { + if (m_slot[i]!=nullptr) m_slot[i]->clock_in(state); + } +} + /* The Genmod modification is only of interest for the Geneve. It requires to modify the decoding of each single card. @@ -402,26 +433,11 @@ SLOT_INTERFACE_START( peribox_slot ) SLOT_INTERFACE("tirs232", TI99_RS232) SLOT_INTERFACE("speech", TI99_SPEECH) SLOT_INTERFACE("horizon", TI99_HORIZON) -SLOT_INTERFACE_END - -SLOT_INTERFACE_START( peribox_slot6 ) - SLOT_INTERFACE("ide", TI99_IDE) - SLOT_INTERFACE("usbsm", TI99_USBSM) - SLOT_INTERFACE("tirs232", TI99_RS232) - SLOT_INTERFACE("speech", TI99_SPEECH) -SLOT_INTERFACE_END - -SLOT_INTERFACE_START( peribox_slot7 ) SLOT_INTERFACE("ide", TI99_IDE) SLOT_INTERFACE("usbsm", TI99_USBSM) SLOT_INTERFACE("bwg", TI99_BWG) SLOT_INTERFACE("hfdc", TI99_HFDC) -SLOT_INTERFACE_END - -SLOT_INTERFACE_START( peribox_slot8 ) SLOT_INTERFACE("tifdc", TI99_FDC) - SLOT_INTERFACE("bwg", TI99_BWG) - SLOT_INTERFACE("hfdc", TI99_HFDC) SLOT_INTERFACE_END MACHINE_CONFIG_FRAGMENT( peribox_device ) @@ -429,9 +445,9 @@ MACHINE_CONFIG_FRAGMENT( peribox_device ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT3, peribox_slot ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slot ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slot ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot6 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8 ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot ) MACHINE_CONFIG_END machine_config_constructor peribox_device::device_mconfig_additions() const @@ -453,29 +469,17 @@ peribox_gen_device::peribox_gen_device(const machine_config &mconfig, const char } // The BwG controller will not run with the Geneve due to its wait state -// logic; it assumes that before reading 5FF6 (data register), address 5FF7 -// is also read (by means of the datamux). Unlike the 9900, the 9995 can read -// single bytes, so it will never trigger a read operation on 5FF7. - -SLOT_INTERFACE_START( peribox_slot7nobwg ) - SLOT_INTERFACE("ide", TI99_IDE) - SLOT_INTERFACE("usbsm", TI99_USBSM) - SLOT_INTERFACE("hfdc", TI99_HFDC) -SLOT_INTERFACE_END - -SLOT_INTERFACE_START( peribox_slot8nobwg ) - SLOT_INTERFACE("tifdc", TI99_FDC) - SLOT_INTERFACE("hfdc", TI99_HFDC) -SLOT_INTERFACE_END +// logic (see bwg.c) SLOT_INTERFACE_START( peribox_slotg ) SLOT_INTERFACE("memex", TI99_MEMEX) - SLOT_INTERFACE("myarcmem", TI99_MYARCMEM) - SLOT_INTERFACE("samsmem", TI99_SAMSMEM) - SLOT_INTERFACE("pcode", TI99_P_CODE) SLOT_INTERFACE("tirs232", TI99_RS232) SLOT_INTERFACE("speech", TI99_SPEECH) SLOT_INTERFACE("horizon", TI99_HORIZON) + SLOT_INTERFACE("ide", TI99_IDE) + SLOT_INTERFACE("usbsm", TI99_USBSM) + SLOT_INTERFACE("tifdc", TI99_FDC) + SLOT_INTERFACE("hfdc", TI99_HFDC) SLOT_INTERFACE_END MACHINE_CONFIG_FRAGMENT( peribox_gen_device ) @@ -483,9 +487,9 @@ MACHINE_CONFIG_FRAGMENT( peribox_gen_device ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT3, peribox_slotg ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slotg ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slotg ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot6 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7nobwg ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8nobwg ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slotg ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slotg ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slotg ) MACHINE_CONFIG_END machine_config_constructor peribox_gen_device::device_mconfig_additions() const @@ -509,12 +513,11 @@ peribox_998_device::peribox_998_device(const machine_config &mconfig, const char // the 99/8; it was intended to use the Hexbus interface. None of the memory // expansions are really supposed to work here. SLOT_INTERFACE_START( peribox_slot998 ) - SLOT_INTERFACE("myarcmem", TI99_MYARCMEM) - SLOT_INTERFACE("samsmem", TI99_SAMSMEM) - SLOT_INTERFACE("horizon", TI99_HORIZON) SLOT_INTERFACE("ide", TI99_IDE) SLOT_INTERFACE("usbsm", TI99_USBSM) SLOT_INTERFACE("tirs232", TI99_RS232) + SLOT_INTERFACE("tifdc", TI99_FDC) + SLOT_INTERFACE("hfdc", TI99_HFDC) SLOT_INTERFACE_END MACHINE_CONFIG_FRAGMENT( peribox_998_device ) @@ -524,7 +527,7 @@ MACHINE_CONFIG_FRAGMENT( peribox_998_device ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slot998 ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot998 ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot998 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8nobwg ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot998 ) MACHINE_CONFIG_END machine_config_constructor peribox_998_device::device_mconfig_additions() const @@ -546,7 +549,14 @@ SLOT_INTERFACE_START( peribox_slotp ) SLOT_INTERFACE("pcode", TI99_P_CODE) SLOT_INTERFACE("tirs232", TI99_RS232) SLOT_INTERFACE("speech", TI99_SPEECH) + SLOT_INTERFACE("myarcmem", TI99_MYARCMEM) + SLOT_INTERFACE("samsmem", TI99_SAMSMEM) SLOT_INTERFACE("horizon", TI99_HORIZON) + SLOT_INTERFACE("ide", TI99_IDE) + SLOT_INTERFACE("usbsm", TI99_USBSM) + SLOT_INTERFACE("bwg", TI99_BWG) + SLOT_INTERFACE("hfdc", TI99_HFDC) + SLOT_INTERFACE("tifdc", TI99_FDC) SLOT_INTERFACE_END SLOT_INTERFACE_START( peribox_ev_slot ) @@ -562,9 +572,9 @@ MACHINE_CONFIG_FRAGMENT( peribox_sg_device ) MCFG_PERIBOX_SLOT_ADD_DEF( PEBSLOT3, peribox_hs_slot, "hsgpl" ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slotp ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slotp ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot6 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8 ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slotp ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slotp ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slotp ) MACHINE_CONFIG_END machine_config_constructor peribox_sg_device::device_mconfig_additions() const @@ -588,9 +598,9 @@ MACHINE_CONFIG_FRAGMENT( peribox_ev_device ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT3, peribox_slot ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slot ) MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slot ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot6 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7 ) - MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8 ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot ) + MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot ) MACHINE_CONFIG_END machine_config_constructor peribox_ev_device::device_mconfig_additions() const @@ -653,6 +663,11 @@ WRITE_LINE_MEMBER( peribox_slot_device::senilb ) m_card->set_senilb(state); } +WRITE_LINE_MEMBER( peribox_slot_device::clock_in ) +{ + m_card->clock_in(state); +} + /* Genmod support */ @@ -668,7 +683,7 @@ void peribox_slot_device::device_start(void) void peribox_slot_device::device_config_complete() { m_slotnumber = get_index_from_tagname(); - device_t *carddev = first_subdevice(); + device_t *carddev = subdevices().first(); peribox_device *peb = static_cast(owner()); if (carddev != nullptr) { diff --git a/src/devices/bus/ti99_peb/peribox.h b/src/devices/bus/ti99_peb/peribox.h index 429d8ba8610..fa390cc2b88 100644 --- a/src/devices/bus/ti99_peb/peribox.h +++ b/src/devices/bus/ti99_peb/peribox.h @@ -43,7 +43,7 @@ public: template static devcb_base &static_set_intb_callback(device_t &device, _Object object) { return downcast(device).m_console_intb.set_callback(object); } template static devcb_base &static_set_ready_callback(device_t &device, _Object object) { return downcast(device).m_datamux_ready.set_callback(object); } - // Next seven methods are called from the console + // Next eight methods are called from the console DECLARE_READ8Z_MEMBER(readz) override; DECLARE_WRITE8_MEMBER(write) override; DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin) override; @@ -53,6 +53,11 @@ public: DECLARE_WRITE_LINE_MEMBER(senila); DECLARE_WRITE_LINE_MEMBER(senilb); + DECLARE_WRITE_LINE_MEMBER( memen_in ); + DECLARE_WRITE_LINE_MEMBER( msast_in ); + + DECLARE_WRITE_LINE_MEMBER( clock_in ); + // Part of configuration void set_prefix(int prefix) { m_address_prefix = prefix; } @@ -86,6 +91,12 @@ protected: // The TI-99/4(A) Flex Cable Interface (slot 1) pulls up the AMA/AMB/AMC lines to 1/1/1. int m_address_prefix; + + // Most significant address byte strobe. Defined by TI-99/8. + bool m_msast; + + // Memory enable. + bool m_memen; }; /************************************************************************ @@ -157,6 +168,7 @@ public: DECLARE_WRITE_LINE_MEMBER(senila); DECLARE_WRITE_LINE_MEMBER(senilb); + DECLARE_WRITE_LINE_MEMBER(clock_in); // Called from the card (direction to box) DECLARE_WRITE_LINE_MEMBER( set_inta ); @@ -207,6 +219,8 @@ public: void set_senila(int state) { m_senila = state; } void set_senilb(int state) { m_senilb = state; } + virtual DECLARE_WRITE_LINE_MEMBER(clock_in) { }; + protected: peribox_slot_device *m_slot; // using a link to the slot for callbacks int m_senila; diff --git a/src/devices/bus/ti99_peb/ti_fdc.cpp b/src/devices/bus/ti99_peb/ti_fdc.cpp index 82585c424ce..97d5962e3cb 100644 --- a/src/devices/bus/ti99_peb/ti_fdc.cpp +++ b/src/devices/bus/ti99_peb/ti_fdc.cpp @@ -390,9 +390,9 @@ void ti_fdc_device::device_reset() void ti_fdc_device::device_config_complete() { // Seems to be null when doing a "-listslots" - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->first_subdevice()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->first_subdevice()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->first_subdevice()); + if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); + if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); + if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); } FLOPPY_FORMATS_MEMBER(ti_fdc_device::floppy_formats) diff --git a/src/devices/bus/ti99x/998board.cpp b/src/devices/bus/ti99x/998board.cpp index 0d1f081ed1b..595ee5f77b1 100644 --- a/src/devices/bus/ti99x/998board.cpp +++ b/src/devices/bus/ti99x/998board.cpp @@ -14,71 +14,795 @@ Note: The TI-99/8's internal codename was "Armadillo" -============================== - Mapper (codename "Amigo") -============================== - Initial setting of mapper (as defined in the power-up routine, TI-99/4A mode) + +-------+ +--------+ + | CPU |========LogAddrBus======| Mapper |====PhysAddrBus========== + | TMS | || | AMIGO | || + | 9995 | +----------+ | | +----------+ + | | | Logical | +--------+ | Physical | + +-------+ | space | | | space | + | decoder | | | decoder | + | VAQUERRO | | | MOFETTA | + +----------+ | +----------+ + | | | + +--------------------+ | +---------------------+ + | Devices | | | Devices | + | +-------+ | | | + | ROM0 | SRAM | | | DRAM (POLLO) | + | Video | ---- | | | ROM1 | + | Speech | Maps--+--+ | Cartridge port | + | GROM +-------+ | PEB | + | Sound | | Hexbus (OSO) | + +--------------------+ +---------------------+ - 0 00ff0000 -> Unmapped; logical address 0000...0fff = ROM0 - 1 00ff0000 -> Unmapped; logical address 1000...1fff = ROM0 - 2 00000800 -> DRAM; 2000 = 000800, 2fff = 0017ff - 3 00001800 -> DRAM; 3000 = 001800, 3fff = 0027ff - 4 00ff4000 -> DSR space (internal / ioport) - 5 00ff5000 -> DSR space (internal / ioport) - 6 00ff6000 -> Cartridge space (6000..6fff) - 7 00ff7000 -> Cartridge space (7000..7fff) - 8 00ff0000 -> Unmapped; device ports (VDP) and SRAM - 9 00ff0000 -> Unmapped; device ports (Speech, GROM) - A 00002800 -> DRAM; a000 = 002800, afff = 0037ff - B 00003800 -> DRAM; b000 = 003800, bfff = 0047ff - C 00004800 -> DRAM; c000 = 004800, cfff = 0057ff - D 00005800 -> DRAM; d000 = 005800, dfff = 0067ff - E 00006800 -> DRAM; e000 = 006800, efff = 0077ff - F 00007800 -> DRAM; f000 = 007800, ffff = 0087ff + Custom chips + ------------ + The chipset of the TI-99/8 consists of five specifically programmed chips. + All are nicknamed after some Spanish words (albeit sometimes misspelled) - Format of map table entry (not emulated) + VAQUERRO: Logical Address Space decoder ("Vaquero" = "Cowboy") + MOFETTA : Physical Address Space decoder ("Mofeta" = "Skunk") + AMIGO : Mapper ("Amigo" = "Friend") + OSO : Hexbus adapter ("Oso" = "Bear") + POLLO : DRAM controller (Not emulated) ("Pollo" = "Chicken") - +------+------+------+------+---+---+---+---------+----------+---------+ - | WProt| XProt| RProt| * | 0 | 0 | 0 | Upper | High | Low | - +------+------+------+------+---+---+---+---------+----------+---------+ + See the comments for the respective chip implementation for details. - WProt: Write protection if set to 1 - XProt: Execute protection if set to 1 - RProt: Read protection if set to 1 - When a protection violation occurs, the tms9901 INT1* pin is pulled low - (active). The pin remains low until the mapper status register is read. + ROM contents + ------------ + The ROM0 chip is accessible at addresses 0000-1FFF in the logical address + space of the compatibility mode. It contains the GPL interpreter. In + native mode the ROM0 chip is invisible. - Address handling - ---------------- - Physical address is (Upper * 2^16) + (High * 2^8) + Low + ROM0 + offset Logical address Name + ----------------------------------- + 0000 0000-1FFF ROM0 - The mapper calculates the actual physical address by looking up the - table entry from the first four bits of the logical address and then - *adding* the remaining 12 bits of the logical address on the map value. - The value 0xff0000 is used to indicate a non-mapped area. + The ROM1 chip contains 32 KiB of various system software. It is located in + the physical address space, so it must be mapped into the logical address + space by defining an appropriate map. - Mapper control register - ----------------------- - The mapper control register is used to initiate a map load/save operation. + ROM1 + offset Physical address Name + ---------------------------------------------------------- + 0000 FFA000-FFDFFF ROM1 + 4000 FF4000-FF5FFF @CRU>2700 Text-to-speech ROM/DSR + 6000 FF4000-FF5FFF @CRU>1700 Hexbus DSR - +---+---+---+---+---+---+---+---+ - | 0 | 0 | 0 | 0 | Map File | RW| - +---+---+---+---+---+---+---+---+ + The DSR portions have to be selected via the CRU bits >1700 or >2700. - The map file is a number from 0-7 indicating the set of map values for the - operation, which means the location in SRAM where the next 64 values are - loaded from or stored into. - RW = 1: load from SRAM into mapper - RW = 0: store from mapper into SRAM + CRU map (I/O address space) + =========================== + 0000-003e: TMS9901 system interface (see ti99_8.c) + 1700-17fe: Hexbus + 2000-26fe: Future external devices + 2700-27fe: Additional ROM ("internal DSR") + 2702 : System reset (when set to 1) + 2800-3ffe: Future external devices + 4000-fffe: Future external devices - When read, the mapper register returns the violation flags: - +------+------+------+---+---+---+---+---+ - | WProt| XProt| RProt| 0 | 0 | 0 | 0 | 0 | - +------+------+------+---+---+---+---+---+ + The TMS9995 offers the full 15-bit CRU address space. Devices designed for + the TI-99/4A should only be accessed in the area 1000-1ffe. They will (by + design) incompletely decode the CRU address and be mirrored in the higher + areas. + + Note that the cartridge port of the TI-99/8 offers support for 16K ROM + cartridges, but lacks CRU support. + + Michael Zapf, October 2010 + February 2012: Rewritten as class + March 2016: Redesigned for custom chip emulation + + Informations taken from + [1] ARMADILLO PRODUCT SPECIFICATIONS + [2] TI-99/8 Graphics Programming Language interpreter + +***************************************************************************/ + +// TODO: +// - PEB + +#include "998board.h" + +#define TRACE_CRU 0 +#define TRACE_ADDRESS 0 +#define TRACE_MAP 0 +#define TRACE_OSO 0 +#define TRACE_DECODE 0 +#define TRACE_READY 0 +#define TRACE_MEM 0 +#define TRACE_CLOCK 0 +#define TRACE_DETAIL 0 +#define TRACE_MOFETTA 0 +#define TRACE_AMIGO 0 +#define TRACE_WS 0 +#define TRACE_CPURY 0 +#define TRACE_GROM 0 +#define TRACE_PUNMAP 0 + +mainboard8_device::mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MAINBOARD8, "TI-99/8 Mainboard", tag, owner, clock, "ti998_mainboard", __FILE__), + m_pending_write(false), + m_speech_ready(true), + m_sound_ready(true), + m_pbox_ready(true), + m_ready(*this), + m_console_reset(*this), + m_hold_line(*this), + m_vaquerro(*this, VAQUERRO_TAG), + m_mofetta(*this, MOFETTA_TAG), + m_amigo(*this, AMIGO_TAG), + m_oso(*this, OSO_TAG) +{ +} + +// =============== CRU bus access ================== + +READ8Z_MEMBER(mainboard8_device::crureadz) +{ + m_peb->crureadz(space, offset, value); +} + +/* + CRU handling. Mofetta is the only chip that bothers to handle it, beside the PEB +*/ +WRITE8_MEMBER(mainboard8_device::cruwrite) +{ + m_mofetta->cruwrite(space, offset, data); + m_peb->cruwrite(space, offset, data); +} + +// =============== Memory bus access ================== + +WRITE_LINE_MEMBER( mainboard8_device::dbin_in ) +{ + m_dbin_level = (line_state)state; +} + +SETOFFSET_MEMBER( mainboard8_device::setoffset ) +{ + if (TRACE_ADDRESS) logerror("set %s %04x\n", (m_dbin_level==ASSERT_LINE)? "R" : "W", offset); + + // No data is waiting on the data bus + m_pending_write = false; + + // Memory cycle begins + m_vaquerro->memen_in(ASSERT_LINE); + m_amigo->memen_in(ASSERT_LINE); + + // Save the logical address + m_logical_address = offset; + m_physical_address = 0; + + // In TI's bit order, A14 is the second line from the right side (2^1) + m_A14_set = ((m_logical_address & 2)!=0); // Needed for clock_in + + // Check for match in logical space + m_vaquerro->set_address(space, m_logical_address, m_dbin_level); + + // Select GROMs if addressed + select_groms(); + + // Speech select lines will always be asserted/cleared as soon as the address is available + m_speech->wsq_w((m_vaquerro->spwt_out() == ASSERT_LINE)? FALSE : TRUE); + m_speech->rsq_w((m_vaquerro->sprd_out() == ASSERT_LINE)? FALSE : TRUE); + + // If it is a logical space address, tell the mapper to stay inactive + line_state lasreq = (line_state)m_vaquerro->lascsq_out(); + m_amigo->lascs_in(lasreq); + m_mofetta->lascs_in(lasreq); + + // Need to set the address in any case so that the lines can be cleared + m_amigo->set_address(space, m_logical_address); + + // AMIGO is the one to control the READY line to the CPU + // MOFETTA does not contribute to READY + m_ready(m_amigo->cpury_out()); +} + +WRITE_LINE_MEMBER( mainboard8_device::reset_console ) +{ + m_console_reset(state); +} + +WRITE_LINE_MEMBER( mainboard8_device::hold_cpu ) +{ + m_hold_line(state); +} + +/* + HOLD Acknowledge from the CPU +*/ +WRITE_LINE_MEMBER( mainboard8_device::holda_line ) +{ + m_amigo->holda_in(state); +} + +/* + Clock line from the CPU. Forward to the custom chips. +*/ +WRITE_LINE_MEMBER( mainboard8_device::clock_in ) +{ + if (TRACE_CLOCK) logerror("CLKOUT = %d\n", state); + + // Propagate to Vaquerro; may change GGRDY (trailing edge) and the GROM select lines + m_vaquerro->clock_in((line_state)state); + + // Set the incoming ready line of Amigo (Mapper) before the clock + bool readycomb = ((m_vaquerro->ggrdy_out()==ASSERT_LINE) && m_speech_ready && m_sound_ready && m_pbox_ready); + m_amigo->srdy_in(readycomb? ASSERT_LINE : CLEAR_LINE); + + // This may change the incoming READY lines of Vaquerro + if (state==CLEAR_LINE) select_groms(); + + m_amigo->clock_in((line_state)state); + + // Mofetta only needs the clock to produce the GROM clock + m_mofetta->clock_in(state); + + m_mofetta->skdrcs_in(m_amigo->skdrcs_out()); + + int gromclk = m_mofetta->gromclk_out(); + + if (gromclk != m_gromclk) // when it changed, propagate to the GROMs + { + m_gromclk = gromclk; + for (int i=0; i < 8; i++) + { + if (i < 3) + { + m_sgrom[i]->gclock_in(gromclk); + m_p3grom[i]->gclock_in(gromclk); + } + m_tsgrom[i]->gclock_in(gromclk); + m_p8grom[i]->gclock_in(gromclk); + } + m_gromport->gclock_in(gromclk); + } + + // Check video for writing + if (m_pending_write && m_vaquerro->vdpwt_out()==ASSERT_LINE) + { + if (m_A14_set) m_video->register_write(*m_space, 0, m_latched_data); + else m_video->vram_write(*m_space, 0, m_latched_data); + m_pending_write = false; + if (TRACE_MEM) logerror("Write %04x (video) <- %02x\n", m_logical_address, m_latched_data); + cycle_end(); + return; + } + + // Propagate the READY signal + m_ready(m_amigo->cpury_out()); + + // In case we're reading, the CPU will now do the READ operation. + // Otherwise we must do the write operation now which we postponed before. + + if (m_pending_write && (state==CLEAR_LINE)) + { + if (m_amigo->skdrcs_out()==ASSERT_LINE) + { + m_dram[m_physical_address & 0xffff] = m_latched_data; + m_pending_write = false; + if (TRACE_MEM) logerror("Write %04x (phys %06x, DRAM) <- %02x\n", m_logical_address, m_physical_address, m_latched_data); + } + + if (m_mofetta->alccs_out()==ASSERT_LINE) + { + m_oso->write(*m_space, m_physical_address>>1, m_latched_data); + m_pending_write = false; + if (TRACE_MEM) logerror("Write %04x (phys %06x, OSO) <- %02x\n", m_logical_address, m_physical_address, m_latched_data); + } + + if (m_mofetta->cmas_out()==ASSERT_LINE) + { + m_gromport->romgq_line(ASSERT_LINE); + m_gromport->write(*m_space, m_physical_address & 0x3fff, m_latched_data); + m_pending_write = false; + if (TRACE_MEM) logerror("Write %04x (phys %06x, cartridge) <- %02x\n", m_logical_address, m_physical_address, m_latched_data); + } + else + { + m_gromport->romgq_line(CLEAR_LINE); + } + + if (m_mofetta->dbc_out()==ASSERT_LINE) + { + m_peb->write(*m_space, m_physical_address, m_latched_data); + m_pending_write = false; + if (TRACE_MEM) logerror("Write %04x (phys %06x, PEB) <- %02x\n", m_logical_address, m_physical_address, m_latched_data); + } + } + + if (m_dbin_level==CLEAR_LINE && !m_pending_write) // Memory cycle ends + cycle_end(); +} + +void mainboard8_device::select_groms() +{ + // Select the GROM libs + // Note that we must also deselect them again, so we have to visit each + // one of them + + int select = m_vaquerro->gromcs_out(); + + // Avoid to be called too often; this would have a bad penalty on emulation performance + // This simple check actually increases bench performance from 120% to 240% + if (select != m_prev_grom) + { + m_prev_grom = select; + int lines = (m_dbin_level==ASSERT_LINE)? GROM_M_LINE : 0; + if (m_A14_set) lines |= GROM_MO_LINE; + + for (int i=0; i < 8; i++) + { + if (i < 3) + { + m_sgrom[i]->set_lines(*m_space, lines, select & SGMSEL); + m_p3grom[i]->set_lines(*m_space, lines, select & P3GSEL); + } + m_tsgrom[i]->set_lines(*m_space, lines, select & TSGSEL); + m_p8grom[i]->set_lines(*m_space, lines, select & P8GSEL); + } + // Write to the cartridge port. The GROMs on cartridges are accesses as system GROMs + if (select & SGMSEL) m_gromport->romgq_line(CLEAR_LINE); + m_gromport->set_gromlines(*m_space, lines, select & SGMSEL); + } + + // If we're planning to write to the GROMs, let's do it right now + if (select !=0 && m_pending_write) + { + m_pending_write = false; + switch (select) + { + case SGMSEL: + for (int i=0; i < 3; i++) + { + m_sgrom[i]->write(*m_space, 0, m_latched_data); + } + if (TRACE_MEM) logerror("Write GS <- %02x\n", m_latched_data); + m_gromport->write(*m_space, 0, m_latched_data); + break; + + case TSGSEL: + for (int i=0; i < 8; i++) + { + m_tsgrom[i]->write(*m_space, 0, m_latched_data); + } + if (TRACE_MEM) logerror("Write GT <- %02x\n", m_latched_data); + break; + + case P8GSEL: + for (int i=0; i < 8; i++) + { + m_p8grom[i]->write(*m_space, 0, m_latched_data); + } + if (TRACE_MEM) logerror("Write G8 <- %02x\n", m_latched_data); + break; + + case P3GSEL: + for (int i=0; i < 3; i++) + { + m_p3grom[i]->write(*m_space, 0, m_latched_data); + } + if (TRACE_MEM) logerror("Write G3 <- %02x\n", m_latched_data); + break; + + default: + logerror("Error: Multiple GROM libs selected: SGM=%d TSG=%d P8G=%d P3G=%d\n", (select & SGMSEL)!=0, (select & TSGSEL)!=0, (select & P8GSEL)!=0, (select & P3GSEL)!=0); + break; + } + } +} + +void mainboard8_device::set_paddress(int address) +{ + // Keep this value as the current address + m_physical_address = (m_physical_address << 16) | address; + if (TRACE_DETAIL) logerror("Setting physical address %06x\n", m_physical_address); + + m_mofetta->set_address(*m_space, address, m_dbin_level); + m_peb->setaddress_dbin(*m_space, address, m_dbin_level); +} + +WRITE_LINE_MEMBER( mainboard8_device::msast_in ) +{ + if (TRACE_DETAIL) logerror("msast = %d\n", state); + + // Start physical space cycle on the trailing edge + if (state==CLEAR_LINE) + { + m_mofetta->pmemen_in(ASSERT_LINE); + m_peb->memen_in(ASSERT_LINE); + } + m_mofetta->msast_in(state); + m_peb->msast_in(state); +} + + +READ8_MEMBER( mainboard8_device::read ) +{ + UINT8 value = 0; + const char* what; + + // ================================================= + // Logical space + // ================================================= + if (m_amigo->mapper_accessed()) + { + value = m_amigo->read(space, 0); + what = "mapper"; + goto readdone; + } + + if (m_amigo->sramcs_out()==ASSERT_LINE) + { + value = m_sram[m_logical_address & 0x07ff]; + what = "SRAM"; + goto readdone; + } + + if (m_vaquerro->lascsq_out()==ASSERT_LINE) + { + // VDP access + if (m_vaquerro->vdprd_out()==ASSERT_LINE) + { + value = m_A14_set? m_video->register_read(space, 0) : m_video->vram_read(space, 0); + what = "video"; + goto readdone; + } + + // System ROM0 + if (m_vaquerro->sromcs_out()==ASSERT_LINE) + { + value = m_rom0[m_logical_address & 0x1fff]; + what = "ROM0"; + goto readdone; + } + + // Speech + if (m_vaquerro->sprd_out()==ASSERT_LINE) + { + value = m_speech->status_r(space, 0) & 0xff; + what = "speech"; + goto readdone; + } + + // GROMs + switch (m_vaquerro->gromcs_out()) + { + case SGMSEL: + for (int i=0; i < 3; i++) + { + m_sgrom[i]->readz(space, 0, &value); + } + m_gromport->readz(space, 0, &value); + if (TRACE_GROM && !m_A14_set) logerror("GS>%04x\n", m_sgrom[0]->debug_get_address()-1); + what = "system GROM"; + goto readdone; + + case TSGSEL: + for (int i=0; i < 8; i++) + { + m_tsgrom[i]->readz(space, 0, &value); + } + if (TRACE_GROM && !m_A14_set) logerror("GT>%04x\n", m_tsgrom[0]->debug_get_address()-1); + what = "TTS GROM"; + goto readdone; + + case P8GSEL: + for (int i=0; i < 8; i++) + { + m_p8grom[i]->readz(space, 0, &value); + } + if (TRACE_GROM && !m_A14_set) logerror("G8>%04x\n", m_p8grom[0]->debug_get_address()-1); + what = "P8 GROM"; + goto readdone; + + case P3GSEL: + for (int i=0; i < 3; i++) + { + m_p3grom[i]->readz(space, 0, &value); + } + if (TRACE_GROM && !m_A14_set) logerror("G3>%04x\n", m_p3grom[0]->debug_get_address()-1); + what = "P3 GROM"; + goto readdone; + default: + break; + } + + // These messages appear in fact every time that a GPL command writes + // an immediate value to a write-only address (like 9400) because the + // GPL interpreter always tries to load the value from the provided memory address first + + logerror("Read %04x (unmapped) ignored\n", m_logical_address); + + // Memory cycle ends + cycle_end(); + return 0; + } + else + { + // ================================================= + // Physical space + // ================================================= + if (m_amigo->skdrcs_out()==ASSERT_LINE) + { + value = m_dram[m_physical_address & 0xffff]; + what = "DRAM"; + goto readdonephys; + } + + if (m_mofetta->rom1cs_out()==ASSERT_LINE) + { + int address = (m_physical_address & 0x1fff); + if (m_mofetta->rom1am_out()==ASSERT_LINE) address |= 0x4000; + if (m_mofetta->rom1al_out()==ASSERT_LINE) address |= 0x2000; + value = m_rom1[address]; + + if (TRACE_MEM) logerror("Read %04x (ROM1@%04x) -> %02x\n", m_logical_address, address, value); + cycle_end(); + return value; + } + + if (m_mofetta->alccs_out()==ASSERT_LINE) + { + value = m_oso->read(*m_space, m_physical_address>>1); + what = "OSO"; + goto readdonephys; + } + + if (m_mofetta->prcs_out()==ASSERT_LINE) + { + value = m_pascalrom[m_physical_address & 0x3fff]; + what = "PASCAL"; + goto readdonephys; + } + + if (m_mofetta->cmas_out()==ASSERT_LINE) + { + m_gromport->romgq_line(ASSERT_LINE); + m_gromport->readz(*m_space, m_physical_address & 0x3fff, &value); + what = "Cartridge"; + goto readdonephys; + } + + if (m_mofetta->dbc_out()==ASSERT_LINE) + { + m_peb->readz(*m_space, m_physical_address & 0xffff, &value); + what = "PEB"; + goto readdonephys; + } + + if (TRACE_PUNMAP) logerror("Read %04x (phys %06x, unmapped) ignored\n", m_logical_address, m_physical_address); + + // Memory cycle ends + cycle_end(); + return 0; + } + + +readdone: + if (TRACE_MEM) logerror("Read %04x (%s) -> %02x\n", m_logical_address, what, value); + cycle_end(); + return value; + +readdonephys: + if (TRACE_MEM) logerror("Read %04x (phys %06x, %s) -> %02x\n", m_logical_address, m_physical_address, what, value); + cycle_end(); + return value; +} + +void mainboard8_device::cycle_end() +{ + // Memory cycle ends + m_vaquerro->memen_in(CLEAR_LINE); + m_amigo->memen_in(CLEAR_LINE); + m_mofetta->pmemen_in(CLEAR_LINE); + m_peb->memen_in(CLEAR_LINE); +} + +/* + When writing, the emulation relies on a push mechanism; the write + operation follows the setaddress operation immediately. + + If the READY line is pulled down due to the mapping process, we must + store the data bus value until the physical address is available. +*/ +WRITE8_MEMBER( mainboard8_device::write ) +{ + m_latched_data = data; + m_space = &space; + m_pending_write = true; + + // Some logical space devices can be written immediately + // GROMs and video must wait to be selected + if (m_amigo->mapper_accessed()) + { + if (TRACE_MEM) logerror("Write %04x (mapper) <- %02x\n", m_logical_address, data); + m_amigo->write(space, 0, data); + m_pending_write = false; + } + + // Sound ... we have to put it before SRAM because in compatibility mode the + // sound address lies within the SRAM area + if (m_vaquerro->sccs_out()==ASSERT_LINE) + { + if (TRACE_MEM) logerror("Write %04x (sound) <- %02x\n", m_logical_address, data); + m_sound->write(space, 0, data); // Sound chip will lower READY after this access + m_pending_write = false; + } + else + { + // SRAM + if (m_amigo->sramcs_out()==ASSERT_LINE) + { + if (TRACE_MEM) logerror("Write %04x (SRAM) <- %02x\n", m_logical_address, data); + m_sram[m_logical_address & 0x07ff] = data; + m_pending_write = false; + } + } + + // Speech + if (m_vaquerro->spwt_out()==ASSERT_LINE) + { + if (TRACE_MEM) logerror("Write %04x (speech) <- %02x\n", m_logical_address, data); + m_speech->data_w(space, 0, data); + m_pending_write = false; + } + + if (!m_pending_write) + cycle_end(); + + // The remaining physical devices will respond as soon as the physical address is completely set +} + +/* + Set 99/4A compatibility mode (CRUS=1) +*/ +WRITE_LINE_MEMBER( mainboard8_device::crus_in ) +{ + if (TRACE_CRU) logerror("%s CRUS\n", (state==1)? "Assert" : "Clear"); + m_vaquerro->crus_in(state); + m_amigo->crus_in(state); +} + +/* + Set mapper /PTGEN line ("Pascal and Text-to-speech GROMs enable"). + Note that PTGEN is negative logic. +*/ +WRITE_LINE_MEMBER( mainboard8_device::ptgen_in ) +{ + if (TRACE_CRU) logerror("%s PTGEN*\n", (state==0)? "Assert" : "Clear"); + m_vaquerro->crusgl_in((state==0)? ASSERT_LINE : CLEAR_LINE); +} + + +/* + READY lines, to be combined +*/ +WRITE_LINE_MEMBER( mainboard8_device::system_grom_ready ) +{ + m_vaquerro->sgmry(state); +} + +WRITE_LINE_MEMBER( mainboard8_device::ptts_grom_ready ) +{ + m_vaquerro->tsgry(state); +} + +WRITE_LINE_MEMBER( mainboard8_device::p8_grom_ready ) +{ + m_vaquerro->p8gry(state); +} + +WRITE_LINE_MEMBER( mainboard8_device::p3_grom_ready ) +{ + m_vaquerro->p3gry(state); +} + +WRITE_LINE_MEMBER( mainboard8_device::sound_ready ) +{ + m_sound_ready = state; +} + +WRITE_LINE_MEMBER( mainboard8_device::speech_ready ) +{ + // The TMS5200 implementation uses TRUE/FALSE, not ASSERT/CLEAR semantics + m_speech_ready = (state==FALSE)? ASSERT_LINE : CLEAR_LINE; +} + +WRITE_LINE_MEMBER( mainboard8_device::pbox_ready ) +{ + m_pbox_ready = state; +} + +WRITE_LINE_MEMBER( mainboard8_device::ggrdy_in ) +{ + m_amigo->srdy_in((state==ASSERT_LINE && m_speech_ready && m_sound_ready && m_pbox_ready)? ASSERT_LINE : CLEAR_LINE); +} + +static const char *const glib0[] = { SYSGROM0_TAG, SYSGROM1_TAG, SYSGROM2_TAG }; +static const char *const glib1[] = { GLIB10_TAG, GLIB11_TAG, GLIB12_TAG, GLIB13_TAG, GLIB14_TAG, GLIB15_TAG, GLIB16_TAG, GLIB17_TAG }; +static const char *const glib2[] = { GLIB20_TAG, GLIB21_TAG, GLIB22_TAG, GLIB23_TAG, GLIB24_TAG, GLIB25_TAG, GLIB26_TAG, GLIB27_TAG }; +static const char *const glib3[] = { GLIB30_TAG, GLIB31_TAG, GLIB32_TAG }; + +void mainboard8_device::device_start() +{ + logerror("Starting main board\n"); + // Lines going to the main driver class, then to the CPU + m_ready.resolve_safe(); // READY + m_console_reset.resolve_safe(); // RESET + m_hold_line.resolve_safe(); // HOLD + + // Setting up the links to the GROMs + for (int i=0; i < 8; i++) + { + if (i < 3) + { + m_sgrom[i] = downcast(machine().device(glib0[i])); + m_p3grom[i] = downcast(machine().device(glib3[i])); + } + m_tsgrom[i] = downcast(machine().device(glib1[i])); + m_p8grom[i] = downcast(machine().device(glib2[i])); + } + + // Link to speech synthesizer + m_speech = downcast(machine().device(SPEECHSYN_TAG)); + + // Link to sound chip + m_sound = downcast(machine().device(TISOUNDCHIP_TAG)); + + // Link to video + m_video = downcast(machine().device(VDP_TAG)); + + // Link to cartridge port + m_gromport = downcast(machine().device(GROMPORT_TAG)); + + // Link to PEB + m_peb = downcast(machine().device(PERIBOX_TAG)); + + // Configure RAM and AMIGO + m_sram = std::make_unique(SRAM_SIZE); + m_dram = std::make_unique(DRAM_SIZE); + + m_amigo->connect_sram(m_sram.get()); + + m_rom0 = machine().root_device().memregion(ROM0_REG)->base(); + m_rom1 = machine().root_device().memregion(ROM1_REG)->base(); + m_pascalrom = machine().root_device().memregion(PASCAL_REG)->base(); +} + +void mainboard8_device::device_reset() +{ + logerror("Resetting main board\n"); + m_last_ready = CLEAR_LINE; + m_speech_ready = true; + m_sound_ready = true; + m_pbox_ready = true; + m_pending_write = false; + m_prev_grom = 0; +} + +MACHINE_CONFIG_FRAGMENT( ti998_mainboard ) + MCFG_DEVICE_ADD(VAQUERRO_TAG, VAQUERRO, 0) + MCFG_DEVICE_ADD(MOFETTA_TAG, MOFETTA, 0) + MCFG_DEVICE_ADD(AMIGO_TAG, AMIGO, 0) + MCFG_DEVICE_ADD(OSO_TAG, OSO, 0) +MACHINE_CONFIG_END + +machine_config_constructor mainboard8_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( ti998_mainboard ); +} +const device_type MAINBOARD8 = &device_creator; + + +/*************************************************************************** + ===== VAQUERRO: Logical Address Space decoder ===== Logical address space (LAS) =========================== @@ -150,648 +874,975 @@ f850-f85f: P-Code library #1 GROM read/write f860-f86f: P-Code library #2 GROM read/write - Physical address space (PAS) - ============================ - The PAS is 24 bits wide and accessed via the custom mapper chip nicknamed - "Amigo". The mapper exchanges map definitions with SRAM (see LAS). That - means, a map can be prepared in SRAM, and for activating it, the mapper - is accessed on its port, telling it to load or save a map. - - 000000-00ffff: 64 KiB console DRAM - 010000-efffff: undefined - f00000-f03fff: P-Code ROM (not mentioned in [1]) - f04000-feffff: undefined - ff0000 : unmapped (code for mapper) - ff0001-ff3fff: undefined - ff4000-ff5fff: DSR ROM in Peripheral Box, Hexbus DSR (CRU 1700) or additional ROM (CRU 2700) - ff6000-ff9fff: Cartridge ROM space - ffa000-ffdfff: 16 KiB ROM1 - ffe000-ffe00f: Interrupt level sense - ffe010-ffffff: undefined - - - CRU map (I/O address space) - =========================== - 0000-003e: TMS9901 system interface (see ti99_8.c) - 1700-17fe: Hexbus - 2000-26fe: Future external devices - 2700-27fe: Additional ROM ("internal DSR") - 2702: System reset (when set to 1) - 2800-3ffe: Future external devices - 4000-fffe: Future external devices - - The TMS9995 offers the full 15-bit CRU address space. Devices designed for - the TI-99/4A should only be accessed in the area 1000-1ffe. They will (by - design) incompletely decode the CRU address and be mirrored in the higher areas. - - Michael Zapf, October 2010 - February 2012: Rewritten as class - - Informations taken from - [1] ARMADILLO PRODUCT SPECIFICATIONS - [2] TI-99/8 Graphics Programming Language interpreter ***************************************************************************/ -#include "998board.h" +vaquerro_device::vaquerro_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) +: device_t(mconfig, VAQUERRO, "Logical Address Space Decoder", tag, owner, clock, "ti998_vaquerro", __FILE__), + m_crus(ASSERT_LINE), + m_crugl(ASSERT_LINE), + m_ggrdy(ASSERT_LINE) +{ +} -#define TRACE_CRU 0 -#define TRACE_MEM 0 -#define TRACE_MAP 0 -#define TRACE_CONFIG 0 -#define TRACE_OSO 0 -#define TRACE_SPEECH 0 -#define TRACE_DETAIL 0 +SETADDRESS_DBIN_MEMBER( vaquerro_device::set_address ) +{ + // Do the decoding + // state = dbin, offset = address -mainboard8_device::mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : bus8z_device(mconfig, MAINBOARD8, "TI-99/8 Main board", tag, owner, clock, "ti998_mainboard", __FILE__), - m_ready(*this), m_dsr_selected(false), m_hexbus_selected(false), m_CRUS(false), m_PTGE(false), m_waitcount(0), m_sram(nullptr), m_dram(nullptr), m_rom0(nullptr), m_rom1(nullptr), m_pcode(nullptr), - m_oso(*this, OSO_TAG) - { } + bool reading = (state==ASSERT_LINE); + bool sgfap = false; + bool tsgfap = false; + bool p8gfap = false; + bool p3gfap = false; + bool vfap = false; + + m_a14 = ((offset & 2)!=0)? ASSERT_LINE : CLEAR_LINE; // Needed for clock_in + + m_dbin_level = (line_state)state; + + int offbase = (offset & 0xfff1); + + // =================== TI (compatibility) mode ====================== + if (m_crus == ASSERT_LINE) + { + if (TRACE_DETAIL) logerror("Compatibility mode\n"); + + // SPRD (Speech read) + m_sprd = ((offbase==0x9000) && reading); + + // SPWT (Speech write) + m_spwt = ((offbase==0x9400) && !reading); + + // Sound + m_sccs = ((offbase==0x8400)&& !reading); + + // ROM0 + m_sromcs = (((offset & 0xe000)==0x0000) && reading); + + // Video select + vfap = ((offbase==0x8800) && reading) || ((offbase==0x8c00) && !reading); + + // System GROM + sgfap = ((offbase==0x9800) && reading) || ((offbase==0x9c00) && !reading); + } + // ====================== Native mode ====================== + else + { + if (TRACE_DETAIL) logerror("Native mode\n"); + + // SPRD (Speech read) + m_sprd = ((offbase==0xf820) && reading); + + // SPWT (Speech write) + m_spwt = ((offbase==0xf820) && !reading); + + // Sound + m_sccs = ((offbase==0xf800) && !reading); + + // Video + vfap = (offbase==0xf810); + + // System GROM (read and write) + sgfap = (offbase==0xf830); + } + + // These lines are not decoded for compatibility or native mode, only + // the line CRUGL determines whether they become visible. + tsgfap = (offbase==0xf840) && m_crugl; + p8gfap = (offbase==0xf850) && m_crugl; + p3gfap = (offbase==0xf860) && m_crugl; + + // The LASREQ line says whether Vaquerro does the job, or whether it is Mofetta's turn. + m_grom_or_video = sgfap || tsgfap || p8gfap || p3gfap || vfap ; + + m_lasreq = (m_sprd || m_spwt || m_sccs || m_sromcs || m_grom_or_video); + + if (TRACE_DETAIL) logerror("sgfap=%d tsgfap=%d p8gfap=%d p3gfap=%d vfap=%d\n", sgfap, tsgfap, p8gfap, p3gfap, vfap); + + // Pass the selection to the wait state generators + // and pick up the current select line states + m_sgmws.select_in(sgfap); + m_tsgws.select_in(tsgfap); + m_p8gws.select_in(p8gfap); + m_p3gws.select_in(p3gfap); + m_vidws.select_in(vfap); + + m_gromsel = m_sgmws.select_out() | m_tsgws.select_out() | m_p8gws.select_out() | m_p3gws.select_out(); + + m_vdprd = (reading && (m_vidws.select_out()!=0)); + m_vdpwt = (!reading && (m_vidws.select_out()!=0)); + + if (m_grom_or_video) + { + // We don't see the current selection now; only with next clock pulse. + m_mainboard->ggrdy_in(m_sry); + if (TRACE_READY) logerror("GGRDY = %d\n", m_sry); + } +} + +WRITE_LINE_MEMBER( vaquerro_device::crusgl_in ) +{ + m_crugl = (state==ASSERT_LINE); +} + +WRITE_LINE_MEMBER( vaquerro_device::crus_in ) +{ + m_crus = (line_state)state; +} + +WRITE_LINE_MEMBER( vaquerro_device::memen_in ) +{ + m_memen = (state==ASSERT_LINE); +} + +/* + Called by Mofetta +*/ +READ_LINE_MEMBER( vaquerro_device::lascsq_out ) +{ + return (m_lasreq && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +/* + Incoming ready lines from the GROM library +*/ +WRITE_LINE_MEMBER( vaquerro_device::sgmry ) +{ + if (TRACE_READY) logerror("Incoming SGMRY = %d\n", state); + m_sgmws.ready_in((line_state)state); +} + +WRITE_LINE_MEMBER( vaquerro_device::tsgry ) +{ + if (TRACE_READY) logerror("Incoming TSGRY = %d\n", state); + m_tsgws.ready_in((line_state)state); +} + +WRITE_LINE_MEMBER( vaquerro_device::p8gry ) +{ + if (TRACE_READY) logerror("Incoming 8GRY = %d\n", state); + m_p8gws.ready_in((line_state)state); +} + +WRITE_LINE_MEMBER( vaquerro_device::p3gry ) +{ + if (TRACE_READY) logerror("Incoming P3GRY = %d\n", state); + m_p3gws.ready_in((line_state)state); +} + +/* + Outgoing READY +*/ +READ_LINE_MEMBER( vaquerro_device::ggrdy_out ) +{ + if (TRACE_READY) logerror("GGRDY out = %d\n", m_ggrdy); + return m_ggrdy; +} + +/* + Select lines +*/ + +// ========================= + +int vaquerro_device::gromcs_out() +{ + return m_gromsel; +} + +// ========================= + +READ_LINE_MEMBER( vaquerro_device::vdprd_out ) +{ + return (m_vdprd && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( vaquerro_device::vdpwt_out ) +{ + return (m_vdpwt && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( vaquerro_device::sprd_out ) +{ + return (m_sprd && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( vaquerro_device::spwt_out ) +{ + return (m_spwt && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( vaquerro_device::sromcs_out ) +{ + return (m_sromcs && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( vaquerro_device::sccs_out ) +{ + return (m_sccs && m_memen)? ASSERT_LINE : CLEAR_LINE; +} + +/* + Incoming clock signal. + + The Vaquerro has a Wait State generation logic circuit for the video + processor and all 4 GROM libraries. Each one has its separate generator. + The GROMs get a 16 cycle wait period after their access, while the video + processors gets an 8 cycle wait period. If during that period another + access occurs, the system READY line will be cleared, triggering wait + states in the CPU. +*/ +WRITE_LINE_MEMBER( vaquerro_device::clock_in ) +{ + line_state level = (line_state)state; + + // Propagate to the wait state generators (note that we need both clock levels) + m_sgmws.clock_in(level); + m_tsgws.clock_in(level); + m_p8gws.clock_in(level); + m_p3gws.clock_in(level); + m_vidws.clock_in(level); + + // Collect the selections + // Each one has its own indication, defined at init time + m_gromsel = m_sgmws.select_out() | m_tsgws.select_out() | m_p8gws.select_out() | m_p3gws.select_out(); + + bool reading = (m_dbin_level==ASSERT_LINE); + + m_vdprd = (reading && (m_vidws.select_out()!=0)); + m_vdpwt = (!reading && (m_vidws.select_out()!=0)); + + // Get the READY levels from the GROMs + if (level==CLEAR_LINE) + { + m_sry = m_sgmws.ready_out() || m_tsgws.ready_out() || m_p8gws.ready_out() || m_p3gws.ready_out() || m_vidws.ready_out(); + if (TRACE_WS) logerror("ready_out = (%d, %d, %d, %d, %d)\n", m_sgmws.ready_out(), m_tsgws.ready_out(), m_p8gws.ready_out(), m_p3gws.ready_out(),m_vidws.ready_out()); + } + + // If the output gate is closed, propagate ASSERT_LINE (pulled up) + m_ggrdy = (!m_grom_or_video || m_sry)? ASSERT_LINE : CLEAR_LINE; +} + + +void vaquerro_device::device_start() +{ + logerror("Starting\n"); + m_mainboard = downcast(owner()); + m_sgmws.init(SGMSEL); + m_tsgws.init(TSGSEL); + m_p8gws.init(P8GSEL); + m_p3gws.init(P3GSEL); + m_vidws.init(VIDSEL); +} + +void vaquerro_device::device_reset() +{ + m_ggrdy = ASSERT_LINE; + m_vdpwt = m_vdprd = CLEAR_LINE; + m_gromsel = 0; + m_sgmws.treset_in(ASSERT_LINE); + m_tsgws.treset_in(ASSERT_LINE); + m_p8gws.treset_in(ASSERT_LINE); + m_p3gws.treset_in(ASSERT_LINE); + m_vidws.treset_in(ASSERT_LINE); +} + +/* + Wait state generation logic inside Vaquerro + + Analysis of the logic diagram of the Vaquerro delivers the following + behavior (for the first GROM library; similar behavior applies for the + other libraries). Note that the CLKOUT line is inverted. + + 1. When the GROMs are unselected by address (SGFAP), the SRY line is Z + (System READY). The GROM ready line (SGMRY) has no effect. + 2. When SGFAP is asserted while the internal counter is off, the + READY line changes from Z to Low and the GROM select line (SGCS) is + asserted (both immediately, before the next tick edge). SGMRY has no effect. + The circuit state is constant during further clock ticks. + 3. After being selected, when SGMRY is asserted (GROM is ready), SRY + changes to High on the next trailing edge. This will allow the + CPU to complete the GROM access on the next cycle, + and the address bus will change, typically deselecting the GROMs. + Until this deselection, the circuit state remains constant + (SGCS asserted, READY=H). + 4. When the GROMs are deselected, SRY changes to Z, and SGCS is cleared + (immediately). A counter is started at 0 that is incremented on each clock + tick (leading edge). + 5. When SGFAP is asserted while the counter is less that 15, SRY changes + to Low immediately. SGCS remains cleared, so the GROMs are not selected. + While SGFAP stays cleared, the counter completes its way to 15, + then 0, and turns off. + 6. When the counter reaches 15, it returns to 0 on the next tick + (leading). On the following trailing edge, the GROM select line is + asserted, while the READY line remains Low. + 7. Continue at 3. +*/ +void waitstate_generator::select_in(bool addressed) +{ + m_addressed = addressed; +} + +int waitstate_generator::select_out() +{ + return (!m_counting && m_addressed)? m_selvalue : 0; +} + +/* + Should be low by default. +*/ +line_state waitstate_generator::ready_out() +{ + return (m_ready && !m_counting && m_generate)? ASSERT_LINE : CLEAR_LINE; +} + +bool waitstate_generator::is_counting() +{ + return m_counting; +} + +bool waitstate_generator::is_generating() +{ + return m_generate; +} + +bool waitstate_generator::is_ready() +{ + return m_ready; +} + +/* + READY in. This may only show an effect with the next trailing edge of CLKOUT. +*/ +void grom_waitstate_generator::ready_in(line_state ready) +{ + m_ready = (ready==ASSERT_LINE); +} + +void grom_waitstate_generator::clock_in(line_state clkout) +{ + if (clkout == ASSERT_LINE) + { + if (m_counting) m_counter++; + } + else + { + if (m_counting && m_counter==16) + { + m_counter = 0; + m_counting = false; + } + else + { + if (!m_addressed && m_generate) m_counting = true; + m_generate = ((m_addressed || m_counting) && (m_counter != 15)); + } + } +} + +void waitstate_generator::treset_in(line_state reset) +{ + if (reset==ASSERT_LINE) + { + m_counter = 0; + m_generate = m_counting = m_addressed = false; + } +} + +void video_waitstate_generator::clock_in(line_state clkout) +{ + if (clkout == ASSERT_LINE) + { + if (m_counting) m_counter++; + } + else + { + if (m_counting && m_counter==7) + { + m_counter = 0; + m_counting = false; + } + else + { + if (!m_addressed && m_generate) m_counting = true; + m_generate = ((m_addressed || m_counting) && (m_counter != 6)); + } + } +} + +const device_type VAQUERRO = &device_creator; /*************************************************************************** - CRU access + ===== MOFETTA: Physical Address Space decoder ===== + + Physical address space (PAS) + ============================ + The PAS is 24 bits wide and accessed via the custom mapper chip nicknamed + "Amigo". The mapper exchanges map definitions with SRAM (see LAS). That + means, a map can be prepared in SRAM, and for activating it, the mapper + is accessed on its port, telling it to load or save a map. + + 000000-00ffff: 64 KiB console DRAM + 010000-efffff: undefined + + f00000-f03fff: PASCAL support ROM (not mentioned in [1]) + + f04000-feffff: undefined + ff0000 : unmapped (code for mapper) + ff0001-ff3fff: undefined + ff4000-ff5fff: DSR ROM in Peripheral Box, Hexbus DSR (CRU 1700) or additional ROM (CRU 2700) + ff6000-ff9fff: Cartridge ROM space + ffa000-ffdfff: 16 KiB ROM1 + ffe000-ffe00f: Interrupt level sense + ffe010-ffffff: undefined + + ***************************************************************************/ -#define HEXBUS_CRU_BASE 0x1700 -#define MAPPER_CRU_BASE 0x2700 - -READ8Z_MEMBER(mainboard8_device::crureadz) +enum { - if (TRACE_CRU) logerror("%s: read CRU %04x ignored\n", tag(), offset); - // Nothing here. + UNDEF=0, + DRAM, + PASCAL, + INTERNAL +}; + +mofetta_device::mofetta_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MOFETTA, "Physical Address Space Decoder", tag, owner, clock, "ti998_mofetta", __FILE__), + m_gotfirstword(false) +{ +} + +SETADDRESS_DBIN_MEMBER( mofetta_device::set_address ) +{ + if (!m_gotfirstword) + { + // Store the first word and wait for clearing of MSAST + if (TRACE_MOFETTA) logerror("Got the upper word of the address: %04x\n", offset); + m_address_latch = offset; + } + else + { + // Second part - now decode the address + if (TRACE_MOFETTA) logerror("Got the lower word of the address: %04x\n", offset); + + bool acs, tcs, rcs, acsx; + bool reading = (state==ASSERT_LINE); + int offbase = (offset & 0xe000); + + // PASCAL ROM select (16K) + m_prcs = (m_prefix == 0xf0) && ((offset & 0xc000) == 0x0000); + + // Hexbus select + acs = (m_prefix == 0xff) && (offbase == 0x4000) && m_alcpg; + + // Internal DSR select (ff4000-ff5fff @ CRU>2700) + tcs = (m_prefix == 0xff) && (offbase == 0x4000) && m_txspg; + + // Hexbus select (ff4000-ff5fef @ CRU>1700), excluding OSO + acsx = acs && ((offset & 0x1ff0)!=0x1ff0); + + // Upper 16K of ROM1 + m_rom1am = !((offbase == 0xa000) || (offbase == 0xc000)); + + // ROM select + rcs = (m_prefix == 0xff) && reading && !m_rom1am; + + // ROM1 select (containing 16K ROM, 8K TTS, 8K ACS) + m_rom1cs = tcs || rcs || acsx; + + // Accessing OSO (ff5ff0 @ CRU>1700) + m_alccs = acs && ((offset & 0x1ff0)==0x1ff0); + + // Second half of ROM or ACS + m_rom1al = reading && (m_prefix == 0xff) && ((offbase == 0xc000) || acs); + + // Cartridge port (ff6000-ff9fff) + m_cmas = (m_prefix == 0xff) && ((offbase == 0x6000) || (offbase == 0x8000)); + + m_gotfirstword = false; + } } /* - CRU handling. We handle the internal device at CRU address 0x2700 via - this mapper component. + Mofetta delivers the GROMCLK. In the 99/4A, this clock is produced by the VDP. + Apart from that, Mofetta does not need the CLKOUT. */ -WRITE8_MEMBER(mainboard8_device::cruwrite) +WRITE_LINE_MEMBER( mofetta_device::clock_in ) { - if ((offset & 0xff00)==MAPPER_CRU_BASE) + if (state == CLEAR_LINE) // TODO: Correct edge? { - int bit = (offset & 0xff)>>1; - switch (bit) + m_gromclock_count++; + if (m_gromclock_count >=3) { - case 0: - // Turn on/off the internal DSR - m_dsr_selected = (data!=0); - if (TRACE_CRU) logerror("%s: DSR select = %d\n", tag(), data); - break; - case 1: - if (TRACE_CRU) logerror("%s: System reset by CRU request\n", tag()); - machine().schedule_soft_reset(); - break; + m_gromclk_up = !m_gromclk_up; + m_gromclock_count = 0; } - return; - } - - if ((offset & 0xff00)==HEXBUS_CRU_BASE) - { - int bit = (offset & 0xff)>>1; - switch (bit) - { - case 0: - // Turn on/off the Hexbus DSR - m_hexbus_selected = (data!=0); - if (TRACE_CRU) logerror("%s: Hexbus select = %d\n", tag(), data); - break; - default: - if (TRACE_CRU) logerror("%s: Set CRU>%04x (Hexbus) to %d\n", tag(), offset,data); - break; - } - return; - } - - if ((offset & 0xff00)>=0x0100) - { - if (TRACE_CRU) logerror("%s: Set CRU>%04x (unknown) to %d\n", tag(), offset,data); - return; } } -void mainboard8_device::CRUS_set(bool state) +READ_LINE_MEMBER( mofetta_device::alccs_out ) { - if (TRACE_CRU) logerror("%s: set CRUS=%d\n", tag(), state); - m_CRUS = state; + return (m_alccs && m_pmemen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::gromclk_out ) +{ + return m_gromclk_up? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::rom1cs_out ) +{ + return (m_rom1cs && m_pmemen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::rom1am_out ) +{ + return (m_rom1am && m_pmemen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::rom1al_out ) +{ + return (m_rom1al && m_pmemen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::prcs_out ) +{ + return (m_prcs && m_pmemen)? ASSERT_LINE : CLEAR_LINE; +} + +READ_LINE_MEMBER( mofetta_device::cmas_out ) +{ + return (m_cmas && m_pmemen)? ASSERT_LINE : CLEAR_LINE; } /* - Note that PTGEN is negative logic. We invert these semantics here. + Asserted when a PEB access occurs */ -void mainboard8_device::PTGE_set(bool state) +READ_LINE_MEMBER( mofetta_device::dbc_out ) { - if (TRACE_CRU) logerror("%s: set PTGEN=%d\n", tag(), state? 1:0); - m_PTGE = state; + return (m_lasreq || m_cmas || m_rom1cs || m_skdrcs || !m_pmemen)? CLEAR_LINE : ASSERT_LINE; } +WRITE8_MEMBER(mofetta_device::cruwrite) +{ + if ((offset & 0xff00)==0x2700) + { + if ((offset & 0x0002)!=0) + { + // SWRST (Software reset) + // Value seems to be irrelevant + if (TRACE_CRU) logerror("Doing a software reset by SBO 2702\n"); + m_mainboard->reset_console(ASSERT_LINE); + m_mainboard->reset_console(CLEAR_LINE); + } + else + { + m_txspg = (data!=0); // CRU>2700 + if (TRACE_CRU) logerror("Turning %s CRU>2700\n", m_txspg? "on" : "off"); + } + } + else + { + if ((offset & 0xff00)==0x1700) + { + m_alcpg = (data!=0); // CRU>1700 + if (TRACE_CRU) logerror("Turning %s CRU>1700\n", m_alcpg? "on" : "off"); + } + } +} + +/* + Setting or clearing the MSAST line. +*/ +WRITE_LINE_MEMBER( mofetta_device::msast_in ) +{ + if (state == ASSERT_LINE) + { + if (m_msast == CLEAR_LINE) // Leading edge + { + m_gotfirstword = true; // Process first word + // We now have the first part, containing the flags and the upper byte. + m_prefix = m_address_latch & 0xff; + } + } + // TODO: Evaluate the first three bits + m_msast = (line_state)state; +} + +WRITE_LINE_MEMBER( mofetta_device::pmemen_in ) +{ + m_pmemen = (state==ASSERT_LINE); +} + +WRITE_LINE_MEMBER( mofetta_device::lascs_in ) +{ + m_lasreq = (state==ASSERT_LINE); +} + +WRITE_LINE_MEMBER( mofetta_device::skdrcs_in ) +{ + m_skdrcs = (state==ASSERT_LINE); +} + +void mofetta_device::device_start() +{ + logerror("Starting\n"); + m_mainboard = downcast(owner()); +} + +void mofetta_device::device_reset() +{ + m_gotfirstword = false; + m_alcpg = false; + m_txspg = false; + m_prefix = 0; +} + + +const device_type MOFETTA = &device_creator; + /*************************************************************************** - Access by address map + + ============================== + Mapper (codename "Amigo") + ============================== + + Unfortunately, we do not have logic diagrams for Amigo, so we have to + guess how it is actually working. + + Initial setting of mapper (as defined in the power-up routine, TI-99/4A mode) + + 0 00ff0000 -> Unmapped; logical address 0000...0fff = ROM0 + 1 00ff0000 -> Unmapped; logical address 1000...1fff = ROM0 + 2 00000800 -> DRAM; 2000 = 000800, 2fff = 0017ff + 3 00001800 -> DRAM; 3000 = 001800, 3fff = 0027ff + 4 00ff4000 -> DSR space (internal / ioport) + 5 00ff5000 -> DSR space (internal / ioport) + 6 00ff6000 -> Cartridge space (6000..6fff) + 7 00ff7000 -> Cartridge space (7000..7fff) + 8 00ff0000 -> Unmapped; device ports (VDP) and SRAM + 9 00ff0000 -> Unmapped; device ports (Speech, GROM) + A 00002800 -> DRAM; a000 = 002800, afff = 0037ff + B 00003800 -> DRAM; b000 = 003800, bfff = 0047ff + C 00004800 -> DRAM; c000 = 004800, cfff = 0057ff + D 00005800 -> DRAM; d000 = 005800, dfff = 0067ff + E 00006800 -> DRAM; e000 = 006800, efff = 0077ff + F 00007800 -> DRAM; f000 = 007800, ffff = 0087ff + + Format of map table entry + + +--+---+---+---+---+---+---+---+ +-----------+ +----------+ +---------+ + | W| X | R | 0 | 0 | 0 | 0 | 0 | | Upper (8) | | High (8) | | Low (8) | + +--+---+---+---+---+---+---+---+ +-----------+ +----------+ +---------+ + + W: Write protection if set to 1 + X: Execute protection if set to 1 + R: Read protection if set to 1 + + When a protection violation occurs, the tms9901 INT1* pin is pulled low + (active). The pin remains low until the mapper status register is read. + + Address handling + ---------------- + Physical address is (Upper * 2^16) + (High * 2^8) + Low + + The mapper calculates the actual physical address by looking up the + table entry from the first four bits of the logical address and then + *adding* the remaining 12 bits of the logical address on the map value. + + The value 0xff0000 is used to indicate a non-mapped area. + + Mapper control register + ----------------------- + The mapper control register is used to initiate a map load/save operation. + + +---+---+---+---+---+---+---+---+ + | 0 | 0 | 0 | 0 | Map File | RW| + +---+---+---+---+---+---+---+---+ + + The map file is a number from 0-7 indicating the set of map values for the + operation, which means the location in SRAM where the next 64 values are + loaded from or stored into. + + RW = 1: load from SRAM into mapper + RW = 0: store from mapper into SRAM + + When read, the mapper register returns the violation flags: + +---+---+---+---+---+---+---+---+ + | W | X | R | 0 | 0 | 0 | 0 | 0 | + +---+---+---+---+---+---+---+---+ + ***************************************************************************/ -/* - This method is called via the address map. -*/ -READ8_MEMBER( mainboard8_device::readm ) +amigo_device::amigo_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) +: device_t(mconfig, AMIGO, "Address space mapper", tag, owner, clock, "ti998_amigo", __FILE__), + m_logical_space(true), + m_crus(ASSERT_LINE) { - UINT8 value = 0; - bool found; - if (TRACE_DETAIL) logerror("%s: read from %04x\n", tag(), offset); - found = access_logical_r(space, offset, &value, mem_mask); - m_waitcount = 2; +} - if (!found) +enum +{ + IDLE = 0, + CREATE_PADDR, + ADDR_MSW, + ADDR_LSW, + SRAMLOAD, + SRAMSAVE +}; + +/* + Incoming READY line (SRDY) +*/ +WRITE_LINE_MEMBER( amigo_device::srdy_in ) +{ + if (TRACE_READY) logerror("Incoming SRDY = %d\n", state); + m_srdy = (line_state)state; + + // If the access is going to logical space, pass through the READY line + if (m_logical_space) { - // In that case, the address decoder could not find a suitable device. - // This means the logical address is transformed by the mapper. - // NOTE: Use "+", not OR. The offset is not a prefix. - UINT32 pas_address = m_pas_offset[(offset & 0xf000)>>12] + (offset & 0xfff); - - // So now let's do the same as above with physical addresses - access_physical_r(space, pas_address, &value, mem_mask); - - // The PAS area requires one more wait state, as the address bus - // is multiplexed - m_waitcount = 3; + if (TRACE_CPURY) logerror("Setting CPURY = %d (SRDY)\n", m_ready_out); + m_ready_out = m_srdy; } +} - // Insert wait states and let CPU enter wait state - m_ready(CLEAR_LINE); +WRITE_LINE_MEMBER( amigo_device::memen_in ) +{ + m_memen = (state==ASSERT_LINE); +} +/* + Polled from the mainboard +*/ +READ_LINE_MEMBER( amigo_device::cpury_out ) +{ + return m_ready_out; +} + +/* + Polled from the mainboard +*/ +READ_LINE_MEMBER( amigo_device::sramcs_out ) +{ + return m_sram_accessed && m_memen? ASSERT_LINE : CLEAR_LINE; +} + +/* + SKDRCS line (maybe "Sixty-four Kilobyte DRam Chip Select"). We assume that + Amigo asserts the select line not before the whole address was written. + This is actually more than needed because we only have 64K DRAM (which + would only need a 16 bit address), and Amigo itself selects it. +*/ +READ_LINE_MEMBER( amigo_device::skdrcs_out ) +{ + return m_dram_accessed && (m_amstate == IDLE) && m_memen? ASSERT_LINE : CLEAR_LINE; +} + +/* + Incoming CRUS line. Needed to set the mapper config addresses. +*/ +WRITE_LINE_MEMBER( amigo_device::crus_in ) +{ + m_crus = (line_state)state; +} + +/* + Incoming LASCS line. +*/ +WRITE_LINE_MEMBER( amigo_device::lascs_in ) +{ + m_logical_space = (state==ASSERT_LINE); +} + +/* + The logical address bus has been set. The Amigo chip now has to map this + address to a physical address. There are three phases (3 clock ticks): + 1. Sample the logical address lines, determine the map register + (first four bits), create the physical address by adding the remaining + 12 bits and the map register contents + 2. Set the physical address bus with the first 16 bits of the physical + address. Assert the MSAST line. + 3. Set the physical address bus with the second 16 bits of the physical + address. Clear the MSAST line. Forward any incoming READY=0 to the CPU. +*/ +SETOFFSET_MEMBER( amigo_device::set_address ) +{ + // Check whether the mapper itself is accessed + int mapaddr = (m_crus==ASSERT_LINE)? 0x8810 : 0xf870; + m_mapper_accessed = ((offset & 0xfff1)==mapaddr); + + // or SRAM + int sramaddr = (m_crus==ASSERT_LINE)? 0x8000 : 0xf000; + m_sram_accessed = ((offset & 0xf800)==sramaddr); + + m_logical_space |= (m_mapper_accessed || m_sram_accessed); + + // Is the address not in the logical address space? + if (!m_logical_space) + { + if (TRACE_AMIGO) logerror("Amigo decoding; %04x is a physical address.\n", offset); + // Build the physical address + // The first three bits are the protection bits (Write, Execute, Read) + // Theoretically, the addition of the logical address could mess up those + // first three bits, but the physical address is only 24 bits wide, so we + // have a space of 5 zeros between the protection bits and the address. + // We should just clear those five bits after the addition. + + m_physical_address = ((offset & 0x0fff) + m_base_register[(offset >> 12) & 0x000f]) & 0x00ffffff; + + // TODO: Process flags + + // Is it DRAM? + m_dram_accessed = (m_physical_address & 0x00ff0000)==0; + + // This takes one clock pulse. + m_amstate = CREATE_PADDR; + + // Pull down READY + m_ready_out = CLEAR_LINE; + + if (TRACE_CPURY) logerror("Setting CPURY = %d (PAS)\n", m_ready_out); + } + else + { + // This was a logical space access. Pass through READY. + m_dram_accessed = false; + m_amstate = IDLE; + m_ready_out = m_srdy; + if (TRACE_CPURY) logerror("Setting CPURY = %d (LAS)\n", m_ready_out); + } +} + +/* + Read the mapper status bits +*/ +READ8_MEMBER( amigo_device::read ) +{ + // Read the protection status bits and reset them + UINT8 value = m_protflag; + m_protflag = 0; return value; } -WRITE8_MEMBER( mainboard8_device::writem ) -{ - bool found; - - // Look for components responding to the logical address - found = access_logical_w(space, offset, data, mem_mask); - m_waitcount = 2; - - if (!found) - { - // In that case, the address decoder could not find a suitable device. - // This means the logical address is transformed by the mapper. - // NOTE: Use "+", not OR. The offset is not a prefix. - UINT32 pas_address = m_pas_offset[(offset & 0xf000)>>12] + (offset & 0xfff); - - // So now let's do the same as above with physical addresses - access_physical_w(space, pas_address, data, mem_mask); - - // The PAS area requires one more wait state, as the address bus - // is multiplexed - m_waitcount = 3; - } - - // Insert wait states and let CPU enter wait state - m_ready(CLEAR_LINE); -} - -/*************************************************************************** - Indirect calls (mapper calls itself) -***************************************************************************/ /* - This method is called by the mapper itself for - f870 (NATIVE): mapper: ignore - 8810 (TI99EM): mapper: ignore - ff4000 (PHYSIC): DSR + Configure the mapper. This is the only reason to write to the AMIGO. */ -READ8Z_MEMBER( mainboard8_device::readz ) -{ - if ((offset & 0xffe000)==0xff4000) - { - if (m_dsr_selected) - { - // Starts at 0x4000 in the image - *value = m_rom1[0x4000 | (offset & 0x1fff)]; - if (TRACE_MEM) logerror("%s: (intDSR) %04x -> %02x\n", tag(), offset, *value); - } - else - { - if (m_hexbus_selected) - { - if ((offset & 0x1ff0)==0x1ff0) - { - *value = m_oso->read(space, (offset>>1) & 0x0003); - } - else - { - // Starts at 0x6000 in the image - *value = m_rom1[0x6000 | (offset & 0x1fff)]; - if (TRACE_MEM) logerror("%s: (HexDSR) %04x -> %02x\n", tag(), offset, *value); - } - } - } - } - else - { - if (((offset & 0xfff0)==0xf870 && m_CRUS==false)||(((offset & 0xfff0)==0x8810 && m_CRUS==true))) - { - if (TRACE_MEM) logerror("%s: read access to mapper ignored: %04x\n", tag(), offset); - } - } -} - -/* - This method is called by the mapper itself for - ff4000 (PHYSIC): DSR. ignore - -*/ -WRITE8_MEMBER( mainboard8_device::write ) -{ - if ((offset & 0xffe000)==0xff4000) - { - if (m_hexbus_selected) - { - if ((offset & 0x1ff0)==0x1ff0) - { - m_oso->write(space, (offset>>1) & 0x0003, data); - } - else - { - logerror("%s: Write access to Hexbus DSR address %06x ignored\n", tag(), offset); - } - } - else - { - if (m_dsr_selected) - { - logerror("%s: Write access to internal DSR address %06x ignored\n", tag(), offset); - } - else - { - logerror("%s: Write access to unmapped DSR space at address %06x ignored\n", tag(), offset); - } - } - } - else - { - if (((offset & 0xfff0)==0xf870 && m_CRUS==false)||(((offset & 0xfff0)==0x8810 && m_CRUS==true))) - { - mapwrite(offset, data); - } - } -} - -/* - Reconfigure mapper. Writing to this address copies the values in the - SRAM into the mapper and vice versa. - Format: - 0000 bbbl; bbb=bank, l=load - - TODO: Emulate properly, making use of HOLD -*/ -void mainboard8_device::mapwrite(int offset, UINT8 data) +WRITE8_MEMBER( amigo_device::write ) { + // Load or save map file if ((data & 0xf0)==0x00) { - int bankindx = (data & 0x0e)>>1; - if (data & 1) + // Need to HOLD the CPU + m_amstate = ((data & 1)==1)? SRAMLOAD : SRAMSAVE; + m_sram_address = (data & 0x0e) << 5; + m_hold_acknowledged = false; + m_basereg = 0; + m_mapvalue = 0; + m_mainboard->hold_cpu(ASSERT_LINE); + } + else logerror("Invalid value written to Amigo: %02x\n", data); +} + +WRITE_LINE_MEMBER( amigo_device::clock_in ) +{ + if (state==CLEAR_LINE) + { + switch (m_amstate) { - if (TRACE_MAP) logerror("%s: load mapper from SRAM, bank %d\n", tag(), bankindx); - // Load from SRAM - // In reality the CPU is put on HOLD during this transfer - for (int i=0; i < 16; i++) - { - int ptr = (bankindx << 6); - m_pas_offset[i] = (m_sram[(i<<2) + ptr] << 24) | (m_sram[(i<<2)+ ptr+1] << 16) - | (m_sram[(i<<2) + ptr+2] << 8) | (m_sram[(i<<2) + ptr+3]); - if (TRACE_MAP) logerror("%s: load %d=%08x\n", tag(), i, m_pas_offset[i]); - } + case IDLE: + break; + case CREATE_PADDR: + // Address has been created + m_amstate = ADDR_MSW; + break; + case ADDR_MSW: + // Transmit the first word (without the protection bits) + m_mainboard->set_paddress((m_physical_address >> 16) & 0x00ff); + m_amstate = ADDR_LSW; + break; + case ADDR_LSW: + m_mainboard->msast_in(ASSERT_LINE); // Pulse MSAST + m_mainboard->msast_in(CLEAR_LINE); + m_mainboard->set_paddress(m_physical_address & 0xffff); + m_amstate = IDLE; + m_ready_out = m_srdy; // Propagate incoming READY + break; + + case SRAMLOAD: + if (m_hold_acknowledged) mapper_load(); + break; + + case SRAMSAVE: + if (m_hold_acknowledged) mapper_save(); + break; + + default: + logerror("Invalid state in mapper: %d\n", m_amstate); + } + } +} + +void amigo_device::mapper_load() +{ + m_mapvalue = (m_mapvalue << 8) | m_sram[m_sram_address++]; + + if ((m_sram_address & 0x03)==0) + { + if (TRACE_MAP) logerror("Loaded basereg %02d = %08x\n", m_basereg, m_mapvalue); + m_base_register[m_basereg++] = m_mapvalue; + } + if (m_basereg == 16) + { + m_amstate = IDLE; + m_mainboard->hold_cpu(CLEAR_LINE); + } +} + +void amigo_device::mapper_save() +{ + if ((m_sram_address & 0x03)==0) + { + if (m_basereg == 16) + { + m_amstate = IDLE; + m_mainboard->hold_cpu(CLEAR_LINE); + return; } else { - if (TRACE_MAP) logerror("%s: store mapper to SRAM, bank %d\n", tag(), bankindx); - // Store in SRAM - for (int i=0; i < 16; i++) - { - int ptr = (bankindx << 6); - m_sram[(i<<2) + ptr] = (m_pas_offset[i] >> 24)& 0xff; - m_sram[(i<<2) + ptr +1] = (m_pas_offset[i] >> 16)& 0xff; - m_sram[(i<<2) + ptr +2] = (m_pas_offset[i] >> 8)& 0xff; - m_sram[(i<<2) + ptr +3] = (m_pas_offset[i])& 0xff; - if (TRACE_MAP) logerror("%s: save %d=%08x\n", tag(), i, m_pas_offset[i]); - } + m_mapvalue = m_base_register[m_basereg]; + if (TRACE_MAP) logerror("Saving basereg %02d = %08x\n", m_basereg, m_mapvalue); + m_basereg++; } } + + m_sram[m_sram_address++] = (m_mapvalue >> 24) & 0xff; + m_mapvalue = m_mapvalue << 8; } +WRITE_LINE_MEMBER( amigo_device::holda_in ) +{ + if (TRACE_MAP) logerror("HOLD acknowledged = %d\n", state); + m_hold_acknowledged = (state==ASSERT_LINE); +} + +void amigo_device::device_start() +{ + logerror("Starting\n"); + m_mainboard = downcast(owner()); +} + +void amigo_device::device_reset() +{ + m_logical_space = true; +} + +const device_type AMIGO = &device_creator; + /*************************************************************************** - Lookup methods. -***************************************************************************/ - -bool mainboard8_device::access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask ) -{ - bool found = false; - logically_addressed_device *ldev = m_logcomp.first(); - bus8z_device *bdev; - - if (TRACE_DETAIL) logerror("%s: offset=%04x; CRUS=%d, PTGEN=%d\n", tag(), offset, m_CRUS? 1:0, m_PTGE? 0:1); - while (ldev != nullptr) - { - if (TRACE_DETAIL) logerror("%s: checking node=%s\n", tag(), ldev->m_config->name); - // Check the mode - if (((ldev->m_config->mode == NATIVE) && (m_CRUS==false)) - || ((ldev->m_config->mode == TI99EM) && (m_CRUS==true)) - || ((ldev->m_config->mode == PATGEN) && (m_PTGE==true))) - { - if ((offset & ldev->m_config->address_mask)==ldev->m_config->select_pattern) - { - switch (ldev->m_kind) - { - case MAP8_SRAM: - *value = m_sram[offset & ~ldev->m_config->address_mask]; - if (TRACE_MEM) logerror("%s: (SRAM) %04x -> %02x\n", tag(), offset, *value); - break; - case MAP8_ROM0: - // Starts at 0000 - *value = m_rom0[offset & ~ldev->m_config->address_mask]; - if (TRACE_MEM) logerror("%s: (ROM0) %04x -> %02x\n", tag(), offset, *value); - break; - case MAP8_DEV: - // device - bdev = static_cast(ldev->m_device); - bdev->readz(space, offset, value, mem_mask); - if (TRACE_MEM) logerror("%s: (dev %s) %04x -> %02x\n", tag(), ldev->m_config->name, offset, *value); - break; - default: - if (TRACE_MEM) logerror("%s: Invalid kind for read access: %d\n", tag(), ldev->m_kind); - } - found = true; - if (ldev->m_config->stop==STOP) break; - } - } - ldev = ldev->m_next; - } - return found; -} - -bool mainboard8_device::access_logical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask ) -{ - bool found = false; - logically_addressed_device *ldev = m_logcomp.first(); - bus8z_device *bdev; - - while (ldev != nullptr) - { - // Check the mode - if (((ldev->m_config->mode == NATIVE) && (m_CRUS==false)) - || ((ldev->m_config->mode == TI99EM) && (m_CRUS==true)) - || ((ldev->m_config->mode == PATGEN) && (m_PTGE==true))) - { - if ((offset & ldev->m_config->address_mask)==(ldev->m_config->select_pattern | ldev->m_config->write_select)) - { - switch (ldev->m_kind) - { - case MAP8_SRAM: - m_sram[offset & ~ldev->m_config->address_mask] = data; - if (TRACE_MEM) logerror("%s: (SRAM) %04x <- %02x\n", tag(), offset, data); - break; - case MAP8_ROM0: - if (TRACE_MEM) logerror("%s: (ROM0) %04x <- %02x (ignored)\n", tag(), offset, data); - break; - case MAP8_DEV: - // device - bdev = static_cast(ldev->m_device); - bdev->write(space, offset, data, mem_mask); - if (TRACE_MEM) logerror("%s: (dev %s) %04x <- %02x\n", tag(), ldev->m_config->name, offset, data); - break; - default: - if (TRACE_MEM) logerror("%s: Invalid kind for write access: %d\n", tag(), ldev->m_kind); - } - found = true; - if (ldev->m_config->stop==STOP) break; - } - } - ldev = ldev->m_next; - } - return found; -} - - -void mainboard8_device::access_physical_r( address_space& space, offs_t pas_address, UINT8 *value, UINT8 mem_mask ) -{ - physically_addressed_device *pdev = m_physcomp.first(); - bus8z_device *bdev; - - while (pdev != nullptr) - { - if ((pas_address & pdev->m_config->address_mask)==pdev->m_config->select_pattern) - { - switch (pdev->m_kind) - { - case MAP8_DRAM: - *value = m_dram[pas_address & ~pdev->m_config->address_mask]; - if (TRACE_MEM) logerror("%s: (DRAM) %06x -> %02x\n", tag(), pas_address, *value); - break; - case MAP8_ROM1A0: - // Starts at 0000 in the image, 8K - *value = m_rom1[pas_address & 0x1fff]; - if (TRACE_MEM) logerror("%s: (ROM) %06x -> %02x\n", tag(), pas_address, *value); - break; - case MAP8_ROM1C0: - // Starts at 2000 in the image, 8K - *value = m_rom1[0x2000 | (pas_address & 0x1fff)]; - if (TRACE_MEM) logerror("%s: (ROM) %06x -> %02x\n", tag(), pas_address, *value); - break; - case MAP8_PCODE: - *value = m_pcode[pas_address & 0x3fff]; - if (TRACE_MEM) logerror("%s: (PCODE) %06x -> %02x\n", tag(), pas_address, *value); - break; - case MAP8_INTS: - // Interrupt sense - logerror("%s: ILSENSE not implemented.\n", tag()); - break; - case MAP8_DEV: - // devices - bdev = static_cast(pdev->m_device); - bdev->readz(space, pas_address, value, mem_mask); - if (TRACE_MEM) logerror("%s: (dev %s) %06x -> %02x\n", tag(), pdev->m_config->name, pas_address, *value); - break; - default: - logerror("%s: Invalid kind for physical read access: %d\n", tag(), pdev->m_kind); - } - if (pdev->m_config->stop==STOP) break; - } - pdev = pdev->m_next; - } -} - -void mainboard8_device::access_physical_w( address_space& space, offs_t pas_address, UINT8 data, UINT8 mem_mask ) -{ - physically_addressed_device *pdev = m_physcomp.first(); - bus8z_device *bdev; - - while (pdev != nullptr) - { - if ((pas_address & pdev->m_config->address_mask)==(pdev->m_config->select_pattern | pdev->m_config->write_select)) - { - switch (pdev->m_kind) - { - case MAP8_DRAM: - m_dram[pas_address & ~pdev->m_config->address_mask] = data; - if (TRACE_MEM) logerror("%s: (DRAM) %06x <- %02x\n", tag(), pas_address, data); - break; - case MAP8_ROM1A0: - case MAP8_ROM1C0: - if (TRACE_MEM) logerror("%s: (ROM1) %06x <- %02x (ignored)\n", tag(), pas_address, data); - break; - case MAP8_PCODE: - if (TRACE_MEM) logerror("%s: (PCODE) %06x <- %02x (ignored)\n", tag(), pas_address, data); - break; - case MAP8_INTS: - // Interrupt sense - logerror("%s: write to ilsense ignored\n", tag()); - break; - case MAP8_DEV: - // devices - bdev = static_cast(pdev->m_device); - if (TRACE_MEM) logerror("%s: (dev %s) %06x <- %02x\n", tag(), pdev->m_config->name, pas_address, data); - bdev->write(space, pas_address, data, mem_mask); - break; - default: - logerror("%s: Invalid kind for physical write access: %d\n", tag(), pdev->m_kind); - } - if (pdev->m_config->stop==STOP) break; - } - pdev = pdev->m_next; - } -} - -/* - The mapper is connected to the clock line in order to operate - the wait state counter. -*/ -void mainboard8_device::clock_in(int clock) -{ - if (clock==ASSERT_LINE && m_waitcount!=0) - { - m_waitcount--; - if (m_waitcount==0) m_ready(ASSERT_LINE); - } -} - - -/*************************************************************************** - DEVICE LIFECYCLE FUNCTIONS -***************************************************************************/ -/* - We need to do all of the configuration in device_start since we don't have all - required links earlier. - - Note that device_reset is too late; the initial context switch occurs earlier. -*/ -void mainboard8_device::device_start() -{ - logerror("%s: Starting mapper\n", tag()); - - // String values of the pseudo constants, used in the configuration. - const char *const pseudodev[7] = { SRAMNAME, ROM0NAME, ROM1A0NAME, ROM1C0NAME, DRAMNAME, PCODENAME, INTSNAME }; - - const mapper8_config *conf = reinterpret_cast(static_config()); - - const mapper8_list_entry *entry = conf->devlist; - m_ready.resolve_safe(); - - m_sram = machine().root_device().memregion(SRAM_TAG)->base(); - m_dram = machine().root_device().memregion(DRAM_TAG)->base(); - m_rom0 = machine().root_device().memregion(ROM0_TAG)->base(); - m_rom1 = machine().root_device().memregion(ROM1_TAG)->base(); - m_pcode = machine().root_device().memregion(PCODEROM_TAG)->base(); - - // Clear the lists - m_logcomp.reset(); - m_physcomp.reset(); - - // Now building the list of active devices at this mapper. - // Coyping partly from datamux.c. - if ( entry != nullptr ) - { - bool done = false; - for (int i=0; !done; i++) - { - if (entry[i].name == nullptr) - { - done = true; - } - else - { - device_t *dev = nullptr; - mapper8_device_kind kind = MAP8_UNDEF; - - for (int j=1; (j < 8) && (kind == MAP8_UNDEF); j++) - { - // Pseudo devices are enumerated as 1 ... 6 (see MAP8_SRAM etc.) - if (strcmp(entry[i].name, pseudodev[j-1])==0) kind = (mapper8_device_kind)j; - } - if (kind==MAP8_UNDEF) - { - // This entry points to a "real" device, not to a special constant - kind = MAP8_DEV; - dev = machine().device(entry[i].name); - } - if (kind != MAP8_DEV || dev != nullptr) - { - if (entry[i].mode != PHYSIC) - { - auto ad = new logically_addressed_device(kind, (device_t*)dev, entry[i]); - m_logcomp.append(*ad); - if (TRACE_CONFIG) logerror("%s: Device %s mounted into logical address space.\n", tag(), entry[i].name); - } - else - { - auto ad = new physically_addressed_device(kind, (device_t*)dev, entry[i]); - m_physcomp.append(*ad); - if (TRACE_CONFIG) logerror("%s: Device %s mounted into physical address space.\n", tag(), entry[i].name); - } - } - else - { - if (TRACE_CONFIG) logerror("%s: Device %s not found.\n", tag(), entry[i].name); - } - } - } - } - if (TRACE_CONFIG) logerror("%s: Mapper logical device count = %d\n", tag(), m_logcomp.count()); - if (TRACE_CONFIG) logerror("%s: Mapper physical device count = %d\n", tag(), m_physcomp.count()); - - m_dsr_selected = false; - m_CRUS = true; - m_PTGE = false; - - // Clean mapper - for (auto & elem : m_pas_offset) elem = 0; -} - -void mainboard8_device::device_reset() -{ - m_dsr_selected = false; - m_CRUS = true; - m_PTGE = false; - m_waitcount = 0; - m_hexbus_selected = false; - - // Clean mapper - for (auto & elem : m_pas_offset) elem = 0; - - m_ready(ASSERT_LINE); -} - -MACHINE_CONFIG_FRAGMENT( ti998_mainboard ) - MCFG_DEVICE_ADD(OSO_TAG, OSO, 0) -MACHINE_CONFIG_END - -machine_config_constructor mainboard8_device::device_mconfig_additions() const -{ - return MACHINE_CONFIG_NAME( ti998_mainboard ); -} - -const device_type MAINBOARD8 = &device_creator; - -/*************************************************************************** - - Custom chips of the TI-99/8 ===== OSO: Hexbus interface ===== @@ -858,12 +1909,12 @@ enum SHSK = 0x01 }; -ti998_oso_device::ti998_oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: device_t(mconfig, OSO, "OSO Hexbus interface", tag, owner, clock, "ti998_oso", __FILE__), m_data(0), m_status(0), m_control(0), m_xmit(0) +oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) +: device_t(mconfig, OSO, "Hexbus interface", tag, owner, clock, "oso", __FILE__), m_data(0), m_status(0), m_control(0), m_xmit(0) { } -READ8_MEMBER( ti998_oso_device::read ) +READ8_MEMBER( oso_device::read ) { int value = 0; offset &= 0x03; @@ -871,36 +1922,36 @@ READ8_MEMBER( ti998_oso_device::read ) { case 0: // read 5FF8: read data register - if (TRACE_OSO) logerror("%s: Read data register = %02x\n", tag(), value); + if (TRACE_OSO) logerror("Read data register = %02x\n", value); value = m_data; break; case 1: // read 5FFA: read status register value = m_status; - if (TRACE_OSO) logerror("%s: Read status %02x\n", tag(), value); + if (TRACE_OSO) logerror("Read status %02x\n", value); break; case 2: // read 5FFC: read control register value = m_control; - if (TRACE_OSO) logerror("%s: Read control register = %02x\n", tag(), value); + if (TRACE_OSO) logerror("Read control register = %02x\n", value); break; case 3: // read 5FFE: read transmit register value = m_xmit; - if (TRACE_OSO) logerror("%s: Read transmit register = %02x\n", tag(), value); + if (TRACE_OSO) logerror("Read transmit register = %02x\n", value); break; } return value; } -WRITE8_MEMBER( ti998_oso_device::write ) +WRITE8_MEMBER( oso_device::write ) { offset &= 0x03; switch (offset) { case 0: // write 5FF8: write transmit register - if (TRACE_OSO) logerror("%s: Write transmit register %02x\n", tag(), data); + if (TRACE_OSO) logerror("Write transmit register %02x\n", data); m_xmit = data; // We set the status register directly in order to prevent lock-ups // until we have a complete Hexbus implementation @@ -908,169 +1959,20 @@ WRITE8_MEMBER( ti998_oso_device::write ) break; case 1: // write 5FFA: write control register - if (TRACE_OSO) logerror("%s: Write control register %02x\n", tag(), data); + if (TRACE_OSO) logerror("Write control register %02x\n", data); m_control = data; break; default: // write 5FFC, 5FFE: undefined - if (TRACE_OSO) logerror("%s: Invalid write on %04x: %02x\n", tag(), (offset<<1) | 0x5ff0, data); + if (TRACE_OSO) logerror("Invalid write on %04x: %02x\n", (offset<<1) | 0x5ff0, data); break; } } -void ti998_oso_device::device_start() +void oso_device::device_start() { + logerror("Starting\n"); m_status = m_xmit = m_control = m_data = 0; } -const device_type OSO = &device_creator; - - -// ======================================================================== - -/**************************************************************************** - - TI-99/8 Speech synthesizer subsystem - - The TI-99/8 contains a speech synthesizer inside the console, so we cannot - reuse the spchsyn implementation of the P-Box speech synthesizer. - Accordingly, this is not a ti_expansion_card_device. - - For comments on real timing see ti99/spchsyn.c - - Note that before the REAL_TIMING can be used we must first establish - the set_address logic in 998board. - -*****************************************************************************/ - -#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */ -#define SPEECHSYN_TAG "speechsyn" -#define REAL_TIMING 0 - -ti998_spsyn_device::ti998_spsyn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: bus8z_device(mconfig, SPEECH8, "TI-99/8 Onboard Speech synthesizer", tag, owner, clock, "ti998_speech", __FILE__), m_vsp(nullptr), - m_ready(*this) -{ -} - -/* - Memory read -*/ -#if REAL_TIMING -// ====== This is the version with real timing ======= -READ8Z_MEMBER( ti998_spsyn_device::readz ) -{ - m_vsp->wsq_w(TRUE); - m_vsp->rsq_w(FALSE); - *value = m_vsp->read(offset) & 0xff; - if (TRACE_SPEECH) logerror("%s: read value = %02x\n", tag(), *value); -} - -/* - Memory write -*/ -WRITE8_MEMBER( ti998_spsyn_device::write ) -{ - m_vsp->rsq_w(m_vsp, TRUE); - m_vsp->wsq_w(m_vsp, FALSE); - if (TRACE_SPEECH) logerror("%s: write value = %02x\n", tag(), data); - m_vsp->write(offset, data); -} - -#else -// ====== This is the version without real timing ======= - -READ8Z_MEMBER( ti998_spsyn_device::readz ) -{ - machine().device("maincpu")->execute().adjust_icount(-(18+3)); /* this is just a minimum, it can be more */ - *value = m_vsp->status_r(space, offset, 0xff) & 0xff; - if (TRACE_SPEECH) logerror("%s: read value = %02x\n", tag(), *value); -} - -/* - Memory write -*/ -WRITE8_MEMBER( ti998_spsyn_device::write ) -{ - machine().device("maincpu")->execute().adjust_icount(-(54+3)); /* this is just an approx. minimum, it can be much more */ - - /* RN: the stupid design of the tms5220 core means that ready is cleared */ - /* when there are 15 bytes in FIFO. It should be 16. Of course, if */ - /* it were the case, we would need to store the value on the bus, */ - /* which would be more complex. */ - if (!m_vsp->readyq_r()) - { - attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready()); - int cycles_to_ready = machine().device("maincpu")->attotime_to_cycles(time_to_ready); - if (TRACE_SPEECH && TRACE_DETAIL) logerror("%s: time to ready: %f -> %d\n", tag(), time_to_ready.as_double(), (int) cycles_to_ready); - - machine().device("maincpu")->execute().adjust_icount(-cycles_to_ready); - machine().scheduler().timer_set(attotime::zero, FUNC_NULL); - } - if (TRACE_SPEECH) logerror("%s: write value = %02x\n", tag(), data); - m_vsp->data_w(space, offset, data); -} -#endif - -/**************************************************************************/ - -WRITE_LINE_MEMBER( ti998_spsyn_device::speech8_ready ) -{ - // The TMS5200 implementation uses TRUE/FALSE, not ASSERT/CLEAR semantics - m_ready((state==0)? ASSERT_LINE : CLEAR_LINE); - if (TRACE_SPEECH) logerror("%s: READY = %d\n", tag(), (state==0)); - -#if REAL_TIMING - // Need to do that here (see explanations in spchsyn.c) - if (state==0) - { - m_vsp->rsq_w(TRUE); - m_vsp->wsq_w(TRUE); - } -#endif -} - -void ti998_spsyn_device::device_start() -{ - m_ready.resolve_safe(); - m_vsp = subdevice(SPEECHSYN_TAG); - speechrom_device* mem = subdevice("vsm"); - mem->set_reverse_bit_order(true); -} - -void ti998_spsyn_device::device_reset() -{ - if (TRACE_SPEECH) logerror("%s: reset\n", tag()); -} - -// Unlike the TI-99/4A, the 99/8 uses the CD2501ECD -// The CD2501ECD is a tms5200/cd2501e with the rate control from the tms5220c added in. -// (it's probably actually a tms5220c die with the cd2501e/tms5200 lpc rom masked onto it) -MACHINE_CONFIG_FRAGMENT( ti998_speech ) - MCFG_DEVICE_ADD("vsm", SPEECHROM, 0) - - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD(SPEECHSYN_TAG, CD2501ECD, 640000L) - MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(ti998_spsyn_device, speech8_ready)) - MCFG_TMS52XX_SPEECHROM("vsm") - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) -MACHINE_CONFIG_END - -/* Verified on a real machine: TI-99/8 uses the same speech rom contents - as the TI speech synthesizer. */ -ROM_START( ti998_speech ) - ROM_REGION(0x8000, "vsm", 0) - ROM_LOAD("cd2325a.vsm", 0x0000, 0x4000, CRC(1f58b571) SHA1(0ef4f178716b575a1c0c970c56af8a8d97561ffe)) - ROM_LOAD("cd2326a.vsm", 0x4000, 0x4000, CRC(65d00401) SHA1(a367242c2c96cebf0e2bf21862f3f6734b2b3020)) -ROM_END - -machine_config_constructor ti998_spsyn_device::device_mconfig_additions() const -{ - return MACHINE_CONFIG_NAME( ti998_speech ); -} - -const rom_entry *ti998_spsyn_device::device_rom_region() const -{ - return ROM_NAME( ti998_speech ); -} -const device_type SPEECH8 = &device_creator; +const device_type OSO = &device_creator; diff --git a/src/devices/bus/ti99x/998board.h b/src/devices/bus/ti99x/998board.h index 9231d9be647..0a1d1523db7 100644 --- a/src/devices/bus/ti99x/998board.h +++ b/src/devices/bus/ti99x/998board.h @@ -18,113 +18,368 @@ #include "emu.h" #include "ti99defs.h" +#include "machine/tmc0430.h" +#include "video/tms9928a.h" +#include "sound/sn76496.h" #include "sound/tms5220.h" +#include "gromport.h" +#include "bus/ti99_peb/peribox.h" extern const device_type MAINBOARD8; -extern const device_type OSO; -extern const device_type SPEECH8; +#define VAQUERRO_TAG "vaquerro" +#define MOFETTA_TAG "mofetta" +#define AMIGO_TAG "amigo" #define OSO_TAG "oso" -#define SPEECHSYN_TAG "speechsyn" - -#define NATIVE 0 -#define TI99EM 1 -#define PATGEN 2 -#define PHYSIC 3 -#define CONT 0 -#define STOP 1 - -#define SRAMNAME "SRAM" -#define ROM0NAME "ROM0" -#define ROM1A0NAME "ROM1A" -#define ROM1C0NAME "ROM1C" -#define INTSNAME "INTS" -#define DRAMNAME "DRAM" -#define PCODENAME "PCODE" #define SRAM_SIZE 2048 #define DRAM_SIZE 65536 -// We use these constants in the read/write functions. -enum mapper8_device_kind +class mainboard8_device; +extern const device_type VAQUERRO; +extern const device_type MOFETTA; +extern const device_type AMIGO; +extern const device_type OSO; + + +enum { - MAP8_UNDEF = 0, - MAP8_SRAM, - MAP8_ROM0, - MAP8_ROM1A0, - MAP8_ROM1C0, - MAP8_DRAM, - MAP8_PCODE, - MAP8_INTS, - MAP8_DEV // device by name -}; - -struct mapper8_list_entry -{ - const char* name; // Name of the device (used for looking up the device) - int mode; // Mode of the system which applies to this entry - int stop; // Mapper shall stop searching for a matching device when this entry applies - UINT32 select_pattern; // State of the address line bits when addressing this device - UINT32 address_mask; // Bits of the address bus used to address this device - UINT32 write_select; // Additional bits set when doing write accesses to this device -}; - -#define MAPPER8_CONFIG(name) \ - const mapper8_config(name) = - -#define MCFG_MAINBOARD8_READY_CALLBACK(_write) \ - devcb = &mainboard8_device::set_ready_wr_callback(*device, DEVCB_##_write); - -struct mapper8_config -{ - const mapper8_list_entry *devlist; + SGMSEL = 1, + TSGSEL = 2, + P8GSEL = 4, + P3GSEL = 8, + VIDSEL = 16 }; /* - Device list of the mapper. + Wait state generator (part of Vaquerro) */ -class logically_addressed_device +class waitstate_generator { - friend class simple_list; - friend class mainboard8_device; - public: - logically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry) - : m_next(nullptr), m_kind(kind), m_device(busdevice), m_config(&entry) { }; + waitstate_generator() : + m_counting(false), + m_generate(false), + m_counter(0), + m_addressed(true), + m_ready(true) { }; + void select_in(bool addressed); + virtual void ready_in(line_state ready) =0; + virtual void clock_in(line_state clkout) =0; + void treset_in(line_state reset); -private: - logically_addressed_device *m_next; // needed for simple_list - mapper8_device_kind m_kind; // named device or predefined - device_t *m_device; // the actual device - const mapper8_list_entry *m_config; + int select_out(); + void init(int select_value) { m_selvalue = select_value; } + + line_state ready_out(); + + bool is_counting(); + bool is_generating(); + bool is_ready(); + +protected: + // Two flipflops + bool m_counting; + bool m_generate; + // Counter + int m_counter; + + // Select value (indicates selected line) + int m_selvalue; + + // Line state flags + bool m_addressed; + bool m_ready; +}; + +class grom_waitstate_generator : public waitstate_generator +{ +public: + void ready_in(line_state ready) override; + void clock_in(line_state clkout) override; +}; + +class video_waitstate_generator : public waitstate_generator +{ +public: + void ready_in(line_state ready) override { }; + void clock_in(line_state clkout) override; }; /* - Device list of the mapper. + Custom chip: Vaquerro */ -class physically_addressed_device +class vaquerro_device : public device_t { - friend class simple_list; - friend class mainboard8_device; - public: - physically_addressed_device(mapper8_device_kind kind, device_t *busdevice, const mapper8_list_entry &entry) - : m_next(nullptr), m_kind(kind), m_device(busdevice), m_config(&entry) { }; + vaquerro_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + void device_start() override; + void device_reset() override; + + line_state ready(); + void treset(); + + DECLARE_READ8_MEMBER( read ); + DECLARE_SETADDRESS_DBIN_MEMBER( set_address ); + + DECLARE_READ_LINE_MEMBER( sprd_out ); + DECLARE_READ_LINE_MEMBER( spwt_out ); + DECLARE_READ_LINE_MEMBER( sccs_out ); + DECLARE_READ_LINE_MEMBER( sromcs_out ); + + // Collective select line query + int gromcs_out(); + + DECLARE_READ_LINE_MEMBER( vdprd_out ); + DECLARE_READ_LINE_MEMBER( vdpwt_out ); + DECLARE_READ_LINE_MEMBER( lascsq_out ); + DECLARE_READ_LINE_MEMBER( ggrdy_out ); + DECLARE_WRITE_LINE_MEMBER( hold_cpu ); + + DECLARE_WRITE_LINE_MEMBER( crus_in ); + DECLARE_WRITE_LINE_MEMBER( crusgl_in ); + DECLARE_WRITE_LINE_MEMBER( clock_in ); + DECLARE_WRITE_LINE_MEMBER( memen_in ); + + DECLARE_WRITE_LINE_MEMBER( sgmry ); + DECLARE_WRITE_LINE_MEMBER( tsgry ); + DECLARE_WRITE_LINE_MEMBER( p8gry ); + DECLARE_WRITE_LINE_MEMBER( p3gry ); private: - physically_addressed_device *m_next; // needed for simple_list - mapper8_device_kind m_kind; // named device or predefined - device_t *m_device; // the actual device - const mapper8_list_entry *m_config; + // Memory cycle state + bool m_memen; + + // Waiting for video + bool m_video_wait; + + // State of the CRUS line + line_state m_crus; + + // Are the GROM libraries turned on? + bool m_crugl; + + // Do we have a logical address space match? + bool m_lasreq = false; + + // Keep the decoding result (opens the SRY gate) + bool m_grom_or_video = false; + + // Select lines + bool m_spwt; + bool m_sccs; + bool m_sromcs; + bool m_sprd; + bool m_vdprd; + bool m_vdpwt; + + // Collective GROM select state + int m_gromsel; + + // Outgoing READY + line_state m_ggrdy; + + // Outgoing READY latch (common flipflop driving SRY) + bool m_sry; + + // Holds the A14 address line state. We need this for the clock_in method. + line_state m_a14; + + // Keeps the recent DBIN level + line_state m_dbin_level; + + // Wait state logic components + grom_waitstate_generator m_sgmws, m_tsgws, m_p8gws, m_p3gws; + video_waitstate_generator m_vidws; + + // Pointer to mainboard + mainboard8_device* m_mainboard; +}; + +/* + Custom chip: Mofetta +*/ +class mofetta_device : public device_t +{ +public: + mofetta_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + void device_start() override; + void device_reset() override; + + DECLARE_WRITE8_MEMBER( cruwrite ); + DECLARE_SETADDRESS_DBIN_MEMBER( set_address ); + + DECLARE_WRITE_LINE_MEMBER( clock_in ); + DECLARE_WRITE_LINE_MEMBER( msast_in ); + DECLARE_WRITE_LINE_MEMBER( lascs_in ); + DECLARE_WRITE_LINE_MEMBER( pmemen_in ); + DECLARE_WRITE_LINE_MEMBER( skdrcs_in ); + + DECLARE_READ8_MEMBER( rom1cs_out ); + DECLARE_READ_LINE_MEMBER( gromclk_out ); + + DECLARE_READ_LINE_MEMBER( alccs_out ); + DECLARE_READ_LINE_MEMBER( prcs_out ); + DECLARE_READ_LINE_MEMBER( cmas_out ); + DECLARE_READ_LINE_MEMBER( dbc_out ); + + DECLARE_READ_LINE_MEMBER( rom1cs_out ); + DECLARE_READ_LINE_MEMBER( rom1am_out ); + DECLARE_READ_LINE_MEMBER( rom1al_out ); + +private: + // Memory cycle state + bool m_pmemen; + + // Logical access + bool m_lasreq; + + // DRAM access + bool m_skdrcs; + + // Holds the decoding result; essentially names the selected line + bool m_gromclk_up; + + // Have we got the upper word of the address? + bool m_gotfirstword; + + // Address latch + int m_address_latch; + + // Most significant byte of the 24-bit address + int m_prefix; + + // CRU select of the 1700 device + bool m_alcpg; + + // CRU select of the 2700 device + bool m_txspg; + + // ROM1 select lines + bool m_rom1cs; + bool m_rom1am; + bool m_rom1al; + + // OSO select + bool m_alccs; + + // Pascal ROM select line + bool m_prcs; + + // Cartridge port select line + bool m_cmas; + + // GROM clock count (as frequency divider) + int m_gromclock_count; + + // Remember last msast state for edge detection + line_state m_msast; + + // Pointer to mainboard + mainboard8_device* m_mainboard; +}; + +/* + Custom chip: Amigo +*/ +class amigo_device : public device_t +{ +public: + amigo_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + void device_start() override; + void device_reset() override; + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + DECLARE_SETOFFSET_MEMBER( set_address ); + + DECLARE_WRITE_LINE_MEMBER( srdy_in ); + DECLARE_WRITE_LINE_MEMBER( clock_in ); + DECLARE_WRITE_LINE_MEMBER( crus_in ); + DECLARE_WRITE_LINE_MEMBER( lascs_in ); + DECLARE_WRITE_LINE_MEMBER( memen_in ); + + DECLARE_WRITE_LINE_MEMBER( holda_in ); + + DECLARE_READ_LINE_MEMBER( cpury_out ); + DECLARE_READ_LINE_MEMBER( sramcs_out ); + DECLARE_READ_LINE_MEMBER( skdrcs_out ); + + void connect_sram(UINT8* sram) { m_sram = sram; } + bool mapper_accessed() { return m_mapper_accessed; } + +private: + // Memory cycle state + bool m_memen; + + // DMA methods for loading/saving maps + void mapper_load(); + void mapper_save(); + + // Address mapper registers. Each offset is selected by the first 4 bits + // of the logical address. + UINT32 m_base_register[16]; + + // Indicates a logical space access + bool m_logical_space; + + // Physical address + UINT32 m_physical_address; + + // Pointer to SRAM where AMIGO needs to upload/download its map values + UINT8* m_sram; + + // Pointer to mainboard + mainboard8_device* m_mainboard; + + // Keep the system ready state + line_state m_srdy; + + // Outgoing READY level + line_state m_ready_out; + + // Keep the CRUS setting + line_state m_crus; + + // State of the address creation + int m_amstate; + + // Protection flags + int m_protflag; + + // Accessing SRAM + bool m_sram_accessed; + + // Accessing DRAM + bool m_dram_accessed; + + // Accessing the mapper + bool m_mapper_accessed; + + // Doing a DMA access + bool m_sram_dma; + + // HOLDA flag + bool m_hold_acknowledged; + + // Address in SRAM during DMA + UINT32 m_sram_address; + + // Number of the currently loaded/save base register + int m_basereg; + + // Latched value for mapper DMA transfer + UINT32 m_mapvalue; }; /* Custom chip: OSO */ -class ti998_oso_device : public device_t +class oso_device : public device_t { public: - ti998_oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + oso_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); void device_start() override; @@ -136,73 +391,60 @@ private: UINT8 m_xmit; }; -/* - Speech support -*/ -#define MCFG_SPEECH8_READY_CALLBACK(_write) \ - devcb = &ti998_spsyn_device::set_ready_wr_callback(*device, DEVCB_##_write); - -class ti998_spsyn_device : public bus8z_device -{ -public: - ti998_spsyn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - template static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast(device).m_ready.set_callback(object); } - - DECLARE_READ8Z_MEMBER(readz) override; - DECLARE_WRITE8_MEMBER(write) override; - - DECLARE_READ8Z_MEMBER(crureadz) { }; - DECLARE_WRITE8_MEMBER(cruwrite) { }; - - DECLARE_WRITE_LINE_MEMBER( speech8_ready ); - -protected: - virtual void device_start() override; - virtual void device_reset(void) override; - virtual const rom_entry *device_rom_region() const override; - virtual machine_config_constructor device_mconfig_additions() const override; - -private: - tms5220_device *m_vsp; -// UINT8 *m_speechrom; // pointer to speech ROM data -// int m_load_pointer; // which 4-bit nibble will be affected by load address -// int m_rombits_count; // current bit position in ROM -// UINT32 m_sprom_address; // 18 bit pointer in ROM -// UINT32 m_sprom_length; // length of data pointed by speechrom_data, from 0 to 2^18 - - // Ready line to the CPU - devcb_write_line m_ready; -}; - -#define MCFG_TISPEECH8_ADD(_tag, _conf) \ - MCFG_DEVICE_ADD(_tag, TI99_SPEECH8, 0) \ - MCFG_DEVICE_CONFIG(_conf) - - -/* - Main class -*/ -class mainboard8_device : public bus8z_device +class mainboard8_device : public device_t { public: mainboard8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - template static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast(device).m_ready.set_callback(object); } + // Memory space + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + DECLARE_SETOFFSET_MEMBER( setoffset ); - DECLARE_READ8_MEMBER( readm); // used from address map - DECLARE_WRITE8_MEMBER( writem ); // used from address map + // I/O space + DECLARE_READ8Z_MEMBER( crureadz ); + DECLARE_WRITE8_MEMBER( cruwrite ); - DECLARE_READ8Z_MEMBER( readz ) override; - DECLARE_WRITE8_MEMBER( write ) override; + // Control lines + DECLARE_WRITE_LINE_MEMBER( clock_in ); + DECLARE_WRITE_LINE_MEMBER( dbin_in ); + DECLARE_WRITE_LINE_MEMBER( msast_in ); + DECLARE_WRITE_LINE_MEMBER( crus_in ); + DECLARE_WRITE_LINE_MEMBER( ptgen_in ); + DECLARE_WRITE_LINE_MEMBER( reset_console ); + DECLARE_WRITE_LINE_MEMBER( hold_cpu ); + DECLARE_WRITE_LINE_MEMBER( ggrdy_in ); - DECLARE_READ8Z_MEMBER(crureadz); - DECLARE_WRITE8_MEMBER(cruwrite); + DECLARE_WRITE_LINE_MEMBER( holda_line ); - void CRUS_set(bool state); - void PTGE_set(bool state); + template static devcb_base &set_ready_wr_callback(device_t &device, _Object object) + { + return downcast(device).m_ready.set_callback(object); + } - void clock_in(int state); + template static devcb_base &set_reset_wr_callback(device_t &device, _Object object) + { + return downcast(device).m_console_reset.set_callback(object); + } + + template static devcb_base &set_hold_wr_callback(device_t &device, _Object object) + { + return downcast(device).m_hold_line.set_callback(object); + } + + void set_paddress(int address); + + // Ready lines from GROMs + DECLARE_WRITE_LINE_MEMBER( system_grom_ready ); + DECLARE_WRITE_LINE_MEMBER( ptts_grom_ready ); + DECLARE_WRITE_LINE_MEMBER( p8_grom_ready ); + DECLARE_WRITE_LINE_MEMBER( p3_grom_ready ); + DECLARE_WRITE_LINE_MEMBER( sound_ready ); + DECLARE_WRITE_LINE_MEMBER( speech_ready ); + DECLARE_WRITE_LINE_MEMBER( pbox_ready ); + + // Emulation + // void set_gromport(gromport_device* dev) { m_gromport = dev; } protected: void device_start(void) override; @@ -210,65 +452,115 @@ protected: machine_config_constructor device_mconfig_additions() const override; private: - bool access_logical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask ); - bool access_logical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask ); - void access_physical_r(address_space& space, offs_t offset, UINT8 *value, UINT8 mem_mask ); - void access_physical_w(address_space& space, offs_t offset, UINT8 data, UINT8 mem_mask ); - void mapwrite(int offset, UINT8 data); + // Propagates the end of the memory cycle + void cycle_end(); + + // Original logical address. + int m_logical_address; + + // Mapped physical address. + int m_physical_address; + + // Hold the address space value so that we can use it in other methods. + address_space* m_space; + + // Indicates that a byte is waiting on the data bus (see m_latched_data) + bool m_pending_write; + + // Hold the value of the data bus. In a real machine, the data bus continues + // to show that value, but in this emulation we have a push mechanism. + UINT8 m_latched_data; + + // Hold the level of the GROMCLK line + int m_gromclk; + + // Selecting GROM libraries + void select_groms(); + + // Previous select state + int m_prev_grom; + + // Ready states + bool m_speech_ready; + bool m_sound_ready; + bool m_pbox_ready; + + // Holds the A14 address line state. We need this for the clock_in method. + bool m_A14_set; + + // 99/4A compatibility mode. Name is taken from the spec. If asserted, 99/4A compatibility is active. + line_state m_crus; + + // P-Code mode, negative logic. Name is taken from the spec. If asserted, P-Code libraries are available. + // May be read as "Pascal and Text-to-speech GROM libraries ENable" + line_state m_ptgen; + + // Keeps the recent DBIN level + line_state m_dbin_level; // Ready line to the CPU devcb_write_line m_ready; - // All devices that are attached to the 16-bit address bus. - simple_list m_logcomp; + // Reset line to the main system + devcb_write_line m_console_reset; - // All devices that are attached to the 24-bit mapped address bus. - simple_list m_physcomp; - - // Select bit for the internal DSR. - bool m_dsr_selected; - - // Select bit for the Hexbus DSR. - bool m_hexbus_selected; - - // 99/4A compatibility mode. Name is taken from the spec. If 1, 99/4A compatibility is active. - bool m_CRUS; - - // P-Code mode. Name is taken from the spec. If 0, P-Code libraries are available. - // May be read as "Pascal and Text-to-speech GROM libraries Enable (Negative)" - // Note: this is negative logic. GROMs are present only for PTGEN=0 - // We use PTGE as the inverse signal. - bool m_PTGE; - - // Counter for the wait states. - int m_waitcount; - - // Address mapper registers. Each offset is selected by the first 4 bits - // of the logical address. - UINT32 m_pas_offset[16]; - - // SRAM area of the system. Directly connected to the address decoder. - UINT8 *m_sram; - - // DRAM area of the system. Connected to the mapped address bus. - UINT8 *m_dram; - - // ROM area of the system. Directly connected to the logical address decoder. - UINT8 *m_rom0; - - // ROM area of the system. Directly connected to the physical address decoder. - UINT8 *m_rom1; - - // P-Code ROM area of the system. Directly connected to the physical address decoder. - UINT8 *m_pcode; + // Hold line to the main system + devcb_write_line m_hold_line; // Custom chips - required_device m_oso; + required_device m_vaquerro; + required_device m_mofetta; + required_device m_amigo; + required_device m_oso; + + // Debugging + line_state m_last_ready; + + // Video processor + tms9118_device* m_video; + + // Sound generator + sn76496_base_device* m_sound; + + // Speech processor + cd2501ecd_device* m_speech; + + // System GROM library + tmc0430_device* m_sgrom[3]; + + // Text-to-speech GROM library + tmc0430_device* m_tsgrom[8]; + + // Pascal 8 GROM library + tmc0430_device* m_p8grom[8]; + + // Pascal 3 GROM library + tmc0430_device* m_p3grom[3]; + + // Gromport (cartridge port) + gromport_device* m_gromport; + + // Peripheral box + peribox_device* m_peb; + + // Memory + std::unique_ptr m_sram; + std::unique_ptr m_dram; + + // ROM area of the system. + UINT8* m_rom0; + UINT8* m_rom1; + UINT8* m_pascalrom; }; +#define MCFG_MAINBOARD8_READY_CALLBACK(_write) \ + devcb = &mainboard8_device::set_ready_wr_callback(*device, DEVCB_##_write); + +#define MCFG_MAINBOARD8_RESET_CALLBACK(_write) \ + devcb = &mainboard8_device::set_reset_wr_callback(*device, DEVCB_##_write); + +#define MCFG_MAINBOARD8_HOLD_CALLBACK(_write) \ + devcb = &mainboard8_device::set_hold_wr_callback(*device, DEVCB_##_write); -#define MCFG_MAINBOARD8_ADD(_tag, _devices) \ - MCFG_DEVICE_ADD(_tag, MAINBOARD8, 0) \ - MCFG_DEVICE_CONFIG( _devices ) #endif diff --git a/src/devices/bus/ti99x/datamux.cpp b/src/devices/bus/ti99x/datamux.cpp index 1b8ec8de02f..da971c4ceec 100644 --- a/src/devices/bus/ti99x/datamux.cpp +++ b/src/devices/bus/ti99x/datamux.cpp @@ -75,9 +75,20 @@ Constructor */ ti99_datamux_device::ti99_datamux_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: device_t(mconfig, DATAMUX, "Databus multiplexer", tag, owner, clock, "ti99_datamux", __FILE__), m_spacep(nullptr), - m_ready(*this), m_muxready(), m_sysready(), m_addr_buf(0), m_read_mode(false), m_latch(0), m_waitcount(0), m_ram16b(nullptr), m_use32k(false), m_base32k(0), m_cpu(nullptr) -{ } + : device_t(mconfig, DATAMUX, "Databus multiplexer", tag, owner, clock, "ti99_datamux", __FILE__), + m_spacep(nullptr), + m_ready(*this), + m_addr_buf(0), + m_dbin(CLEAR_LINE), + m_muxready(CLEAR_LINE), + m_sysready(CLEAR_LINE), + m_latch(0), + m_waitcount(0), + m_ram16b(nullptr), + m_use32k(false), + m_base32k(0), + m_console_groms_present(false) + { } #define TRACE_READY 0 #define TRACE_ACCESS 0 @@ -89,140 +100,236 @@ ti99_datamux_device::ti99_datamux_device(const machine_config &mconfig, const ch DEVICE ACCESSOR FUNCTIONS ***************************************************************************/ -void ti99_datamux_device::read_all(address_space& space, UINT16 addr, UINT8 *target) +void ti99_datamux_device::read_all(address_space& space, UINT16 addr, UINT8 *value) { - attached_device *dev = m_devices.first(); + // Valid access + bool validaccess = ((addr & 0x0400)==0); - // Reading the odd address first (addr+1) - while (dev != nullptr) + if (validaccess) { - if (dev->m_config->write_select != 0xffff) // write-only + // GROM access + if ((addr & 0xf801)==0x9800) { - if ((addr & dev->m_config->address_mask)==dev->m_config->select) + if (m_console_groms_present) { - // Cast to the bus8z_device (see ti99defs.h) - bus8z_device *devz = static_cast(dev->m_device); - devz->readz(space, addr, target); + for (int i=0; i < 3; i++) + { + m_grom[i]->readz(space, addr, value); + } } - // hope we don't have two devices answering... - // consider something like a logical OR and maybe some artificial smoke + // GROMport (GROMs) + m_gromport->readz(space, addr, value); } - dev = dev->m_next; + + // Video + if ((addr & 0xf801)==0x8800) m_video->readz(space, addr, value); } + + // GROMport (ROMs) + if ((addr & 0xe000)==0x6000) m_gromport->readz(space, addr, value); + + // PEB gets all accesses + m_peb->readz(space, addr, value); + m_peb->memen_in(CLEAR_LINE); } void ti99_datamux_device::write_all(address_space& space, UINT16 addr, UINT8 value) { - attached_device *dev = m_devices.first(); - while (dev != nullptr) + // GROM access + if ((addr & 0xf801)==0x9800) { - if ((addr & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select)) + if (m_console_groms_present) { - bus8z_device *devz = static_cast(dev->m_device); - devz->write(space, addr, value); + for (int i=0; i < 3; i++) + m_grom[i]->write(space, addr, value); } - dev = dev->m_next; + // GROMport + m_gromport->write(space, addr, value); } + + // Other devices + if ((addr & 0xe000)==0x6000) m_gromport->write(space, addr, value); + if ((addr & 0xfc01)==0x8400) m_sound->write(space, addr, value); + if ((addr & 0xf801)==0x8800) m_video->write(space, addr, value); + + // PEB gets all accesses + m_peb->write(space, addr, value); + m_peb->memen_in(CLEAR_LINE); } void ti99_datamux_device::setaddress_all(address_space& space, UINT16 addr) { - attached_device *dev = m_devices.first(); - while (dev != nullptr) + line_state a14 = ((addr & 2)!=0)? ASSERT_LINE : CLEAR_LINE; + + // Valid access = not(DBIN and A5) + bool validaccess = (m_dbin==CLEAR_LINE || (addr & 0x0400)==0); + + // GROM access + bool isgrom = ((addr & 0xf801)==0x9800) && validaccess; + + // Cartridge ROM + bool iscartrom = ((addr & 0xe000)==0x6000); + + // Always deliver to GROM so that the select line may be cleared + int lines = (m_dbin==ASSERT_LINE)? 1 : 0; + if (a14==ASSERT_LINE) lines |= 2; + line_state select = isgrom? ASSERT_LINE : CLEAR_LINE; + + if (m_console_groms_present) + for (int i=0; i < 3; i++) + m_grom[i]->set_lines(space, lines, select); + + // GROMport (GROMs) + m_gromport->set_gromlines(space, lines, select); + + if (validaccess) { - if ((addr & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select)) - { - bus8z_device *devz = static_cast(dev->m_device); - devz->setaddress_dbin(space, addr, m_read_mode? ASSERT_LINE : CLEAR_LINE); - } - dev = dev->m_next; + // Other devices + if ((addr & 0xfc01)==0x8400) m_sound->setaddress_dbin(space, addr, m_dbin); + if ((addr & 0xf801)==0x8800) m_video->setaddress_dbin(space, addr, m_dbin); } + + // GROMport (ROMs) + m_gromport->romgq_line(iscartrom? ASSERT_LINE : CLEAR_LINE); + + // PEB gets all accesses + m_peb->memen_in(ASSERT_LINE); + m_peb->setaddress_dbin(space, addr, m_dbin); } /* - Special debugger access; these routines have no influence on the wait - state generation. + Special debugger access. The access is similar to the normal access, + but it bypasses the wait state circuitry. Also, access ports of memory- + mapped devices are excluded because their state would be changed + unpredictably by the debugger access. */ UINT16 ti99_datamux_device::debugger_read(address_space& space, UINT16 addr) { - UINT16 base32k = 0; - UINT8 lval, hval; - UINT16 addrb = addr << 1; - if (m_use32k) - { - if ((addrb & 0xe000)==0x2000) base32k = 0x1000; - if (((addrb & 0xe000)==0xa000) || ((addrb & 0xc000)==0xc000)) base32k = 0x4000; - } - if (base32k != 0) - { - return m_ram16b[addr - base32k]; - } + UINT16 value = 0; + + if ((addrb & 0xe000)==0x0000) value = m_consolerom[(addrb & 0x1fff)>>1]; else { - lval = hval = 0; - read_all(space, addrb+1, &lval); - read_all(space, addrb, &hval); - return ((hval << 8)&0xff00) | (lval & 0xff); + if ((addrb & 0xfc00)==0x8000) value = m_padram[(addrb & 0x00ff)>>1]; + else + { + int base32k = 0; + if (m_use32k) + { + if ((addrb & 0xe000)==0x2000) base32k = 0x2000; + if (((addrb & 0xe000)==0xa000) || ((addrb & 0xc000)==0xc000)) base32k = 0x8000; + } + + if (base32k != 0) value = m_ram16b[(addrb-base32k)>>1]; + else + { + UINT8 lval = 0; + UINT8 hval = 0; + + if ((addr & 0xe000)==0x6000) + { + m_gromport->readz(space, addrb+1, &lval); + m_gromport->readz(space, addrb, &hval); + } + m_peb->memen_in(ASSERT_LINE); + m_peb->readz(space, addrb+1, &lval); + m_peb->readz(space, addrb, &hval); + m_peb->memen_in(CLEAR_LINE); + value = ((hval << 8)&0xff00) | (lval & 0xff); + } + } } + return value; } void ti99_datamux_device::debugger_write(address_space& space, UINT16 addr, UINT16 data) { - UINT16 base32k = 0; - UINT16 addrb = addr << 1; - if (m_use32k) - { - if ((addrb & 0xe000)==0x2000) base32k = 0x1000; - if (((addrb & 0xe000)==0xa000) || ((addrb & 0xc000)==0xc000)) base32k = 0x4000; - } - if (base32k != 0) - { - m_ram16b[addr - base32k] = data; - } + + if ((addrb & 0xe000)==0x0000) return; + + if ((addrb & 0xfc00)==0x8000) m_padram[(addrb & 0x00ff)>>1] = data; else { - write_all(space, addrb+1, data & 0xff); - write_all(space, addrb, (data >> 8) & 0xff); + int base32k = 0; + if (m_use32k) + { + if ((addrb & 0xe000)==0x2000) base32k = 0x2000; + if (((addrb & 0xe000)==0xa000) || ((addrb & 0xc000)==0xc000)) base32k = 0x8000; + } + + if (base32k != 0) m_ram16b[(addrb-base32k)>>1] = data; + else + { + if ((addr & 0xe000)==0x6000) + { + m_gromport->write(space, addr+1, data & 0xff); + m_gromport->write(space, addr, (data>>8) & 0xff); + } + + m_peb->memen_in(ASSERT_LINE); + m_peb->write(space, addr+1, data & 0xff); + m_peb->write(space, addr, (data>>8) & 0xff); + m_peb->memen_in(CLEAR_LINE); + } } } /* Read access. We are using two loops because the delay between both accesses must not occur within the loop. So we have one access on the bus, - a delay, and then the second access (each one with possibly many attached - devices) + a delay, and then the second access. + + mem_mask is always ffff on TMS processors (cannot control bus width) */ READ16_MEMBER( ti99_datamux_device::read ) { + UINT16 value = 0; + // Care for debugger if (space.debugger_access()) { return debugger_read(space, offset); } - // Looks ugly, but this is close to the real thing. If the 16bit - // memory expansion is installed in the console, and the access hits its - // space, just respond to the memory access and don't bother the - // datamux in any way. In particular, do not make the datamux insert wait - // states. - - if (m_base32k != 0) + // Addresses below 0x2000 are ROM (no wait states) + if ((m_addr_buf & 0xe000)==0x0000) { - UINT16 reply = m_ram16b[offset-m_base32k]; - return reply & mem_mask; + value = m_consolerom[(m_addr_buf & 0x1fff)>>1]; } else { - // The byte from the odd address has already been read into the latch - // Reading the even address now (addr) - UINT8 hbyte = 0; - read_all(space, m_addr_buf, &hbyte); - if (TRACE_ACCESS) logerror("datamux: read even byte from address %04x -> %02x\n", m_addr_buf, hbyte); + // Addresses from 8300-83ff (mirrors at 8000, 8100, 8200) are console RAM (no wait states) + if ((m_addr_buf & 0xfc00)==0x8000) + { + value = m_padram[(m_addr_buf & 0x00ff)>>1]; + } + else + { + // Looks ugly, but this is close to the real thing. If the 16bit + // memory expansion is installed in the console, and the access hits its + // space, just respond to the memory access and don't bother the + // datamux in any way. In particular, do not make the datamux insert wait + // states. - return ((hbyte<<8) | m_latch) & mem_mask; + if (m_base32k != 0) + { + value = m_ram16b[(m_addr_buf-m_base32k)>>1]; + } + else + { + // The byte from the odd address has already been read into the latch + // Reading the even address now (addr) + UINT8 hbyte = 0; + read_all(space, m_addr_buf, &hbyte); + if (TRACE_ACCESS) logerror("Read even byte from address %04x -> %02x\n", m_addr_buf, hbyte); + + value = (hbyte<<8) | m_latch; + } + } } + return value; } /* @@ -230,21 +337,29 @@ READ16_MEMBER( ti99_datamux_device::read ) */ WRITE16_MEMBER( ti99_datamux_device::write ) { - // Addresses below 0x2000 are ROM and should be handled in the address map - // by the ROM entry, but as the write handler for ROM is not mapped, we end up - // here when there are invalid accesses, and this will mess up everything. - if (offset < 0x1000) return; - if (space.debugger_access()) { debugger_write(space, offset, data); return; } + // Addresses below 0x2000 are ROM + if ((m_addr_buf & 0xe000)==0x0000) + { + return; + } + + // Addresses from 8300-83ff (mirrors at 8000, 8100, 8200) are console RAM + if ((m_addr_buf & 0xfc00)==0x8000) + { + m_padram[(m_addr_buf & 0x00ff)>>1] = data; + return; + } + // Handle the internal 32K expansion if (m_base32k != 0) { - m_ram16b[offset-m_base32k] = data; + m_ram16b[(m_addr_buf-m_base32k)>>1] = data; } else { @@ -264,21 +379,34 @@ WRITE16_MEMBER( ti99_datamux_device::write ) */ SETOFFSET_MEMBER( ti99_datamux_device::setoffset ) { - if (TRACE_ADDRESS) logerror("datamux: set address %04x\n", offset << 1); + m_addr_buf = offset << 1; + m_waitcount = 0; + + if (TRACE_ADDRESS) logerror("set address %04x\n", m_addr_buf); + + if ((m_addr_buf & 0xe000) == 0x0000) + { + return; // console ROM + } + + if ((m_addr_buf & 0xfc00) == 0x8000) + { + return; // console RAM + } + // Initialize counter // 1 cycle for loading into the datamux // 2 subsequent wait states (LSB) // 2 subsequent wait states (MSB) // clock cycle 6 is the nominal follower of the last wait state m_waitcount = 5; - m_addr_buf = offset << 1; m_spacep = &space; m_base32k = 0; if (m_use32k) { - if ((m_addr_buf & 0xe000)==0x2000) m_base32k = 0x1000; - if (((m_addr_buf & 0xe000)==0xa000) || ((m_addr_buf & 0xc000)==0xc000)) m_base32k = 0x4000; + if ((m_addr_buf & 0xe000)==0x2000) m_base32k = 0x2000; + if (((m_addr_buf & 0xe000)==0xa000) || ((m_addr_buf & 0xc000)==0xc000)) m_base32k = 0x8000; } // Suspend the CPU if not using the 32K @@ -308,13 +436,13 @@ WRITE_LINE_MEMBER( ti99_datamux_device::clock_in ) if (TRACE_READY) logerror("datamux: stalled due to external READY=0\n"); return; } - if (m_read_mode) + + if (m_dbin==ASSERT_LINE) { // Reading if (state==ASSERT_LINE) { // raising edge - m_waitcount--; - if (m_waitcount==0) + if (--m_waitcount==0) { m_muxready = ASSERT_LINE; ready_join(); @@ -333,8 +461,7 @@ WRITE_LINE_MEMBER( ti99_datamux_device::clock_in ) { if (state==ASSERT_LINE) { // raising edge - m_waitcount--; - if (m_waitcount==0) + if (--m_waitcount==0) { m_muxready = ASSERT_LINE; ready_join(); @@ -365,21 +492,31 @@ void ti99_datamux_device::ready_join() WRITE_LINE_MEMBER( ti99_datamux_device::dbin_in ) { - m_read_mode = (state==ASSERT_LINE); - if (TRACE_ADDRESS) logerror("datamux: data bus in = %d\n", m_read_mode? 1:0 ); + m_dbin = (line_state)state; + if (TRACE_ADDRESS) logerror("data bus in = %d\n", (m_dbin==ASSERT_LINE)? 1:0 ); } WRITE_LINE_MEMBER( ti99_datamux_device::ready_line ) { if (TRACE_READY) { - if (state != m_sysready) logerror("datamux: READY line from PBox = %d\n", state); + if (state != m_sysready) logerror("READY line from PBox = %d\n", state); } m_sysready = (line_state)state; // Also propagate to CPU via driver ready_join(); } +WRITE_LINE_MEMBER( ti99_datamux_device::gromclk_in ) +{ + // Propagate to the GROMs + if (m_console_groms_present) + { + for (int i=0; i < 3; i++) m_grom[i]->gclock_in(state); + } + m_gromport->gclock_in(state); +} + /*************************************************************************** DEVICE LIFECYCLE FUNCTIONS ***************************************************************************/ @@ -398,15 +535,9 @@ void ti99_datamux_device::device_stop(void) void ti99_datamux_device::device_reset(void) { - const datamux_config *conf = reinterpret_cast(static_config()); - - const dmux_device_list_entry *list = conf->devlist; - - m_cpu = machine().device("maincpu"); - // m_space = &m_cpu->memory().space(AS_PROGRAM); - - m_devices.reset(); // clear the list + m_consolerom = (UINT16*)owner()->memregion(CONSOLEROM)->base(); m_use32k = (ioport("RAM")->read()==1); + m_console_groms_present = (ioport("GROMENA")->read()==1); // better use a region? if (m_ram16b==nullptr) @@ -414,51 +545,6 @@ void ti99_datamux_device::device_reset(void) m_ram16b = make_unique_clear(32768/2); } - // Now building the list of active devices at this databus multiplex. - // We allow for turning off devices according to configuration switch settings. - // In particular, the HSGPL card cannot function unless the console GROMs are - // removed. - if ( list != nullptr ) - { - bool done = false; - for (int i=0; !done; i++) - { - if (list[i].name == nullptr) - { - done = true; - } - else - { - UINT32 set; - bool active_device = true; - if (list[i].setting!=nullptr) - { - set = ioport(list[i].setting)->read(); - active_device = ((set & list[i].set)==list[i].set) && ((set & list[i].unset)==0); - } - if (active_device) - { - device_t *dev = machine().device(list[i].name); - if (dev != nullptr) - { - auto ad = new attached_device(dev, list[i]); - m_devices.append(*ad); - if (TRACE_SETUP) logerror("datamux: Device %s mounted at index %d.\n", list[i].name, i); - } - else - { - if (TRACE_SETUP) logerror("datamux: Device %s not found.\n", list[i].name); - } - } - else - { - if (TRACE_SETUP) logerror("datamux: Device %s not mounted due to configuration setting %s.\n", list[i].name, list[i].setting); - } - } - } - } - if (TRACE_SETUP) logerror("datamux: Device count = %d\n", m_devices.count()); - m_sysready = ASSERT_LINE; m_muxready = ASSERT_LINE; ready_join(); @@ -466,9 +552,22 @@ void ti99_datamux_device::device_reset(void) m_waitcount = 0; m_latch = 0; - m_read_mode = true; + m_dbin = CLEAR_LINE; } +void ti99_datamux_device::device_config_complete() +{ + m_video = downcast(owner()->subdevice(VIDEO_SYSTEM_TAG)); + m_sound = downcast(owner()->subdevice(TISOUND_TAG)); + m_gromport = downcast(owner()->subdevice(GROMPORT_TAG)); + m_peb = downcast(owner()->subdevice(PERIBOX_TAG)); + m_grom[0] = downcast(owner()->subdevice(GROM0_TAG)); + m_grom[1] = downcast(owner()->subdevice(GROM1_TAG)); + m_grom[2] = downcast(owner()->subdevice(GROM2_TAG)); + m_padram = make_unique_clear(256/2); +} + + INPUT_PORTS_START( datamux ) PORT_START( "RAM" ) /* config */ PORT_CONFNAME( 0x01, 0x00, "Console 32 KiB RAM upgrade (16 bit)" ) diff --git a/src/devices/bus/ti99x/datamux.h b/src/devices/bus/ti99x/datamux.h index 604dfb2e62f..eaad45b7238 100644 --- a/src/devices/bus/ti99x/datamux.h +++ b/src/devices/bus/ti99x/datamux.h @@ -15,53 +15,13 @@ #define __DMUX__ #include "ti99defs.h" +#include "videowrp.h" +#include "machine/tmc0430.h" +#include "gromport.h" +#include "bus/ti99_peb/peribox.h" extern const device_type DATAMUX; -/* - Device that is attached to this datamux. - The configuration setting is used for certain configurations - where devices may only be used if others are turned off. In particular, - if the HGSPL expansion card is used, the GROMs in the console must be - removed. -*/ -struct dmux_device_list_entry -{ - const char *name; // Name of the device (used for looking up the device) - UINT16 select; // State of the address line bits when addressing this device - UINT16 address_mask; // Bits of the address bus used to address this device - UINT16 write_select; // Bits set when doing write accesses to this device (ffff = write-only) - const char *setting; // configuration switch that may have an effect for the presence of this device - UINT8 set; // bits that must be set for this switch so that this device is present - UINT8 unset; // bits that must be reset for this switch so that this device is present -}; - -#define DMUX_CONFIG(name) \ - const datamux_config(name) = - -struct datamux_config -{ - const dmux_device_list_entry *devlist; -}; - -/* - Device list of this datamux. -*/ -class attached_device -{ - friend class simple_list; - friend class ti99_datamux_device; - -public: - attached_device(device_t *busdevice, const dmux_device_list_entry &entry) - : m_next(nullptr), m_device(busdevice), m_config(&entry) { }; - -private: - attached_device *m_next; - device_t *m_device; // the actual device - const dmux_device_list_entry *m_config; -}; - /* Main class */ @@ -77,6 +37,8 @@ public: DECLARE_WRITE_LINE_MEMBER( dbin_in ); DECLARE_WRITE_LINE_MEMBER( ready_line ); + DECLARE_WRITE_LINE_MEMBER( gromclk_in ); + template static devcb_base &static_set_ready_callback(device_t &device, _Object object) { return downcast(device).m_ready.set_callback(object); @@ -87,9 +49,22 @@ protected: void device_start() override; void device_stop() override; void device_reset() override; + void device_config_complete() override; ioport_constructor device_input_ports() const override; private: + // Link to the video processor + bus8z_device* m_video; + + // Link to the sound processor + ti_sound_sn94624_device* m_sound; + + // Link to the peripheral expansion box + peribox_device* m_peb; + + // Link to the cartridge port (aka GROM port) + gromport_device* m_gromport; + // Keeps the address space pointer address_space* m_spacep; @@ -112,21 +87,18 @@ private: // Ready line to the CPU devcb_write_line m_ready; + // Address latch (emu). In reality, the address bus remains constant. + UINT16 m_addr_buf; + + // DBIN line + line_state m_dbin; + // Own ready state. line_state m_muxready; // Ready state. Needed to control wait state generation via inbound READY line_state m_sysready; - /* Address latch (emu). In reality, the address bus remains constant. */ - UINT16 m_addr_buf; - - /* Stores the state of the DBIN line. */ - bool m_read_mode; - - /* All devices that are attached to the 8-bit bus. */ - simple_list m_devices; - /* Latch which stores the first (odd) byte */ UINT8 m_latch; @@ -136,22 +108,28 @@ private: /* Memory expansion (internal, 16 bit). */ std::unique_ptr m_ram16b; + // Console RAM + std::unique_ptr m_padram; + + // Console ROM + UINT16* m_consolerom; + + // Console GROMs + tmc0430_device* m_grom[3]; + /* Use the memory expansion? */ bool m_use32k; /* Memory base for piggy-back 32K expansion. If 0, expansion is not used. */ UINT16 m_base32k; - /* Reference to the CPU; avoid lookups. */ - device_t *m_cpu; + // Console GROMs are available (the HSGPL expects them to be removed) + bool m_console_groms_present; }; /******************************************************************************/ -#define MCFG_DMUX_ADD(_tag, _devices) \ - MCFG_DEVICE_ADD(_tag, DATAMUX, 0) \ - MCFG_DEVICE_CONFIG( _devices ) -#endif - #define MCFG_DMUX_READY_HANDLER( _intcallb ) \ devcb = &ti99_datamux_device::static_set_ready_callback( *device, DEVCB_##_intcallb ); + +#endif diff --git a/src/devices/bus/ti99x/genboard.cpp b/src/devices/bus/ti99x/genboard.cpp index 9d6aeef7e76..1abdd7c6762 100644 --- a/src/devices/bus/ti99x/genboard.cpp +++ b/src/devices/bus/ti99x/genboard.cpp @@ -535,6 +535,7 @@ READ8_MEMBER( geneve_mapper_device::readm ) // 1001 0000 0000 0000 // We need to add the address prefix bits m_peribox->readz(space, dec->offset, &value, 0xff); + m_peribox->memen_in(CLEAR_LINE); if (TRACE_READ) logerror("%s: Read speech -> %02x\n", tag(), value); break; @@ -594,6 +595,7 @@ READ8_MEMBER( geneve_mapper_device::readm ) // 0x000000-0x1fffff for the GenMod.(AME,AMD,AMC,AMB,AMA,A0 ...,A15) m_peribox->readz(space, dec->physaddr, &value, 0xff); + m_peribox->memen_in(CLEAR_LINE); if (TRACE_READ) logerror("%s: Read P-Box %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value); break; @@ -616,6 +618,7 @@ READ8_MEMBER( geneve_mapper_device::readm ) case MPGMBOX: // Route everything else to the P-Box m_peribox->readz(space, dec->physaddr, &value, 0xff); + m_peribox->memen_in(CLEAR_LINE); break; } return value; @@ -701,6 +704,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem ) // 1001 0100 0000 0000 // We need to add the address prefix bits m_peribox->write(space, dec->offset, data, 0xff); + m_peribox->memen_in(CLEAR_LINE); if (TRACE_WRITE) logerror("%s: Write speech <- %02x\n", tag(), data); break; @@ -756,6 +760,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem ) dec->physaddr = (dec->physaddr & 0x0007ffff); // 19 bit address if (TRACE_WRITE) logerror("%s: Write P-Box %04x (%06x) <- %02x\n", tag(), offset, dec->physaddr, data); m_peribox->write(space, dec->physaddr, data, 0xff); + m_peribox->memen_in(CLEAR_LINE); break; case MPGMDRAM: @@ -775,6 +780,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem ) case MPGMBOX: // Route everything else to the P-Box m_peribox->write(space, dec->physaddr, data, 0xff); + m_peribox->memen_in(CLEAR_LINE); break; } } @@ -875,6 +881,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read // We need to add the address prefix bits dec->function = MLTSPEECH; dec->offset = offset | ((m_genmod)? 0x170000 : 0x070000); + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->offset, read_mode); set_wait(1); return; @@ -954,6 +961,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read dec->function = MPGBOX; dec->physaddr = (dec->physaddr & 0x0007ffff); // 19 bit address (with AMA..AMC) + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->physaddr, read_mode); return; } @@ -986,6 +994,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read // Check: Are waitstates completely turned off for turbo mode, or // merely the waitstates for DRAM memory access and box access? + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->physaddr, read_mode); return; } @@ -1072,6 +1081,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read { dec->function = MLTSPEECH; dec->offset = dec->offset | ((m_genmod)? 0x170000 : 0x070000); + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->offset, read_mode); set_wait(1); return; @@ -1151,6 +1161,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read // only AMA, AMB, AMC are used; AMD and AME are not used dec->function = MPGBOX; dec->physaddr = (dec->physaddr & 0x0007ffff); // 19 bit address + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->physaddr, read_mode); set_wait(1); } @@ -1175,6 +1186,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read // Route everything else to the P-Box dec->function = MPGMBOX; dec->physaddr = (dec->physaddr & 0x001fffff); // 21 bit address for Genmod + m_peribox->memen_in(ASSERT_LINE); m_peribox->setaddress_dbin(space, dec->physaddr, read_mode); if (!m_turbo) set_wait(1); } @@ -1346,7 +1358,7 @@ WRITE_LINE_MEMBER( geneve_mapper_device::pfm_output_enable ) void geneve_mapper_device::device_start() { // Get pointers - m_peribox = machine().device(PERIBOX_TAG); + m_peribox = machine().device(PERIBOX_TAG); m_keyboard = machine().device(GKEYBOARD_TAG); m_video = machine().device(VIDEO_SYSTEM_TAG); m_sound = machine().device(TISOUND_TAG); diff --git a/src/devices/bus/ti99x/genboard.h b/src/devices/bus/ti99x/genboard.h index 2248c64f9fe..8f49cb6906e 100644 --- a/src/devices/bus/ti99x/genboard.h +++ b/src/devices/bus/ti99x/genboard.h @@ -19,6 +19,7 @@ #include "video/v9938.h" #include "cpu/tms9900/tms9995.h" #include "machine/at29x.h" +#include "bus/ti99_peb/peribox.h" extern const device_type GENEVE_MOUSE; extern const device_type GENEVE_KEYBOARD; @@ -207,7 +208,7 @@ private: geneve_keyboard_device* m_keyboard; bus8z_device* m_video; - bus8z_device* m_peribox; + peribox_device* m_peribox; bus8z_device* m_sound; UINT8* m_eprom; UINT8* m_sram; diff --git a/src/devices/bus/ti99x/grom.cpp b/src/devices/bus/ti99x/grom.cpp deleted file mode 100644 index 1ecb0168d80..00000000000 --- a/src/devices/bus/ti99x/grom.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Michael Zapf -/*************************************************************************** - - GROM emulation (aka TMC0430) - - +----+--+----+ - AD7 |1 G 16| Vss - AD6 |2 R 15| GR - AD5 |3 O 14| Vdd - AD4 |4 M 13| GRC - AD3 |5 12| M - AD2 |6 11| MO - AD1 |7 10| GS* - AD0 |8 9| Vcc - +------------+ - - GR = GROM Ready. Should be connected to processor's READY/HOLD*. - GRC = GROM clock. Typically in the range of 400-500 kHz. - M = Direction. 1=read, 0=write - MO = Mode. 1=address counter access, 0=data access - GS* = GROM select. 0=select, 1=deselect - - GROMs are slow ROM devices, which are - interfaced via a 8-bit data bus, and include an internal address pointer - which is incremented after each read. This implies that accesses are - faster when reading consecutive bytes, although the address pointer can be - read and written at any time. - - GROMs are generally used to store programs written in GPL (Graphic Programming - Language): a proprietary, interpreted language. The GPL interpreter takes - most space of the TI-99/4A system ROMs. - - Both TI-99/4 and TI-99/4A include three GROMs, with some start-up code, - system routines and TI-Basic. TI99/4 includes an additional Equation - Editor. According to the preliminary schematics found on ftp.whtech.com, - TI-99/8 includes the three standard GROMs and 16 GROMs for the UCSD - p-system. TI99/2 does not include GROMs at all, and was not designed to - support any, although it should be relatively easy to create an expansion - card with the GPL interpreter and a /4a cartridge port. - - Communication with GROM is done by writing and reading data over the - AD0-AD7 lines. Within the TI-99 systems, the address bus is decoded for - the M, GS*, and MO lines: Writing a byte to address 9c02 asserts the GS* and - MO line, and clears the M line, which means the transmitted byte is put into - the internal address register. Two bytes must be written to set up the - complete address. - - It was obviously planned to offer GRAM circuits as well, since the - programming manuals refer to writing to a special address, clearing the MO - line. Although the TI-99 systems reserve a port in the memory space, no one - has ever seen a GRAM circuit in the wild. However, third-party products like - HSGPL or GRAM Kracker simulate GRAMs using conventional RAM with some - addressing circuitry, usually in a custom chip. - - Each GROM is logically 8 KiB long. Original TI-built GROM are 6 KiB long; - the extra 2kb can be read, and follow the following formula: - - GROM[0x1800+offset] = GROM[0x0800+offset] | GROM[0x1000+offset]; - - (sounds like address decoding is incomplete - we are lucky we don't burn - any silicon when doing so... Needless to say, some hackers simulated 8kb - GRAMs and GROMs with normal RAM/PROM chips and glue logic.) - - The address pointer is incremented after each GROM operation, but it will - always remain within the bounds of the currently selected GROM (e.g. after - 0x3fff comes 0x2000). - - Since address are 16-bit long, you can have up to 8 GROMs. Accordingly, - a cartridge may include up to 5 GROMs. - - Every GROM has an internal ID which represents the high-order three - address bits. The address counter can be set to any value from 0 - to 0xffff; the GROM will only react when selected and when the current - address counter's high-order bits match the ID of the chip. - Example: When the ID is 6, the GROM will react when the address - counter contains a value from 0xc000 to 0xdfff. - - CHECK: Reading the address increases the counter only once. The first access - returns the MSB, the second (and all following accesses) return the LSB. - - Michael Zapf, August 2010 - January 2012: rewritten as class - -***************************************************************************/ - -#include "emu.h" -#include "grom.h" - -#define TRACE_ADDRESS 0 - -/* - Constructor. -*/ -ti99_grom_device::ti99_grom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: bus8z_device(mconfig, GROM, "TI-99 GROM device", tag, owner, clock, "ti99_grom", __FILE__), m_writable(false), m_ident(0), m_size(0), - m_gromready(*this), m_clockrate(0), m_address(0), m_buffer(0), m_raddr_LSB(false), m_waddr_LSB(false), m_memptr(nullptr), m_timer(nullptr) -{ -} - -/* - Reading from the chip. Represents an access with M=1, GS*=0. The MO bit is - defined by the offset (0 or 1). This is the enhanced read function with - Z state. -*/ -READ8Z_MEMBER( ti99_grom_device::readz ) -{ - // Prevent debugger access - if (space.debugger_access()) return; - - if (offset & 2) - { - // GROMs generally answer the address read request - // (important if GROM simulators do not serve the request but rely on - // the console GROMs) so we don't check the ident - - /* When reading, reset the hi/lo flag byte for writing. */ - /* TODO: Verify this with a real machine. */ - m_waddr_LSB = false; - - /* Address reading is done in two steps; first, the high byte */ - /* is transferred, then the low byte. */ - if (m_raddr_LSB) - { - /* second pass */ - *value = m_address & 0x00ff; - m_raddr_LSB = false; - } - else - { - /* first pass */ - *value = (m_address & 0xff00)>>8; - m_raddr_LSB = true; - } - } - else - { - if (((m_address >> 13)&0x07)==m_ident) - { - // GROMs are buffered. Data is retrieved from a buffer, - // while the buffer is replaced with the next cell content. - if (TRACE_ADDRESS) if (m_ident==0) logerror("grom0: %04x = %02x\n", m_address-1, m_buffer); - *value = m_buffer; - // Get next value, put it in buffer. Note that the GROM - // wraps at 8K boundaries. - UINT16 addr = m_address-(m_ident<<13); - - if (m_size == 0x1800 && ((m_address&0x1fff)>=0x1800)) - m_buffer = m_memptr[addr-0x1000] | m_memptr[addr-0x0800]; - else - m_buffer = m_memptr[addr]; - } - // Note that all GROMs update their address counter. - // TODO: Check this on a real console - m_address = (m_address & 0xE000) | ((m_address + 1)&0x1FFF); - - // Reset the read and write address flipflops. - m_raddr_LSB = m_waddr_LSB = false; - - // Maybe the timer is also required for address reading/setting, but - // we don't have such technical details on GROMs. - clear_ready(); - } -} - -/* - Writing to the chip. Represents an access with M=0, GS*=0. The MO bit is - defined by the offset (0 or 1). -*/ -WRITE8_MEMBER( ti99_grom_device::write ) -{ - // Prevent debugger access - if (space.debugger_access()) return; - - if (offset & 2) - { - /* write GROM address */ - /* see comments above */ - m_raddr_LSB = false; - - /* Implements the internal flipflop. */ - /* The Editor/Assembler manuals says that the current address */ - /* plus one is returned. This effect is properly emulated */ - /* by using a read-ahead buffer. */ - if (m_waddr_LSB) - { - /* Accept low byte (2nd write) */ - m_address = (m_address & 0xFF00) | data; - /* Setting the address causes a new prefetch */ - if (is_selected()) - { - m_buffer = m_memptr[m_address-(m_ident<<13)]; - } - m_waddr_LSB = false; - if (TRACE_ADDRESS) if (m_ident==0) logerror("grom0: %04x\n", m_address); - } - else - { - /* Accept high byte (1st write). Do not advance the address conter. */ - m_address = (data << 8) | (m_address & 0xFF); - m_waddr_LSB = true; - return; - } - } - else - { - /* write GRAM data */ - if ((((m_address >> 13)&0x07)==m_ident) && m_writable) - { - UINT16 write_addr; - // We need to rewind by 1 because the read address has already advanced. - // However, do not change the address counter! - write_addr = (m_address & 0xE000) | ((m_address - 1)&0x1FFF); - - // UINT16 addr = m_address-(m_ident<<13); - if (m_size > 0x1800 || ((m_address&0x1fff)<0x1800)) - m_memptr[write_addr-(m_ident<<13)] = data; - } - m_raddr_LSB = m_waddr_LSB = false; - clear_ready(); - } - m_address = (m_address & 0xE000) | ((m_address + 1)&0x1FFF); -} - -/* - Timing. We assume that each data read results in READY going down for - one cycle at the given frequency. -*/ -void ti99_grom_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - m_gromready(ASSERT_LINE); -} - -void ti99_grom_device::clear_ready() -{ - m_gromready(CLEAR_LINE); - m_timer->adjust(attotime::from_hz(m_clockrate)); -} - -/*************************************************************************** - DEVICE FUNCTIONS -***************************************************************************/ - -void ti99_grom_device::device_start(void) -{ - const ti99grom_config *conf = reinterpret_cast(static_config()); - - m_memptr = owner()->memregion(conf->regionname)->base(); - assert (m_memptr!=nullptr); - m_memptr += conf->offset_reg; - - m_size = conf->size; - m_clockrate = conf->clockrate; - m_writable = conf->writable; - m_ident = conf->ident; - m_gromready.resolve_safe(); - - m_timer = timer_alloc(0); -} - -void ti99_grom_device::device_reset(void) -{ - m_address = 0; - m_raddr_LSB = false; - m_waddr_LSB = false; - m_buffer = 0; -} - -const device_type GROM = &device_creator; diff --git a/src/devices/bus/ti99x/grom.h b/src/devices/bus/ti99x/grom.h deleted file mode 100644 index a3129b6997f..00000000000 --- a/src/devices/bus/ti99x/grom.h +++ /dev/null @@ -1,108 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Michael Zapf -/*************************************************************************** - - GROM emulation - See grom.c for documentation, - - Michael Zapf - - February 2012: Rewritten as class - -***************************************************************************/ -#ifndef __TI99GROM__ -#define __TI99GROM__ - -#include "ti99defs.h" - -struct ti99grom_config -{ - bool writable; - int ident; - const char *regionname; - offs_t offset_reg; - int size; - int clockrate; -}; - -#define GROM_CONFIG(name) \ - const ti99grom_config(name) = - -#define MCFG_GROM_READY_CALLBACK(_write) \ - devcb = &ti99_grom_device::set_ready_wr_callback(*device, DEVCB_##_write); - -extern const device_type GROM; - -/* - ti99_grom. For bus8z_device see ti99defs.h -*/ -class ti99_grom_device : public bus8z_device, ti99grom_config -{ -public: - ti99_grom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - template static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast(device).m_gromready.set_callback(object); } - - DECLARE_READ8Z_MEMBER(readz) override; - DECLARE_WRITE8_MEMBER(write) override; - -private: - // Is this a GRAM (never seen actually, but obviously planned) - bool m_writable; - - // Identification of this GROM (0-7) - int m_ident; - - // If the GROM has only 6 KiB, the remaining 2 KiB are filled with a - // specific byte pattern which is created by a logical OR of lower - // regions - int m_size; - - // Ready callback. This line is usually connected to the READY pin of the CPU. - devcb_write_line m_gromready; - - // Frequency of the incoming GROM clock. In most application cases the - // GROM gets its clock from the video display processor (TMS9918) - int m_clockrate; - - /* Address pointer. */ - // This value is always expected to be in the range 0x0000 - 0xffff, even - // when this GROM is not addressed. - UINT16 m_address; - - /* GROM data buffer. */ - UINT8 m_buffer; - - /* Internal flip-flop. Used when retrieving the address counter. */ - bool m_raddr_LSB; - - /* Internal flip-flops. Used when writing the address counter.*/ - bool m_waddr_LSB; - - /* Pointer to the memory region contained in this GROM. */ - UINT8 *m_memptr; - - // Timer for READY line operation - emu_timer *m_timer; - - /* Indicates whether this device will react on the next read/write data access. */ - inline int is_selected() - { - return (((m_address >> 13)&0x07)==m_ident); - } - - // Calling this method causes the READY line to be cleared, which puts the - // CPU into wait state mode. A timer is set to raise READY again. - void clear_ready(); - - virtual void device_start(void) override; - virtual void device_reset(void) override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; -}; - - -#define MCFG_GROM_ADD(_tag, _config) \ - MCFG_DEVICE_ADD(_tag, GROM, 0) \ - MCFG_DEVICE_CONFIG(_config) - -#endif diff --git a/src/devices/bus/ti99x/gromport.cpp b/src/devices/bus/ti99x/gromport.cpp index baa77932f7e..9a836f970d1 100644 --- a/src/devices/bus/ti99x/gromport.cpp +++ b/src/devices/bus/ti99x/gromport.cpp @@ -40,7 +40,7 @@ This means that a maximum of 8 KiB of direct memory space can be accessed. The /GS line is used to enable GROM circuits on the board (serial ROMs with - own address counter, see grom.h). + own address counter, see tmc0430.h). When a cartridge is inserted the /RESET line is pulled to ground, which via a R/C component pulls down the /RESET input of the timer circuit for @@ -119,6 +119,7 @@ #define TRACE_ILLWRITE 0 #define TRACE_CONFIG 0 #define TRACE_READ 0 +#define TRACE_WRITE 0 #define TRACE_GROM 0 #define TRACE_GKRACKER 0 #define TRACE_CRU 0 @@ -186,20 +187,33 @@ gromport_device::gromport_device(const machine_config &mconfig, const char *tag, m_connector(nullptr), m_reset_on_insert(true), m_console_ready(*this), - m_console_reset(*this), m_grombase(0), m_grommask(0) + m_console_reset(*this) // , m_grombase(0), m_grommask(0) { } -/* Only called for addresses 6000-7fff and GROM addresses (see datamux config) */ +/* + Reading via the GROM port. Only 13 address lines are passed through + on the TI-99/4A, and 14 lines on the TI-99/8. +*/ READ8Z_MEMBER(gromport_device::readz) { if (m_connector != nullptr) - m_connector->readz(space, offset, value); + { + m_connector->readz(space, offset & m_mask, value); + if (TRACE_READ) if (m_romgq) logerror("Read %04x -> %02x\n", offset, *value); + } } +/* + Writing via the GROM port. Only 13 address lines are passed through + on the TI-99/4A, and 14 lines on the TI-99/8. +*/ WRITE8_MEMBER(gromport_device::write) { if (m_connector != nullptr) - m_connector->write(space, offset, data); + { + if (TRACE_WRITE) if (m_romgq) logerror("Write %04x <- %02x\n", offset, data); + m_connector->write(space, offset & m_mask, data); + } } READ8Z_MEMBER(gromport_device::crureadz) @@ -219,6 +233,31 @@ WRITE_LINE_MEMBER(gromport_device::ready_line) m_console_ready(state); } +/* + Asserted when the console addresses cartridge rom. +*/ +WRITE_LINE_MEMBER(gromport_device::romgq_line) +{ + m_romgq = state; + if (m_connector != nullptr) + m_connector->romgq_line(state); +} + +WRITE_LINE_MEMBER(gromport_device::gclock_in) +{ + if (m_connector != nullptr) + m_connector->gclock_in(state); +} + +/* + Combined GROM control lines. +*/ +WRITE8_MEMBER( gromport_device::set_gromlines ) +{ + if (m_connector != nullptr) + m_connector->set_gromlines(space, offset, data); +} + void gromport_device::device_start() { m_console_ready.resolve(); @@ -230,11 +269,11 @@ void gromport_device::device_reset() m_reset_on_insert = (ioport("CARTRESET")->read()==0x01); } -void gromport_device::set_grom_base(UINT16 grombase, UINT16 grommask) -{ - m_grombase = grombase; - m_grommask = grommask; -} +// void gromport_device::set_grom_base(UINT16 grombase, UINT16 grommask) +// { + // m_grombase = grombase; + // m_grommask = grommask; +// } /* Shall we reset the console when a cartridge has been inserted? @@ -254,16 +293,19 @@ void gromport_device::cartridge_inserted() void gromport_device::device_config_complete() { - m_connector = static_cast(first_subdevice()); - set_grom_base(0x9800, 0xf800); + m_connector = static_cast(subdevices().first()); } -SLOT_INTERFACE_START( gromport ) +SLOT_INTERFACE_START( gromport4 ) SLOT_INTERFACE("single", GROMPORT_SINGLE) SLOT_INTERFACE("multi", GROMPORT_MULTI) SLOT_INTERFACE("gkracker", GROMPORT_GK) SLOT_INTERFACE_END +SLOT_INTERFACE_START( gromport8 ) + SLOT_INTERFACE("single", GROMPORT_SINGLE) + SLOT_INTERFACE("multi", GROMPORT_MULTI) +SLOT_INTERFACE_END INPUT_PORTS_START(gromport) PORT_START( "CARTRESET" ) @@ -310,16 +352,6 @@ void ti99_cartridge_connector_device::device_config_complete() m_gromport = static_cast(owner()); } -UINT16 ti99_cartridge_connector_device::grom_base() -{ - return m_gromport->get_grom_base(); -} - -UINT16 ti99_cartridge_connector_device::grom_mask() -{ - return m_gromport->get_grom_mask(); -} - single_conn_device::single_conn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : ti99_cartridge_connector_device(mconfig, GROMPORT_SINGLE, "Standard cartridge connector", tag, owner, clock, "single", __FILE__), m_cartridge(nullptr) @@ -350,9 +382,31 @@ WRITE8_MEMBER(single_conn_device::cruwrite) m_cartridge->cruwrite(space, offset, data); } +WRITE_LINE_MEMBER(single_conn_device::romgq_line) +{ + // Pass through + m_cartridge->romgq_line(state); +} + +/* + Combined select lines +*/ +WRITE8_MEMBER(single_conn_device::set_gromlines) +{ + // Pass through + m_cartridge->set_gromlines(space, offset, data); +} + + +WRITE_LINE_MEMBER(single_conn_device::gclock_in) +{ + // Pass through + m_cartridge->gclock_in(state); +} + void single_conn_device::device_start() { - m_cartridge = static_cast(first_subdevice()); + m_cartridge = static_cast(subdevices().first()); } void single_conn_device::device_reset() @@ -475,10 +529,8 @@ int multi_conn_device::get_active_slot(bool changebase, offs_t offset) int slot; if (changebase) { - if ((offset & grom_mask()) == grom_base()) - { - set_slot((offset>>2) & 0x00ff); - } + // GROM selected? + if (m_gsel != 0) set_slot((offset>>2) & 0x00ff); } slot = m_active_slot; return slot; @@ -497,6 +549,50 @@ void multi_conn_device::remove(int index) m_cartridge[index] = nullptr; } +WRITE_LINE_MEMBER(multi_conn_device::romgq_line) +{ + m_readrom = state; + + // Propagate to all slots + for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) + { + if (m_cartridge[i] != nullptr) + { + m_cartridge[i]->romgq_line(state); + } + } +} + +/* + Combined select lines +*/ +WRITE8_MEMBER(multi_conn_device::set_gromlines) +{ + // GROM selected? + m_gsel = data; + + // Propagate to all slots + for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) + { + if (m_cartridge[i] != nullptr) + { + m_cartridge[i]->set_gromlines(space, offset, data); + } + } +} + +WRITE_LINE_MEMBER(multi_conn_device::gclock_in) +{ + // Propagate to all slots + for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) + { + if (m_cartridge[i] != nullptr) + { + m_cartridge[i]->gclock_in(state); + } + } +} + READ8Z_MEMBER(multi_conn_device::readz) { int slot = get_active_slot(true, offset); @@ -504,14 +600,14 @@ READ8Z_MEMBER(multi_conn_device::readz) // If we have a GROM access, we need to send the read request to all // attached cartridges so the slot is irrelevant here. Each GROM // contains an internal address counter, and we must make sure they all stay in sync. - if ((offset & grom_mask()) == grom_base()) + if (m_gsel != 0) { for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) { if (m_cartridge[i] != nullptr) { UINT8 newval = *value; - m_cartridge[i]->readz(space, offset, &newval, mem_mask); + m_cartridge[i]->readz(space, offset, &newval, 0xff); if (i==slot) { *value = newval; @@ -523,33 +619,32 @@ READ8Z_MEMBER(multi_conn_device::readz) { if (slot < NUMBER_OF_CARTRIDGE_SLOTS && m_cartridge[slot] != nullptr) { - m_cartridge[slot]->readz(space, offset, value, mem_mask); + m_cartridge[slot]->readz(space, offset, value, 0xff); } } } WRITE8_MEMBER(multi_conn_device::write) { - int slot = get_active_slot(true, offset); - // Same issue as above (read) // We don't have GRAM cartridges, anyway, so it's just used for setting the address. - if ((offset & grom_mask()) == grom_base()) + if (m_gsel != 0) { for (auto & elem : m_cartridge) { if (elem != nullptr) { - elem->write(space, offset, data, mem_mask); + elem->write(space, offset, data, 0xff); } } } else { + int slot = get_active_slot(true, offset); if (slot < NUMBER_OF_CARTRIDGE_SLOTS && m_cartridge[slot] != nullptr) { - // logerror("%s: try it on slot %d\n", tag(), slot); - m_cartridge[slot]->write(space, offset, data, mem_mask); + // logerror("writing %04x (slot %d) <- %02x\n", offset, slot, data); + m_cartridge[slot]->write(space, offset, data, 0xff); } } } @@ -595,6 +690,7 @@ void multi_conn_device::device_reset(void) { m_active_slot = 0; m_fixed_slot = ioport("CARTSLOT")->read() - 1; + m_gsel = 0; } static MACHINE_CONFIG_FRAGMENT( multi_slot ) @@ -751,9 +847,40 @@ gkracker_device::gkracker_device(const machine_config &mconfig, const char *tag, { } +WRITE_LINE_MEMBER(gkracker_device::romgq_line) +{ + if (m_cartridge != nullptr) + { + // Propagate to the guest + m_cartridge->romgq_line(state); + } +} + +/* + Combined select lines +*/ +WRITE8_MEMBER(gkracker_device::set_gromlines) +{ + m_gsel = data; + if (m_cartridge != nullptr) + { + // Propagate to the guest + m_cartridge->set_gromlines(space, offset, data); + } +} + +WRITE_LINE_MEMBER(gkracker_device::gclock_in) +{ + if (m_cartridge != nullptr) + { + // Propagate to the guest + m_cartridge->gclock_in(state); + } +} + READ8Z_MEMBER(gkracker_device::readz) { - if ((offset & grom_mask()) == grom_base()) + if (m_gsel != 0) { // Reads from the GRAM space of the GRAM Kracker. @@ -863,7 +990,7 @@ WRITE8_MEMBER(gkracker_device::write) m_cartridge->write(space, offset, data, mem_mask); } - if ((offset & grom_mask()) == grom_base()) + if (m_gsel != 0) { // Write to the GRAM space of the GRAM Kracker. if ((offset & 0x0002)==0x0002) @@ -1056,6 +1183,7 @@ void gkracker_device::device_reset() m_grom_address = 0; // for the GROM emulation m_ram_page = 0; m_waddr_LSB = false; + m_gsel = 0; } static MACHINE_CONFIG_FRAGMENT( gkracker_slot ) @@ -1270,15 +1398,15 @@ bool ti99_cartridge_device::has_grom() return m_pcb->m_grom_size>0; } -UINT16 ti99_cartridge_device::grom_base() -{ - return m_connector->grom_base(); -} - -UINT16 ti99_cartridge_device::grom_mask() -{ - return m_connector->grom_mask(); -} +// UINT16 ti99_cartridge_device::grom_base() +// { + // return m_connector->grom_base(); +// } +// +// UINT16 ti99_cartridge_device::grom_mask() +// { + // return m_connector->grom_mask(); +// } bool ti99_cartridge_device::call_load() { @@ -1401,12 +1529,14 @@ bool ti99_cartridge_device::call_softlist_load(software_list_device &swlist, con READ8Z_MEMBER(ti99_cartridge_device::readz) { - if (m_pcb != nullptr) m_pcb->readz(space, offset, value); + if (m_pcb != nullptr) + m_pcb->readz(space, offset, value); } WRITE8_MEMBER(ti99_cartridge_device::write) { - if (m_pcb != nullptr) m_pcb->write(space, offset, data); + if (m_pcb != nullptr) + m_pcb->write(space, offset, data); } READ8Z_MEMBER(ti99_cartridge_device::crureadz) @@ -1424,6 +1554,28 @@ WRITE_LINE_MEMBER( ti99_cartridge_device::ready_line ) m_connector->ready_line(state); } +WRITE_LINE_MEMBER( ti99_cartridge_device::romgq_line ) +{ + if (m_pcb != nullptr) + { + m_pcb->romgq_line(state); + m_readrom = state; + } +} + +/* + Combined select lines +*/ +WRITE8_MEMBER(ti99_cartridge_device::set_gromlines) +{ + if (m_pcb != nullptr) m_pcb->set_gromlines(space, offset, data); +} + +WRITE_LINE_MEMBER(ti99_cartridge_device::gclock_in) +{ + if (m_pcb != nullptr) m_pcb->gclock_in(state); +} + void ti99_cartridge_device::device_config_complete() { update_names(); @@ -1431,41 +1583,15 @@ void ti99_cartridge_device::device_config_complete() m_connector = static_cast(owner()); } -static GROM_CONFIG(grom3_config) -{ - false, 3, CARTGROM_TAG, 0x0000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(grom4_config) -{ - false, 4, CARTGROM_TAG, 0x2000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(grom5_config) -{ - false, 5, CARTGROM_TAG, 0x4000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(grom6_config) -{ - false, 6, CARTGROM_TAG, 0x6000, 0x1800, GROMFREQ -}; -static GROM_CONFIG(grom7_config) -{ - false, 7, CARTGROM_TAG, 0x8000, 0x1800, GROMFREQ -}; - /* 5 GROMs that may be contained in a cartridge */ static MACHINE_CONFIG_FRAGMENT( ti99_cartridge ) - MCFG_GROM_ADD( GROM3_TAG, grom3_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_cartridge_device, ready_line)) - MCFG_GROM_ADD( GROM4_TAG, grom4_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_cartridge_device, ready_line)) - MCFG_GROM_ADD( GROM5_TAG, grom5_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_cartridge_device, ready_line)) - MCFG_GROM_ADD( GROM6_TAG, grom6_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_cartridge_device, ready_line)) - MCFG_GROM_ADD( GROM7_TAG, grom7_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_cartridge_device, ready_line)) + MCFG_GROM_ADD( GROM3_TAG, 3, CARTGROM_TAG, 0x0000, WRITELINE(ti99_cartridge_device, ready_line)) + MCFG_GROM_ADD( GROM4_TAG, 4, CARTGROM_TAG, 0x2000, WRITELINE(ti99_cartridge_device, ready_line)) + MCFG_GROM_ADD( GROM5_TAG, 5, CARTGROM_TAG, 0x4000, WRITELINE(ti99_cartridge_device, ready_line)) + MCFG_GROM_ADD( GROM6_TAG, 6, CARTGROM_TAG, 0x6000, WRITELINE(ti99_cartridge_device, ready_line)) + MCFG_GROM_ADD( GROM7_TAG, 7, CARTGROM_TAG, 0x8000, WRITELINE(ti99_cartridge_device, ready_line)) MACHINE_CONFIG_END machine_config_constructor ti99_cartridge_device::device_mconfig_additions() const @@ -1499,19 +1625,31 @@ const device_type TI99CART = &device_creator; Unlike in the previous implementation we do not model it as a full device. ***************************************************************************/ -ti99_cartridge_pcb::ti99_cartridge_pcb(): m_cart(nullptr), m_grom_size(0), m_rom_size(0), m_ram_size(0), m_rom_ptr(nullptr), m_ram_ptr(nullptr), m_rom_page(0), m_grom_ptr(nullptr), m_grom_address(0), m_ram_page(0), m_tag(nullptr) +ti99_cartridge_pcb::ti99_cartridge_pcb() + : m_cart(nullptr), + m_grom_size(0), + m_rom_size(0), + m_ram_size(0), + m_rom_ptr(nullptr), + m_ram_ptr(nullptr), + m_access_cartspace(false), + m_rom_page(0), + m_grom_ptr(nullptr), + m_grom_address(0), + m_ram_page(0), + m_tag(nullptr) { } -UINT16 ti99_cartridge_pcb::grom_base() -{ - return m_cart->grom_base(); -} - -UINT16 ti99_cartridge_pcb::grom_mask() -{ - return m_cart->grom_mask(); -} +// UINT16 ti99_cartridge_pcb::grom_base() +// { + // return m_cart->grom_base(); +// } +// +// UINT16 ti99_cartridge_pcb::grom_mask() +// { + // return m_cart->grom_mask(); +// } void ti99_cartridge_pcb::set_cartridge(ti99_cartridge_device *cart) { @@ -1540,31 +1678,38 @@ WRITE8_MEMBER(ti99_cartridge_pcb::gromwrite) } } +/* + TI-99/4A cartridges can only occupy 8 KiB of CPU RAM space. For TI-99/8 + cartridges with up to 16 KiB we need a new PCB type. Unfortunately, such + cartridges were never developed. +*/ READ8Z_MEMBER(ti99_cartridge_pcb::readz) { - if ((offset & grom_mask())==grom_base()) - gromreadz(space, offset, value, mem_mask); - else + if (m_access_cartspace) { if (m_rom_ptr!=nullptr) { - // For TI-99/8 we should plan for 16K cartridges. However, none was ever produced. - // Well, forget about that. *value = m_rom_ptr[offset & 0x1fff]; - // logerror("%s: read cartridge rom space %04x = %02x\n", tag(), offset, *value); } } + else + { + // Will not return anything when not selected (preceding gsq=ASSERT) + gromreadz(space, offset, value, mem_mask); + } } WRITE8_MEMBER(ti99_cartridge_pcb::write) { - // logerror("%s: write standard\n", tag()); - if ((offset & grom_mask())==grom_base()) - gromwrite(space, offset, data, mem_mask); - else + if (m_access_cartspace) { if (TRACE_ILLWRITE) space.device().logerror("%s: Cannot write to ROM space at %04x\n", tag(), offset); } + else + { + // Will not change anything when not selected (preceding gsq=ASSERT) + gromwrite(space, offset, data, mem_mask); + } } READ8Z_MEMBER(ti99_cartridge_pcb::crureadz) @@ -1575,11 +1720,35 @@ WRITE8_MEMBER(ti99_cartridge_pcb::cruwrite) { } -inline void ti99_cartridge_pcb::set_grom_pointer(int number, device_t *dev) +void ti99_cartridge_pcb::set_grom_pointer(int number, device_t *dev) { - m_grom[number] = static_cast(dev); + m_grom[number] = static_cast(dev); } + +WRITE_LINE_MEMBER( ti99_cartridge_pcb::romgq_line ) +{ + m_access_cartspace = (state==ASSERT_LINE); +} + +// Propagate to all GROMs + +/* + Combined select lines +*/ +WRITE8_MEMBER(ti99_cartridge_pcb::set_gromlines) +{ + for (auto& elem : m_grom) + if (elem != nullptr) elem->set_lines(space, offset, data); +} + +WRITE_LINE_MEMBER(ti99_cartridge_pcb::gclock_in) +{ + for (auto& elem : m_grom) + if (elem != nullptr) elem->gclock_in(state); +} + + /***************************************************************************** Cartridge type: Paged (Extended Basic) This cartridge consists of GROM memory and 2 pages of standard ROM. @@ -1591,23 +1760,28 @@ inline void ti99_cartridge_pcb::set_grom_pointer(int number, device_t *dev) READ8Z_MEMBER(ti99_paged_cartridge::readz) { - if ((offset & grom_mask())==grom_base()) - gromreadz(space, offset, value, mem_mask); - else + if (m_access_cartspace) { *value = m_rom_ptr[(offset & 0x1fff) | (m_rom_page << 13)]; } + else + { + // Will not return anything when not selected (preceding gsq=ASSERT) + gromreadz(space, offset, value, mem_mask); + } } WRITE8_MEMBER(ti99_paged_cartridge::write) { - // logerror("%s: write standard\n", tag()); - if ((offset & grom_mask())==grom_base()) - gromwrite(space, offset, data, mem_mask); - - else { + if (m_access_cartspace) + { m_rom_page = (offset >> 1) & 1; } + else + { + // Will not change anything when not selected (preceding gsq=ASSERT) + gromwrite(space, offset, data, mem_mask); + } } /***************************************************************************** @@ -1620,10 +1794,7 @@ WRITE8_MEMBER(ti99_paged_cartridge::write) /* Read function for the minimem cartridge. */ READ8Z_MEMBER(ti99_minimem_cartridge::readz) { - if ((offset & grom_mask())==grom_base()) - gromreadz(space, offset, value, mem_mask); - - else + if (m_access_cartspace) { if ((offset & 0x1000)==0x0000) { @@ -1637,16 +1808,16 @@ READ8Z_MEMBER(ti99_minimem_cartridge::readz) *value = m_ram_ptr[offset & 0x0fff]; } } + else + { + gromreadz(space, offset, value, mem_mask); + } } /* Write function for the minimem cartridge. */ WRITE8_MEMBER(ti99_minimem_cartridge::write) { - // logerror("%s: write standard\n", tag()); - if ((offset & grom_mask())==grom_base()) - gromwrite(space, offset, data, mem_mask); - - else + if (m_access_cartspace) { if ((offset & 0x1000)==0x0000) { @@ -1657,6 +1828,10 @@ WRITE8_MEMBER(ti99_minimem_cartridge::write) m_ram_ptr[offset & 0x0fff] = data; } } + else + { + gromwrite(space, offset, data, mem_mask); + } } /***************************************************************************** @@ -1678,26 +1853,30 @@ WRITE8_MEMBER(ti99_minimem_cartridge::write) /* Read function for the super cartridge. */ READ8Z_MEMBER(ti99_super_cartridge::readz) { - if ((offset & grom_mask())==grom_base()) - gromreadz(space, offset, value, mem_mask); - else + if (m_access_cartspace) { if (m_ram_ptr != nullptr) { *value = m_ram_ptr[(m_ram_page << 13) | (offset & 0x1fff)]; } } + else + { + gromreadz(space, offset, value, mem_mask); + } } /* Write function for the super cartridge. */ WRITE8_MEMBER(ti99_super_cartridge::write) { - if ((offset & grom_mask())==grom_base()) - gromwrite(space, offset, data, mem_mask); - else + if (m_access_cartspace) { m_ram_ptr[(m_ram_page << 13) | (offset & 0x1fff)] = data; } + else + { + gromwrite(space, offset, data, mem_mask); + } } READ8Z_MEMBER(ti99_super_cartridge::crureadz) @@ -1763,9 +1942,7 @@ WRITE8_MEMBER(ti99_super_cartridge::cruwrite) /* Read function for the mbx cartridge. */ READ8Z_MEMBER(ti99_mbx_cartridge::readz) { - if ((offset & grom_mask())==grom_base()) - gromreadz(space, offset, value, mem_mask); - else + if (m_access_cartspace) { if ((offset & 0x1c00)==0x0c00) { @@ -1781,14 +1958,16 @@ READ8Z_MEMBER(ti99_mbx_cartridge::readz) *value = m_rom_ptr[(offset & 0x1fff) | (m_rom_page<<13)]; } } + else + { + gromreadz(space, offset, value, mem_mask); + } } /* Write function for the mbx cartridge. */ WRITE8_MEMBER(ti99_mbx_cartridge::write) { - if ((offset & grom_mask())==grom_base()) - gromwrite(space, offset, data, mem_mask); - else + if (m_access_cartspace) { if (offset == 0x6ffe) { @@ -1802,6 +1981,10 @@ WRITE8_MEMBER(ti99_mbx_cartridge::write) m_ram_ptr[offset & 0x03ff] = data; } } + else + { + gromwrite(space, offset, data, mem_mask); + } } /***************************************************************************** @@ -2032,9 +2215,15 @@ WRITE8_MEMBER(ti99_pagedcru_cartridge::cruwrite) ******************************************************************************/ +WRITE_LINE_MEMBER(ti99_gromemu_cartridge::gsq_line) +{ + m_grom_space = (state==ASSERT_LINE); +} + + READ8Z_MEMBER(ti99_gromemu_cartridge::readz) { - if ((offset & grom_mask())==grom_base()) + if (m_grom_space) gromemureadz(space, offset, value, mem_mask); else { @@ -2055,8 +2244,7 @@ READ8Z_MEMBER(ti99_gromemu_cartridge::readz) WRITE8_MEMBER(ti99_gromemu_cartridge::write) { - // logerror("%s: write standard\n", tag()); - if ((offset & grom_mask())==grom_base()) + if (m_grom_space) gromemuwrite(space, offset, data, mem_mask); else { @@ -2179,7 +2367,7 @@ rpk::rpk(emu_options& options, const char* sysname) rpk::~rpk() { - //if (TRACE_RPK) logerror("gromport/RPK: Destroy RPK\n"); + if (TRACE_RPK) printf("gromport/RPK: Destroy RPK\n"); } /* @@ -2290,7 +2478,7 @@ rpk_socket* rpk_reader::load_rom_resource(util::archive_file &zip, xml_data_node file = xml_get_attribute_string(rom_resource_node, "file", nullptr); if (file == nullptr) throw rpk_exception(RPK_INVALID_LAYOUT, " must have a 'file' attribute"); - //if (TRACE_RPK) logerror("gromport/RPK: Loading ROM contents for socket '%s' from file %s\n", socketname, file); + if (TRACE_RPK) printf("gromport/RPK: Loading ROM contents for socket '%s' from file %s\n", socketname, file); // check for crc crcstr = xml_get_attribute_string(rom_resource_node, "crc", nullptr); @@ -2378,7 +2566,7 @@ rpk_socket* rpk_reader::load_ram_resource(emu_options &options, xml_data_node* r contents = global_alloc_array_clear(length); if (contents==nullptr) throw rpk_exception(RPK_OUT_OF_MEMORY); - //if (TRACE_RPK) logerror("gromport/RPK: Allocating RAM buffer (%d bytes) for socket '%s'\n", length, socketname); + if (TRACE_RPK) printf("gromport/RPK: Allocating RAM buffer (%d bytes) for socket '%s'\n", length, socketname); ram_pname = nullptr; @@ -2400,7 +2588,7 @@ rpk_socket* rpk_reader::load_ram_resource(emu_options &options, xml_data_node* r std::string ram_pathname = std::string(system_name).append(PATH_SEPARATOR).append(ram_filename); ram_pname = core_strdup(ram_pathname.c_str()); // load, and fill rest with 00 - //if (TRACE_RPK) logerror("gromport/RPK: Loading NVRAM contents from '%s'\n", ram_pname); + if (TRACE_RPK) printf("gromport/RPK: Loading NVRAM contents from '%s'\n", ram_pname); image_battery_load_by_name(options, ram_pname, contents, length, 0x00); } } @@ -2488,7 +2676,7 @@ rpk* rpk_reader::open(emu_options &options, const char *filename, const char *sy // We'll try to find the PCB type on the provided type list. pcb_type = xml_get_attribute_string(pcb_node, "type", nullptr); if (pcb_type==nullptr) throw rpk_exception(RPK_INVALID_LAYOUT, " must have a 'type' attribute"); - //if (TRACE_RPK) logerror("gromport/RPK: Cartridge says it has PCB type '%s'\n", pcb_type); + if (TRACE_RPK) printf("gromport/RPK: Cartridge says it has PCB type '%s'\n", pcb_type); i=0; do diff --git a/src/devices/bus/ti99x/gromport.h b/src/devices/bus/ti99x/gromport.h index 36900c40045..8f49a7f98d4 100644 --- a/src/devices/bus/ti99x/gromport.h +++ b/src/devices/bus/ti99x/gromport.h @@ -13,7 +13,7 @@ #include "emu.h" #include "ti99defs.h" -#include "grom.h" +#include "machine/tmc0430.h" extern const device_type GROMPORT; @@ -29,13 +29,22 @@ public: DECLARE_WRITE8_MEMBER(cruwrite); DECLARE_WRITE_LINE_MEMBER(ready_line); + DECLARE_WRITE_LINE_MEMBER(romgq_line); + + // Combined GROM select lines + DECLARE_WRITE8_MEMBER(set_gromlines); + + DECLARE_WRITE_LINE_MEMBER(gclock_in); + + static void set_mask(device_t &device, int mask) { downcast(device).m_mask = mask; } + template static devcb_base &static_set_ready_callback(device_t &device, _Object object) { return downcast(device).m_console_ready.set_callback(object); } template static devcb_base &static_set_reset_callback(device_t &device, _Object object) { return downcast(device).m_console_reset.set_callback(object); } void cartridge_inserted(); - void set_grom_base(UINT16 grombase, UINT16 grommask); - UINT16 get_grom_base() { return m_grombase; } - UINT16 get_grom_mask() { return m_grommask; } + // void set_grom_base(UINT16 grombase, UINT16 grommask); + // UINT16 get_grom_base() { return m_grombase; } + // UINT16 get_grom_mask() { return m_grommask; } protected: virtual void device_start() override; @@ -48,15 +57,24 @@ private: bool m_reset_on_insert; devcb_write_line m_console_ready; devcb_write_line m_console_reset; - UINT16 m_grombase; - UINT16 m_grommask; + int m_mask; + int m_romgq; + // UINT16 m_grombase; + // UINT16 m_grommask; }; -SLOT_INTERFACE_EXTERN(gromport); +SLOT_INTERFACE_EXTERN(gromport4); +SLOT_INTERFACE_EXTERN(gromport8); -#define MCFG_TI99_GROMPORT_ADD( _tag ) \ +#define MCFG_GROMPORT4_ADD( _tag ) \ MCFG_DEVICE_ADD(_tag, GROMPORT, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(gromport, "single", false) + gromport_device::set_mask(*device, 0x1fff); \ + MCFG_DEVICE_SLOT_INTERFACE(gromport4, "single", false) + +#define MCFG_GROMPORT8_ADD( _tag ) \ + MCFG_DEVICE_ADD(_tag, GROMPORT, 0) \ + gromport_device::set_mask(*device, 0x3fff); \ + MCFG_DEVICE_SLOT_INTERFACE(gromport8, "single", false) #define MCFG_GROMPORT_READY_HANDLER( _ready ) \ devcb = &gromport_device::static_set_ready_callback( *device, DEVCB_##_ready ); @@ -80,11 +98,16 @@ public: DECLARE_WRITE8_MEMBER(cruwrite); DECLARE_WRITE_LINE_MEMBER(ready_line); + DECLARE_WRITE_LINE_MEMBER(romgq_line); + DECLARE_WRITE8_MEMBER(set_gromlines); + + DECLARE_WRITE_LINE_MEMBER(gclock_in); + bool is_available() { return m_pcb != nullptr; } bool has_grom(); void set_slot(int i); - UINT16 grom_base(); - UINT16 grom_mask(); + // UINT16 grom_base(); + // UINT16 grom_mask(); protected: virtual void device_start() override { }; @@ -111,6 +134,7 @@ protected: const option_guide *create_option_guide() const override { return nullptr; } private: + bool m_readrom; bool m_softlist; int m_pcbtype; int m_slot; @@ -136,18 +160,24 @@ public: virtual DECLARE_READ8Z_MEMBER(crureadz) = 0; virtual DECLARE_WRITE8_MEMBER(cruwrite) = 0; + virtual DECLARE_WRITE_LINE_MEMBER(romgq_line) =0; + virtual DECLARE_WRITE8_MEMBER(set_gromlines) =0; + + virtual DECLARE_WRITE_LINE_MEMBER(gclock_in) =0; + DECLARE_WRITE_LINE_MEMBER(ready_line); virtual void insert(int index, ti99_cartridge_device* cart) { m_gromport->cartridge_inserted(); }; virtual void remove(int index) { }; - UINT16 grom_base(); - UINT16 grom_mask(); + // UINT16 grom_base(); + // UINT16 grom_mask(); protected: ti99_cartridge_connector_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); virtual void device_config_complete() override; gromport_device* m_gromport; + int m_gsel; }; /* @@ -162,6 +192,9 @@ public: DECLARE_WRITE8_MEMBER(write) override; DECLARE_READ8Z_MEMBER(crureadz) override; DECLARE_WRITE8_MEMBER(cruwrite) override; + DECLARE_WRITE_LINE_MEMBER(romgq_line) override; + DECLARE_WRITE8_MEMBER(set_gromlines) override; + DECLARE_WRITE_LINE_MEMBER(gclock_in) override; protected: virtual void device_start() override; @@ -190,6 +223,9 @@ public: DECLARE_WRITE8_MEMBER(write) override; DECLARE_READ8Z_MEMBER(crureadz) override; DECLARE_WRITE8_MEMBER(cruwrite) override; + DECLARE_WRITE_LINE_MEMBER(romgq_line) override; + DECLARE_WRITE8_MEMBER(set_gromlines) override; + DECLARE_WRITE_LINE_MEMBER(gclock_in) override; void insert(int index, ti99_cartridge_device* cart) override; void remove(int index) override; @@ -201,6 +237,7 @@ protected: virtual ioport_constructor device_input_ports() const override; private: + bool m_readrom; int m_active_slot; int m_fixed_slot; int m_next_free_slot; @@ -222,6 +259,9 @@ public: DECLARE_WRITE8_MEMBER(write) override; DECLARE_READ8Z_MEMBER(crureadz) override; DECLARE_WRITE8_MEMBER(cruwrite) override; + DECLARE_WRITE_LINE_MEMBER(romgq_line) override; + DECLARE_WRITE8_MEMBER(set_gromlines) override; + DECLARE_WRITE_LINE_MEMBER(gclock_in) override; void insert(int index, ti99_cartridge_device* cart) override; void remove(int index) override; @@ -275,23 +315,28 @@ protected: virtual DECLARE_READ8Z_MEMBER(crureadz); virtual DECLARE_WRITE8_MEMBER(cruwrite); + DECLARE_WRITE_LINE_MEMBER(romgq_line); + DECLARE_WRITE8_MEMBER(set_gromlines); + DECLARE_WRITE_LINE_MEMBER(gclock_in); + DECLARE_READ8Z_MEMBER(gromreadz); DECLARE_WRITE8_MEMBER(gromwrite); inline void set_grom_pointer(int number, device_t *dev); void set_cartridge(ti99_cartridge_device *cart); - UINT16 grom_base(); - UINT16 grom_mask(); + // UINT16 grom_base(); + // UINT16 grom_mask(); const char* tag() { return m_tag; } void set_tag(const char* tag) { m_tag = tag; } ti99_cartridge_device* m_cart; - ti99_grom_device* m_grom[5]; + tmc0430_device* m_grom[5]; int m_grom_size; int m_rom_size; int m_ram_size; UINT8* m_rom_ptr; UINT8* m_ram_ptr; + bool m_access_cartspace; int m_rom_page; // for some cartridge types UINT8* m_grom_ptr; // for gromemu int m_grom_address; // for gromemu @@ -398,15 +443,19 @@ public: class ti99_gromemu_cartridge : public ti99_cartridge_pcb { public: - ti99_gromemu_cartridge(): m_waddr_LSB(false) + ti99_gromemu_cartridge(): m_waddr_LSB(false), m_grom_space(false) { m_grom_address = 0; } ~ti99_gromemu_cartridge() { }; DECLARE_READ8Z_MEMBER(readz) override; DECLARE_WRITE8_MEMBER(write) override; DECLARE_READ8Z_MEMBER(gromemureadz); DECLARE_WRITE8_MEMBER(gromemuwrite); + + DECLARE_WRITE_LINE_MEMBER(gsq_line); + private: bool m_waddr_LSB; + bool m_grom_space; }; diff --git a/src/devices/bus/ti99x/joyport.cpp b/src/devices/bus/ti99x/joyport.cpp index 9aab362f812..5cc4dd08e56 100644 --- a/src/devices/bus/ti99x/joyport.cpp +++ b/src/devices/bus/ti99x/joyport.cpp @@ -87,7 +87,7 @@ void joyport_device::device_start() void joyport_device::device_config_complete() { - m_connected = static_cast(first_subdevice()); + m_connected = static_cast(subdevices().first()); } /*****************************************************************************/ diff --git a/src/devices/bus/ti99x/ti99defs.h b/src/devices/bus/ti99x/ti99defs.h index 130c0cfbc40..8d137e6599f 100644 --- a/src/devices/bus/ti99x/ti99defs.h +++ b/src/devices/bus/ti99x/ti99defs.h @@ -32,6 +32,7 @@ #define JOYPORT_TAG "joyport" #define VDP_TAG "vdp" #define DSRROM "dsrrom" +#define CONSOLEROM "consolerom" #define VDPFREQ XTAL_10_738635MHz #define GROMFREQ VDPFREQ/24 @@ -41,10 +42,49 @@ #define DRAM_TAG "dram8" #define MAPPER_TAG "mapper" #define MAINBOARD8_TAG "mainboard8" -#define SPEECH_TAG "speech" -#define ROM0_TAG "rom0" -#define ROM1_TAG "rom1" -#define PCODEROM_TAG "pcode" +#define SPEECHSYN_TAG "speech" + +#define ROM0_REG "rom0_region" +#define ROM1_REG "rom1_region" +#define PASCAL_REG "pascal_region" +#define SYSGROM_REG "sysgrom_region" +#define GROMLIB1_REG "gromlib1_region" +#define GROMLIB2_REG "gromlib2_region" +#define GROMLIB3_REG "gromlib3_region" +#define SPEECHROM_REG "speech_region" + +#define GROMLIB_TAG "gromlib" +#define SYSGROM_TAG GROMLIB_TAG "0" +#define SYSGROM0_TAG SYSGROM_TAG "_0" +#define SYSGROM1_TAG SYSGROM_TAG "_1" +#define SYSGROM2_TAG SYSGROM_TAG "_2" + +#define GLIB1_TAG GROMLIB_TAG "1" +#define GLIB10_TAG GLIB1_TAG "_0" +#define GLIB11_TAG GLIB1_TAG "_1" +#define GLIB12_TAG GLIB1_TAG "_2" +#define GLIB13_TAG GLIB1_TAG "_3" +#define GLIB14_TAG GLIB1_TAG "_4" +#define GLIB15_TAG GLIB1_TAG "_5" +#define GLIB16_TAG GLIB1_TAG "_6" +#define GLIB17_TAG GLIB1_TAG "_7" + +#define GLIB2_TAG GROMLIB_TAG "2" +#define GLIB20_TAG GLIB2_TAG "_0" +#define GLIB21_TAG GLIB2_TAG "_1" +#define GLIB22_TAG GLIB2_TAG "_2" +#define GLIB23_TAG GLIB2_TAG "_3" +#define GLIB24_TAG GLIB2_TAG "_4" +#define GLIB25_TAG GLIB2_TAG "_5" +#define GLIB26_TAG GLIB2_TAG "_6" +#define GLIB27_TAG GLIB2_TAG "_7" + +#define GLIB3_TAG GROMLIB_TAG "3" +#define GLIB30_TAG GLIB3_TAG "_0" +#define GLIB31_TAG GLIB3_TAG "_1" +#define GLIB32_TAG GLIB3_TAG "_2" + + // Geneve #define GKEYBOARD_TAG "gkeyboard" diff --git a/src/devices/bus/ti99x/videowrp.cpp b/src/devices/bus/ti99x/videowrp.cpp index 6f09da722e7..387872bba5d 100644 --- a/src/devices/bus/ti99x/videowrp.cpp +++ b/src/devices/bus/ti99x/videowrp.cpp @@ -39,7 +39,9 @@ ti_std_video_device::ti_std_video_device(const machine_config &mconfig, const ch } ti_exp_video_device::ti_exp_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ti_video_device(mconfig, V9938VIDEO, "TI99 EXP Video subsystem", tag, owner, clock, "v9938_video", __FILE__), m_v9938(nullptr) + : ti_video_device(mconfig, V9938VIDEO, "TI99 EXP Video subsystem", tag, owner, clock, "v9938_video", __FILE__), + m_v9938(nullptr), + m_out_gromclk_cb(*this) { } @@ -129,6 +131,14 @@ WRITE16_MEMBER( ti_exp_video_device::write16 ) } } +void ti_exp_video_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + // Pulse it + m_out_gromclk_cb(ASSERT_LINE); + m_out_gromclk_cb(CLEAR_LINE); +} + + /******************************************************************************/ /* @@ -194,10 +204,13 @@ void ti_video_device::device_start(void) void ti_exp_video_device::device_start(void) { m_v9938 = static_cast(machine().device(VDP_TAG)); + m_out_gromclk_cb.resolve(); + m_gromclk_timer = timer_alloc(0); } -void ti_video_device::device_reset(void) +void ti_exp_video_device::device_reset(void) { + if (!m_out_gromclk_cb.isnull()) m_gromclk_timer->adjust(attotime::zero, 0, attotime::from_hz(XTAL_10_738635MHz/24)); } /**************************************************************************/ diff --git a/src/devices/bus/ti99x/videowrp.h b/src/devices/bus/ti99x/videowrp.h index cb339e9dd60..c59069db13b 100644 --- a/src/devices/bus/ti99x/videowrp.h +++ b/src/devices/bus/ti99x/videowrp.h @@ -30,7 +30,7 @@ protected: /* Constructor */ ti_video_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); virtual void device_start(void) override; - virtual void device_reset(void) override; + virtual void device_reset(void) override { }; virtual DECLARE_READ8Z_MEMBER(readz) override { }; virtual DECLARE_WRITE8_MEMBER(write) override { }; }; @@ -55,6 +55,8 @@ class ti_exp_video_device : public ti_video_device { public: ti_exp_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + template static devcb_base &set_out_gromclk_callback(device_t &device, _Object object) { return downcast(device).m_out_gromclk_cb.set_callback(object); } + void video_update_mouse(int delta_x, int delta_y, int buttons); DECLARE_READ8Z_MEMBER(readz) override; DECLARE_WRITE8_MEMBER(write) override; @@ -63,10 +65,20 @@ public: void reset_vdp(int state) override { m_v9938->reset_line(state); } protected: - virtual void device_start(void) override; - v9938_device *m_v9938; + virtual void device_start(void) override; + virtual void device_reset(void) override; + +private: + void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + v9938_device *m_v9938; + devcb_write_line m_out_gromclk_cb; // GROMCLK line is optional; if present, pulse it by XTAL/24 rate + emu_timer *m_gromclk_timer; }; +#define MCFG_ADD_GROMCLK_CB(_devcb) \ + devcb = &ti_exp_video_device::set_out_gromclk_callback(*device, DEVCB_##_devcb); + + extern const device_type TI99VIDEO; extern const device_type V9938VIDEO; @@ -131,35 +143,39 @@ protected: /****************************************************************************/ -#define MCFG_TI_TMS991x_ADD_NTSC(_tag, _chip, _vsize, _class, _int) \ +#define MCFG_TI_TMS991x_ADD_NTSC(_tag, _chip, _vsize, _class, _int, _gclk) \ MCFG_DEVICE_ADD(_tag, TI99VIDEO, 0) \ MCFG_DEVICE_ADD( VDP_TAG, _chip, XTAL_10_738635MHz / 2 ) \ MCFG_TMS9928A_VRAM_SIZE(_vsize) \ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(_class,_int)) \ + MCFG_TMS9928A_OUT_GROMCLK_CB(WRITELINE(_class,_gclk)) \ MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG ) \ MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) -#define MCFG_TI_TMS991x_ADD_PAL(_tag, _chip, _vsize, _class, _int) \ +#define MCFG_TI_TMS991x_ADD_PAL(_tag, _chip, _vsize, _class, _int, _gclk) \ MCFG_DEVICE_ADD(_tag, TI99VIDEO, 0) \ MCFG_DEVICE_ADD( VDP_TAG, _chip, XTAL_10_738635MHz / 2 ) \ MCFG_TMS9928A_VRAM_SIZE(_vsize) \ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(_class,_int)) \ + MCFG_TMS9928A_OUT_GROMCLK_CB(WRITELINE(_class,_gclk)) \ MCFG_TMS9928A_SCREEN_ADD_PAL( SCREEN_TAG ) \ MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) -#define MCFG_TI998_ADD_NTSC(_tag, _chip, _vsize, _class, _int) \ +#define MCFG_TI998_ADD_NTSC(_tag, _chip, _vsize, _class, _int, _gclk) \ MCFG_DEVICE_ADD(_tag, TI99VIDEO, 0) \ MCFG_DEVICE_ADD( VDP_TAG, _chip, XTAL_10_738635MHz / 2 ) \ MCFG_TMS9928A_VRAM_SIZE(_vsize) \ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(_class,_int)) \ + MCFG_TMS9928A_OUT_GROMCLK_CB(WRITELINE(_class,_gclk)) \ MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG ) \ MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) -#define MCFG_TI998_ADD_PAL(_tag, _chip, _vsize, _class, _int) \ +#define MCFG_TI998_ADD_PAL(_tag, _chip, _vsize, _class, _int, _gclk) \ MCFG_DEVICE_ADD(_tag, TI99VIDEO, 0) \ MCFG_DEVICE_ADD( VDP_TAG, _chip, XTAL_10_738635MHz / 2 ) \ MCFG_TMS9928A_VRAM_SIZE(_vsize) \ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(_class,_int)) \ + MCFG_TMS9928A_OUT_GROMCLK_CB(WRITELINE(_class,_gclk)) \ MCFG_TMS9928A_SCREEN_ADD_PAL( SCREEN_TAG ) \ MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) diff --git a/src/devices/machine/legscsi.cpp b/src/devices/machine/legscsi.cpp index 23cc5902a29..e8cbd7e9704 100644 --- a/src/devices/machine/legscsi.cpp +++ b/src/devices/machine/legscsi.cpp @@ -133,9 +133,9 @@ UINT8 legacy_scsi_host_adapter::get_status() scsihle_device *legacy_scsi_host_adapter::get_device(int id) { // steal scsi devices from bus - for (device_t *device = m_scsi_port->first_subdevice(); device != nullptr; device = device->next()) + for (device_t &device : m_scsi_port->subdevices()) { - SCSI_PORT_SLOT_device *slot = dynamic_cast(device); + SCSI_PORT_SLOT_device *slot = dynamic_cast(&device); if (slot != nullptr) { scsihle_device *scsidev = dynamic_cast(slot->dev()); diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index d0a06604707..1ca8d185e47 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -312,12 +312,12 @@ void netlist_mame_device_t::device_start() m_setup_func(*m_setup); /* let sub-devices tweak the netlist */ - for( device_t *d = this->first_subdevice(); d != nullptr; d = d->next() ) + for (device_t &d : subdevices()) { - netlist_mame_sub_interface *sdev = dynamic_cast(d); + netlist_mame_sub_interface *sdev = dynamic_cast(&d); if( sdev != nullptr ) { - LOG_DEV_CALLS(("Found subdevice %s/%s\n", d->name(), d->shortname())); + LOG_DEV_CALLS(("Found subdevice %s/%s\n", d.name(), d.shortname())); sdev->custom_netlist_additions(*m_setup); } } diff --git a/src/devices/machine/pci.cpp b/src/devices/machine/pci.cpp index 33a84919f1e..5987a423a09 100644 --- a/src/devices/machine/pci.cpp +++ b/src/devices/machine/pci.cpp @@ -434,14 +434,15 @@ void pci_bridge_device::device_start() for(auto & elem : sub_devices) elem = nullptr; - for(device_t *d = bus_root()->first_subdevice(); d != nullptr; d = d->next()) { - const char *t = d->tag(); + for (device_t &d : bus_root()->subdevices()) + { + const char *t = d.tag(); int l = strlen(t); if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') continue; int id = strtol(t+l-4, nullptr, 16); int fct = t[l-1] - '0'; - sub_devices[(id << 3) | fct] = downcast(d); + sub_devices[(id << 3) | fct] = downcast(&d); } mapper_cb cf_cb(FUNC(pci_bridge_device::regenerate_config_mapping), this); diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index b31e4734751..ca743e73d70 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -502,6 +502,15 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_rs_ws)); save_item(NAME(m_read_latch)); save_item(NAME(m_write_latch)); + + // 5110 specific stuff + save_item(NAME(m_PDC)); + save_item(NAME(m_CTL_pins)); + save_item(NAME(m_state)); + save_item(NAME(m_address)); + save_item(NAME(m_next_is_address)); + save_item(NAME(m_addr_bit)); + save_item(NAME(m_CTL_buffer)); } @@ -1649,7 +1658,7 @@ void tms5220_device::device_start() m_timer_io_ready = timer_alloc(0); - /* not during reset which is called frm within a write! */ + /* not during reset which is called from within a write! */ m_io_ready = 1; m_true_timing = 0; m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup @@ -1750,6 +1759,16 @@ void tms5220_device::device_reset() m_speechrom->read(1); m_schedule_dummy_read = FALSE; } + + // 5110 specific stuff + m_PDC = 0; + m_CTL_pins = 0; + m_state = 0; + m_address = 0; + m_next_is_address = FALSE; + m_addr_bit = 0; + m_CTL_buffer = 0; + } /********************************************************************************************** diff --git a/src/emu/addrmap.cpp b/src/emu/addrmap.cpp index 2ae44142ac1..b377fe73231 100644 --- a/src/emu/addrmap.cpp +++ b/src/emu/addrmap.cpp @@ -650,46 +650,50 @@ void address_map::map_validity_check(validity_checker &valid, const device_t &de osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig.m_name, datawidth, m_databits); // loop over entries and look for errors - for (address_map_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_entrylist) { - UINT32 bytestart = spaceconfig.addr2byte(entry->m_addrstart); - UINT32 byteend = spaceconfig.addr2byte_end(entry->m_addrend); + UINT32 bytestart = spaceconfig.addr2byte(entry.m_addrstart); + UINT32 byteend = spaceconfig.addr2byte_end(entry.m_addrend); // look for overlapping entries if (!detected_overlap) { - for (address_map_entry *scan = m_entrylist.first(); scan != entry; scan = scan->next()) - if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart && - ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) || - (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE))) + for (address_map_entry &scan : m_entrylist) + { + if (&scan == &entry) + break; + if (entry.m_addrstart <= scan.m_addrend && entry.m_addrend >= scan.m_addrstart && + ((entry.m_read.m_type != AMH_NONE && scan.m_read.m_type != AMH_NONE) || + (entry.m_write.m_type != AMH_NONE && scan.m_write.m_type != AMH_NONE))) { - osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); + osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_read.m_type, entry.m_write.m_type, scan.m_addrstart, scan.m_addrend, scan.m_read.m_type, scan.m_write.m_type); detected_overlap = true; break; } + } } // look for inverted start/end pairs if (byteend < bytestart) - osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend); + osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend); // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) - osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, alignunit); + osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, alignunit); // if this is a program space, auto-assign implicit ROM entries - if (entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr) + if (entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { - entry->m_region = device.tag(); - entry->m_rgnoffs = entry->m_addrstart; + entry.m_region = device.tag(); + entry.m_rgnoffs = entry.m_addrstart; } // if this entry references a memory region, validate it - if (entry->m_region != nullptr && entry->m_share == nullptr) + if (entry.m_region != nullptr && entry.m_share == nullptr) { // make sure we can resolve the full path to the region bool found = false; - std::string entry_region = entry->m_devbase.subtag(entry->m_region); + std::string entry_region = entry.m_devbase.subtag(entry.m_region); // look for the region device_iterator deviter(device.mconfig().root_device()); @@ -700,68 +704,68 @@ void address_map::map_validity_check(validity_checker &valid, const device_t &de { // verify the address range is within the region's bounds offs_t length = ROMREGION_GETLENGTH(romp); - if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) - osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); + if (entry.m_rgnoffs + (byteend - bytestart + 1) > length) + osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, length); found = true; } } // error if not found if (!found) - osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); + osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); } // make sure all devices exist - if (entry->m_read.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_read.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; - switch (entry->m_read.m_bits) + switch (entry.m_read.m_bits) { - case 8: devtag = entry->m_rproto8.device_name(); break; - case 16: devtag = entry->m_rproto16.device_name(); break; - case 32: devtag = entry->m_rproto32.device_name(); break; - case 64: devtag = entry->m_rproto64.device_name(); break; + case 8: devtag = entry.m_rproto8.device_name(); break; + case 16: devtag = entry.m_rproto16.device_name(); break; + case 32: devtag = entry.m_rproto32.device_name(); break; + case 64: devtag = entry.m_rproto64.device_name(); break; } - if (entry->m_devbase.subdevice(devtag) == nullptr) + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry reads from nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } - if (entry->m_write.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_write.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; - switch (entry->m_write.m_bits) + switch (entry.m_write.m_bits) { - case 8: devtag = entry->m_wproto8.device_name(); break; - case 16: devtag = entry->m_wproto16.device_name(); break; - case 32: devtag = entry->m_wproto32.device_name(); break; - case 64: devtag = entry->m_wproto64.device_name(); break; + case 8: devtag = entry.m_wproto8.device_name(); break; + case 16: devtag = entry.m_wproto16.device_name(); break; + case 32: devtag = entry.m_wproto32.device_name(); break; + case 64: devtag = entry.m_wproto64.device_name(); break; } - if (entry->m_devbase.subdevice(devtag) == nullptr) + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry writes to nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } - if (entry->m_setoffsethd.m_type == AMH_DEVICE_DELEGATE) + if (entry.m_setoffsethd.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate - const char *devtag = entry->m_soproto.device_name(); - if (entry->m_devbase.subdevice(devtag) == nullptr) + const char *devtag = entry.m_soproto.device_name(); + if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : ""); } // make sure ports exist -// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) || -// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL)) -// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig.m_name, entry->m_read.m_tag); +// if ((entry.m_read.m_type == AMH_PORT && entry.m_read.m_tag != NULL && portlist.find(entry.m_read.m_tag) == NULL) || +// (entry.m_write.m_type == AMH_PORT && entry.m_write.m_tag != NULL && portlist.find(entry.m_write.m_tag) == NULL)) +// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig.m_name, entry.m_read.m_tag); // validate bank and share tags - if (entry->m_read.m_type == AMH_BANK) - valid.validate_tag(entry->m_read.m_tag); - if (entry->m_write.m_type == AMH_BANK) - valid.validate_tag(entry->m_write.m_tag); - if (entry->m_share != nullptr) - valid.validate_tag(entry->m_share); + if (entry.m_read.m_type == AMH_BANK) + valid.validate_tag(entry.m_read.m_tag); + if (entry.m_write.m_type == AMH_BANK) + valid.validate_tag(entry.m_write.m_tag); + if (entry.m_share != nullptr) + valid.validate_tag(entry.m_share); } } diff --git a/src/emu/audit.cpp b/src/emu/audit.cpp index e9e4dee63f2..6797d967218 100644 --- a/src/emu/audit.cpp +++ b/src/emu/audit.cpp @@ -208,10 +208,10 @@ media_auditor::summary media_auditor::audit_software(const char *list_name, soft int required = 0; // now iterate over software parts - for ( software_part *part = swinfo->first_part(); part != nullptr; part = part->next() ) + for (software_part &part : swinfo->parts()) { // now iterate over regions - for ( const rom_entry *region = part->romdata(); region; region = rom_next_region( region ) ) + for ( const rom_entry *region = part.romdata(); region; region = rom_next_region( region ) ) { // now iterate over rom definitions for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) @@ -336,25 +336,25 @@ media_auditor::summary media_auditor::summarize(const char *name, std::string *o // loop over records summary overall_status = CORRECT; - for (audit_record *record = m_record_list.first(); record != nullptr; record = record->next()) + for (audit_record &record : m_record_list) { summary best_new_status = INCORRECT; // skip anything that's fine - if (record->substatus() == audit_record::SUBSTATUS_GOOD) + if (record.substatus() == audit_record::SUBSTATUS_GOOD) continue; // output the game name, file name, and length (if applicable) if (output != nullptr) { - output->append(string_format("%-12s: %s", name, record->name())); - if (record->expected_length() > 0) - output->append(string_format(" (%d bytes)", record->expected_length())); + output->append(string_format("%-12s: %s", name, record.name())); + if (record.expected_length() > 0) + output->append(string_format(" (%d bytes)", record.expected_length())); output->append(" - "); } // use the substatus for finer details - switch (record->substatus()) + switch (record.substatus()) { case audit_record::SUBSTATUS_GOOD_NEEDS_REDUMP: if (output != nullptr) output->append("NEEDS REDUMP\n"); @@ -370,19 +370,19 @@ media_auditor::summary media_auditor::summarize(const char *name, std::string *o if (output != nullptr) { output->append("INCORRECT CHECKSUM:\n"); - output->append(string_format("EXPECTED: %s\n", record->expected_hashes().macro_string().c_str())); - output->append(string_format(" FOUND: %s\n", record->actual_hashes().macro_string().c_str())); + output->append(string_format("EXPECTED: %s\n", record.expected_hashes().macro_string().c_str())); + output->append(string_format(" FOUND: %s\n", record.actual_hashes().macro_string().c_str())); } break; case audit_record::SUBSTATUS_FOUND_WRONG_LENGTH: - if (output != nullptr) output->append(string_format("INCORRECT LENGTH: %d bytes\n", record->actual_length())); + if (output != nullptr) output->append(string_format("INCORRECT LENGTH: %d bytes\n", record.actual_length())); break; case audit_record::SUBSTATUS_NOT_FOUND: if (output != nullptr) { - device_t *shared_device = record->shared_device(); + device_t *shared_device = record.shared_device(); if (shared_device == nullptr) output->append("NOT FOUND\n"); else diff --git a/src/emu/audit.h b/src/emu/audit.h index d39ecbb3a91..ed9e3a3fade 100644 --- a/src/emu/audit.h +++ b/src/emu/audit.h @@ -141,8 +141,7 @@ public: media_auditor(const driver_enumerator &enumerator); // getters - audit_record *first() const { return m_record_list.first(); } - int count() const { return m_record_list.count(); } + const simple_list &records() const { return m_record_list; } // audit operations summary audit_media(const char *validation = AUDIT_VALIDATE_FULL); diff --git a/src/emu/cheat.cpp b/src/emu/cheat.cpp index f9fe6499d61..fbd2b7f1479 100644 --- a/src/emu/cheat.cpp +++ b/src/emu/cheat.cpp @@ -181,10 +181,10 @@ const char *cheat_parameter::text() { // if not, we're an item cheat m_curtext = string_format("??? (%d)", UINT32(m_value)); - for (item *curitem = m_itemlist.first(); curitem != nullptr; curitem = curitem->next()) - if (curitem->value() == m_value) + for (item &curitem : m_itemlist) + if (curitem.value() == m_value) { - m_curtext.assign(curitem->text()); + m_curtext.assign(curitem.text()); break; } } @@ -216,8 +216,8 @@ void cheat_parameter::save(emu_file &cheatfile) const // iterate over items else { - for (const item *curitem = m_itemlist.first(); curitem != nullptr; curitem = curitem->next()) - cheatfile.printf("\t\t\t%s\n", curitem->value().format().c_str(), curitem->text()); + for (const item &curitem : m_itemlist) + cheatfile.printf("\t\t\t%s\n", curitem.value().format().c_str(), curitem.text()); cheatfile.printf("\t\t\n"); } } @@ -357,8 +357,8 @@ void cheat_script::execute(cheat_manager &manager, UINT64 &argindex) return; // iterate over entries - for (script_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) - entry->execute(manager, argindex); + for (script_entry &entry : m_entrylist) + entry.execute(manager, argindex); } @@ -381,8 +381,8 @@ void cheat_script::save(emu_file &cheatfile) const cheatfile.printf(">\n"); // output entries - for (const script_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next()) - entry->save(cheatfile); + for (const script_entry &entry : m_entrylist) + entry.save(cheatfile); // close the tag cheatfile.printf("\t\t\n"); @@ -499,8 +499,8 @@ void cheat_script::script_entry::execute(cheat_manager &manager, UINT64 &arginde // iterate over arguments and evaluate them UINT64 params[MAX_ARGUMENTS]; int curarg = 0; - for (output_argument *arg = m_arglist.first(); arg != nullptr; arg = arg->next()) - curarg += arg->values(argindex, ¶ms[curarg]); + for (output_argument &arg : m_arglist) + curarg += arg.values(argindex, ¶ms[curarg]); // generate the astring manager.get_output_astring(m_line, m_justify) = string_format(m_format, @@ -550,8 +550,8 @@ void cheat_script::script_entry::save(emu_file &cheatfile) const else { cheatfile.printf(">\n"); - for (const output_argument *curarg = m_arglist.first(); curarg != nullptr; curarg = curarg->next()) - curarg->save(cheatfile); + for (const output_argument &curarg : m_arglist) + curarg.save(cheatfile); cheatfile.printf("\t\t\t\n"); } } @@ -567,8 +567,8 @@ void cheat_script::script_entry::validate_format(const char *filename, int line) { // first count arguments int argsprovided = 0; - for (const output_argument *curarg = m_arglist.first(); curarg != nullptr; curarg = curarg->next()) - argsprovided += curarg->count(); + for (const output_argument &curarg : m_arglist) + argsprovided += curarg.count(); // now scan the string for valid argument usage const char *p = strchr(m_format.c_str(), '%'); @@ -1026,6 +1026,19 @@ std::unique_ptr &cheat_entry::script_for_state(script_state state) } +//------------------------------------------------- +// is_duplicate - determine if a new cheat entry +// is already included in the list +//------------------------------------------------- + +bool cheat_entry::is_duplicate() const +{ + for (cheat_entry &scannode : manager().entries()) + if (strcmp(scannode.description(), description()) == 0) + return true; + return false; +} + //************************************************************************** // CHEAT MANAGER @@ -1086,9 +1099,9 @@ void cheat_manager::set_enable(bool enable) if (!m_disabled && !enable) { // iterate over running cheats and execute any OFF Scripts - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - if (cheat->state() == SCRIPT_STATE_RUN) - cheat->execute_off_script(); + for (cheat_entry &cheat : m_cheatlist) + if (cheat.state() == SCRIPT_STATE_RUN) + cheat.execute_off_script(); machine().popmessage("Cheats Disabled"); m_disabled = true; } @@ -1098,9 +1111,9 @@ void cheat_manager::set_enable(bool enable) { // iterate over running cheats and execute any ON Scripts m_disabled = false; - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - if (cheat->state() == SCRIPT_STATE_RUN) - cheat->execute_on_script(); + for (cheat_entry &cheat : m_cheatlist) + if (cheat.state() == SCRIPT_STATE_RUN) + cheat.execute_on_script(); machine().popmessage("Cheats Enabled"); } } @@ -1186,8 +1199,8 @@ bool cheat_manager::save_all(const char *filename) cheatfile.printf("\n", CHEAT_VERSION); // iterate over cheats in the list and save them - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - cheat->save(cheatfile); + for (cheat_entry &cheat : m_cheatlist) + cheat.save(cheatfile); // close out the file cheatfile.printf("\n"); @@ -1345,8 +1358,8 @@ void cheat_manager::frame_update() elem.clear(); // iterate over running cheats and execute them - for (cheat_entry *cheat = m_cheatlist.first(); cheat != nullptr; cheat = cheat->next()) - cheat->frame_update(); + for (cheat_entry &cheat : m_cheatlist) + cheat.frame_update(); // increment the frame counter m_framecount++; @@ -1403,23 +1416,16 @@ void cheat_manager::load_cheats(const char *filename) for (xml_data_node *cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != nullptr; cheatnode = xml_get_sibling(cheatnode->next, "cheat")) { // load this entry - auto curcheat = global_alloc(cheat_entry(*this, m_symtable, filename, *cheatnode)); + cheat_entry *curcheat = global_alloc(cheat_entry(*this, m_symtable, filename, *cheatnode)); // make sure we're not a duplicate - cheat_entry *scannode = nullptr; - if (REMOVE_DUPLICATE_CHEATS) - for (scannode = m_cheatlist.first(); scannode != nullptr; scannode = scannode->next()) - if (strcmp(scannode->description(), curcheat->description()) == 0) - { - osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); - break; - } - - // add to the end of the list - if (scannode == nullptr) - m_cheatlist.append(*curcheat); - else + if (REMOVE_DUPLICATE_CHEATS && curcheat->is_duplicate()) + { + osd_printf_verbose("Ignoring duplicate cheat '%s' from file %s\n", curcheat->description(), cheatfile.fullpath()); global_free(curcheat); + } + else // add to the end of the list + m_cheatlist.append(*curcheat); } // free the file and loop for the next one diff --git a/src/emu/cheat.h b/src/emu/cheat.h index 20772e25640..dac90e17286 100644 --- a/src/emu/cheat.h +++ b/src/emu/cheat.h @@ -243,6 +243,7 @@ public: bool is_value_parameter() const { return (m_parameter != nullptr && !m_parameter->has_itemlist()); } bool is_itemlist_parameter() const { return (m_parameter != nullptr && m_parameter->has_itemlist()); } bool is_oneshot_parameter() const { return (m_parameter != nullptr && !has_run_script() && !has_off_script() && has_change_script()); } + bool is_duplicate() const; // actions bool activate(); @@ -294,7 +295,7 @@ public: // getters running_machine &machine() const { return m_machine; } bool enabled() const { return !m_disabled; } - cheat_entry *first() const { return m_cheatlist.first(); } + const simple_list &entries() const { return m_cheatlist; } // setters void set_enable(bool enable = true); diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp index 8889ab916a1..02c27149231 100644 --- a/src/emu/clifront.cpp +++ b/src/emu/clifront.cpp @@ -130,10 +130,10 @@ int cli_frontend::execute(int argc, char **argv) if (swinfo != nullptr) { // loop through all parts - for (software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (software_part &swpart : swinfo->parts()) { - const char *mount = swpart->feature("automount"); - if (swpart->is_compatible(*swlistdev)) + const char *mount = swpart.feature("automount"); + if (swpart.is_compatible(*swlistdev)) { if (mount == nullptr || strcmp(mount,"no") != 0) { @@ -144,17 +144,17 @@ int cli_frontend::execute(int argc, char **argv) const char *interface = image->image_interface(); if (interface != nullptr) { - if (swpart->matches_interface(interface)) + if (swpart.matches_interface(interface)) { const char *option = m_options.value(image->brief_instance_name()); // mount only if not already mounted if (*option == 0) { - std::string val = string_format("%s:%s:%s", swlistdev->list_name(), m_options.software_name(), swpart->name()); + std::string val = string_format("%s:%s:%s", swlistdev->list_name(), m_options.software_name(), swpart.name()); // call this in order to set slot devices according to mounting - m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.c_str(), swpart); + m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.c_str(), &swpart); break; } } @@ -661,16 +661,16 @@ void cli_frontend::listslots(const char *gamename) bool first_option = true; // get the options and print them - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option->selectable()) + if (option.selectable()) { - device_t *dev = (*option->devtype())(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); + device_t *dev = (*option.devtype())(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); dev->config_complete(); if (first_option) { - printf("%-15s %s\n", option->name(),dev->name()); + printf("%-15s %s\n", option.name(),dev->name()); } else { - printf("%-23s %-15s %s\n", "",option->name(),dev->name()); + printf("%-23s %-15s %s\n", "",option.name(),dev->name()); } global_free(dev); @@ -869,11 +869,11 @@ void cli_frontend::verifyroms(const char *gamename) slot_interface_iterator slotiter(config.root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != nullptr; slot = slotiter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(config).device_add(&config.root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); @@ -1175,36 +1175,36 @@ void cli_frontend::verifysamples(const char *gamename) void cli_frontend::output_single_softlist(FILE *out, software_list_device &swlistdev) { fprintf(out, "\t\n", swlistdev.list_name(), xml_normalize_string(swlistdev.description())); - for (software_info *swinfo = swlistdev.first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev.get_info()) { - fprintf( out, "\t\tshortname() ); - if ( swinfo->parentname() != nullptr ) - fprintf( out, " cloneof=\"%s\"", swinfo->parentname() ); - if ( swinfo->supported() == SOFTWARE_SUPPORTED_PARTIAL ) - fprintf( out, " supported=\"partial\"" ); - if ( swinfo->supported() == SOFTWARE_SUPPORTED_NO ) - fprintf( out, " supported=\"no\"" ); - fprintf( out, ">\n" ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string(swinfo->longname()) ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string( swinfo->year() ) ); - fprintf( out, "\t\t\t%s\n", xml_normalize_string( swinfo->publisher() ) ); + fprintf(out, "\t\t\n" ); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.longname())); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.year())); + fprintf(out, "\t\t\t%s\n", xml_normalize_string(swinfo.publisher())); - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - fprintf( out, "\t\t\t\n", flist->name(), xml_normalize_string( flist->value() ) ); + for (feature_list_item &flist : swinfo.other_info()) + fprintf( out, "\t\t\t\n", flist.name(), xml_normalize_string( flist.value() ) ); - for ( software_part *part = swinfo->first_part(); part != nullptr; part = part->next() ) + for (software_part &part : swinfo.parts()) { - fprintf( out, "\t\t\tname() ); - if ( part->interface() != nullptr ) - fprintf( out, " interface=\"%s\"", part->interface() ); + fprintf(out, "\t\t\t\n"); + fprintf(out, ">\n"); - for (feature_list_item *flist = part->featurelist(); flist != nullptr; flist = flist->next()) - fprintf( out, "\t\t\t\t\n", flist->name(), xml_normalize_string(flist->value()) ); + for (feature_list_item &flist : part.featurelist()) + fprintf(out, "\t\t\t\t\n", flist.name(), xml_normalize_string(flist.value())); /* TODO: display rom region information */ - for ( const rom_entry *region = part->romdata(); region; region = rom_next_region( region ) ) + for (const rom_entry *region = part.romdata(); region; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); @@ -1312,7 +1312,7 @@ void cli_frontend::listsoftware(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { if (isfirst) { fprintf(out, SOFTLIST_XML_BEGIN); isfirst = false; } output_single_softlist(out, *swlistdev); @@ -1356,12 +1356,12 @@ void cli_frontend::verifysoftware(const char *gamename) for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) if (list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { nrlists++; - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev->get_info()) { - media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), swinfo, AUDIT_VALIDATE_FAST); + media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), &swinfo, AUDIT_VALIDATE_FAST); // if not found, count that and leave it at that if (summary == media_auditor::NOTFOUND) @@ -1373,11 +1373,11 @@ void cli_frontend::verifysoftware(const char *gamename) { // output the summary of the audit std::string summary_string; - auditor.summarize(swinfo->shortname(), &summary_string); + auditor.summarize(swinfo.shortname(), &summary_string); osd_printf_info("%s", summary_string.c_str()); // display information about what we discovered - osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo->shortname()); + osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo.shortname()); // switch off of the result switch (summary) @@ -1443,7 +1443,7 @@ void cli_frontend::getsoftlist(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (core_strwildcmp(gamename, swlistdev->list_name()) == 0 && list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { if (isfirst) { fprintf( out, SOFTLIST_XML_BEGIN); isfirst = FALSE; } output_single_softlist(out, *swlistdev); @@ -1476,14 +1476,14 @@ void cli_frontend::verifysoftlist(const char *gamename) software_list_device_iterator iter(drivlist.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (core_strwildcmp(gamename, swlistdev->list_name()) == 0 && list_map.insert(swlistdev->list_name()).second) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { matched++; // Get the actual software list contents - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlistdev->get_info()) { - media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), swinfo, AUDIT_VALIDATE_FAST); + media_auditor::summary summary = auditor.audit_software(swlistdev->list_name(), &swinfo, AUDIT_VALIDATE_FAST); // if not found, count that and leave it at that if (summary == media_auditor::NOTFOUND) @@ -1495,11 +1495,11 @@ void cli_frontend::verifysoftlist(const char *gamename) { // output the summary of the audit std::string summary_string; - auditor.summarize(swinfo->shortname(), &summary_string); + auditor.summarize(swinfo.shortname(), &summary_string); osd_printf_info("%s", summary_string.c_str()); // display information about what we discovered - osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo->shortname()); + osd_printf_info("romset %s:%s ", swlistdev->list_name(), swinfo.shortname()); // switch off of the result switch (summary) @@ -1964,9 +1964,9 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) { if (listnames.insert(swlistdev->list_name()).second) { - for (software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - for (software_part *part = swinfo->first_part(); part != nullptr; part = part->next()) - for (const rom_entry *region = part->romdata(); region != nullptr; region = rom_next_region(region)) + for (software_info &swinfo : swlistdev->get_info()) + for (software_part &part : swinfo.parts()) + for (const rom_entry *region = part.romdata(); region != nullptr; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) { hash_collection romhashes(ROM_GETHASHDATA(rom)); @@ -1977,7 +1977,7 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) // output information about the match if (found) osd_printf_info(" "); - osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev->list_name(), swinfo->shortname(), swinfo->longname()); + osd_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlistdev->list_name(), swinfo.shortname(), swinfo.longname()); found++; } } diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp index a4bee628ae9..28d5cced1ce 100644 --- a/src/emu/crsshair.cpp +++ b/src/emu/crsshair.cpp @@ -113,11 +113,11 @@ crosshair_manager::crosshair_manager(running_machine &machine) m_auto_time = CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT; /* determine who needs crosshairs */ - for (ioport_port *port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->crosshair_axis() != CROSSHAIR_AXIS_NONE) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE) { - int player = field->player(); + int player = field.player(); assert(player < MAX_PLAYERS); diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 2e10b40356e..cd16bd4e691 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -1935,7 +1935,6 @@ static void execute_cheatinit(running_machine &machine, int ref, int params, con UINT64 curaddr; UINT8 i, region_count = 0; - address_map_entry *entry; cheat_region_map cheat_region[100]; memset(cheat_region, 0, sizeof(cheat_region)); @@ -1987,18 +1986,18 @@ static void execute_cheatinit(running_machine &machine, int ref, int params, con /* initialize entire memory by default */ if (params <= 1) { - for (entry = space->map()->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : space->map()->m_entrylist) { - cheat_region[region_count].offset = space->address_to_byte(entry->m_addrstart) & space->bytemask(); - cheat_region[region_count].endoffset = space->address_to_byte(entry->m_addrend) & space->bytemask(); - cheat_region[region_count].share = entry->m_share; - cheat_region[region_count].disabled = (entry->m_write.m_type == AMH_RAM) ? FALSE : TRUE; + cheat_region[region_count].offset = space->address_to_byte(entry.m_addrstart) & space->bytemask(); + cheat_region[region_count].endoffset = space->address_to_byte(entry.m_addrend) & space->bytemask(); + cheat_region[region_count].share = entry.m_share; + cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? FALSE : TRUE; /* disable double share regions */ - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) for (i = 0; i < region_count; i++) if (cheat_region[i].share != nullptr) - if (strcmp(cheat_region[i].share, entry->m_share) == 0) + if (strcmp(cheat_region[i].share, entry.m_share) == 0) cheat_region[region_count].disabled = TRUE; region_count++; @@ -2979,12 +2978,12 @@ static void execute_symlist(running_machine &machine, int ref, int params, const } /* gather names for all symbols */ - for (symbol_entry *entry = symtable->first(); entry != nullptr; entry = entry->next()) + for (symbol_entry &entry : symtable->entries()) { /* only display "register" type symbols */ - if (!entry->is_function()) + if (!entry.is_function()) { - namelist[count++] = entry->name(); + namelist[count++] = entry.name(); if (count >= ARRAY_LENGTH(namelist)) break; } diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 4e59ed8a652..7e352e7dbe8 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -1666,9 +1666,10 @@ device_debug::device_debug(device_t &device) // add all registers into it std::string tempstr; - for (const device_state_entry *entry = m_state->state_first(); entry != nullptr; entry = entry->next()) { - strmakelower(tempstr.assign(entry->symbol())); - m_symtable.add(tempstr.c_str(), (void *)(FPTR)entry->index(), get_state, set_state); + for (const device_state_entry &entry : m_state->state_entries()) + { + strmakelower(tempstr.assign(entry.symbol())); + m_symtable.add(tempstr.c_str(), (void *)(FPTR)entry.index(), get_state, set_state); } } diff --git a/src/emu/debug/debugvw.cpp b/src/emu/debug/debugvw.cpp index 641a31b41f0..135ac5fb76e 100644 --- a/src/emu/debug/debugvw.cpp +++ b/src/emu/debug/debugvw.cpp @@ -231,9 +231,9 @@ void debug_view::set_source(const debug_view_source &source) const debug_view_source *debug_view::source_for_device(device_t *device) const { - for (debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) - if (device == source->device()) - return source; + for (debug_view_source &source : m_source_list) + if (device == source.device()) + return &source; return m_source_list.first(); } diff --git a/src/emu/debug/debugvw.h b/src/emu/debug/debugvw.h index ab4c986172e..cb1852aed2c 100644 --- a/src/emu/debug/debugvw.h +++ b/src/emu/debug/debugvw.h @@ -156,7 +156,7 @@ public: bool cursor_supported() { flush_updates(); return m_supports_cursor; } bool cursor_visible() { flush_updates(); return m_cursor_visible; } const debug_view_source *source() const { return m_source; } - const debug_view_source *first_source() { return m_source_list.first(); } + const debug_view_source *first_source() const { return m_source_list.first(); } const simple_list &source_list() const { return m_source_list; } // setters diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp index 89b98e106d0..4e3f6f71bae 100644 --- a/src/emu/debug/dvbpoints.cpp +++ b/src/emu/debug/dvbpoints.cpp @@ -201,10 +201,10 @@ void debug_view_breakpoints::pad_ostream_to_length(std::ostream& str, int len) void debug_view_breakpoints::gather_breakpoints() { m_buffer.resize(0); - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { // Collect - device_debug &debugInterface = *source->device()->debug(); + device_debug &debugInterface = *source.device()->debug(); for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != nullptr; bp = bp->next()) m_buffer.push_back(bp); } diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp index 10cb3e75e64..027e50b6f2a 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -66,9 +66,9 @@ debug_view_disasm::debug_view_disasm(running_machine &machine, debug_view_osd_up // count the number of comments int total_comments = 0; - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { - const debug_view_disasm_source &dasmsource = downcast(*source); + const debug_view_disasm_source &dasmsource = downcast(source); total_comments += dasmsource.m_device.debug()->comment_count(); } diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index c39372af5b3..8efaa22ef9a 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -147,10 +147,10 @@ void debug_view_memory::enumerate_sources() } // then add all the memory regions - for (memory_region *region = machine().memory().first_region(); region != nullptr; region = region->next()) + for (memory_region ®ion : machine().memory().regions()) { - name = string_format("Region '%s'", region->name()); - m_source_list.append(*global_alloc(debug_view_memory_source(name.c_str(), *region))); + name = string_format("Region '%s'", region.name()); + m_source_list.append(*global_alloc(debug_view_memory_source(name.c_str(), region))); } // finally add all global array symbols diff --git a/src/emu/debug/dvstate.cpp b/src/emu/debug/dvstate.cpp index 8e1fe7513fd..773aa1fc3ee 100644 --- a/src/emu/debug/dvstate.cpp +++ b/src/emu/debug/dvstate.cpp @@ -141,15 +141,15 @@ void debug_view_state::recompute() tailptr = &(*tailptr)->m_next; // add all registers into it - for (const device_state_entry *entry = source.m_stateintf->state_first(); entry != nullptr; entry = entry->next()) - if (entry->divider()) + for (const device_state_entry &entry : source.m_stateintf->state_entries()) + if (entry.divider()) { *tailptr = global_alloc(state_item(REG_DIVIDER, "", 0)); tailptr = &(*tailptr)->m_next; } - else if (entry->visible()) + else if (entry.visible()) { - *tailptr = global_alloc(state_item(entry->index(), entry->symbol(), source.m_stateintf->state_string_max_length(entry->index()))); + *tailptr = global_alloc(state_item(entry.index(), entry.symbol(), source.m_stateintf->state_string_max_length(entry.index()))); tailptr = &(*tailptr)->m_next; } diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp index 0e84726a7aa..17582796c39 100644 --- a/src/emu/debug/dvwpoints.cpp +++ b/src/emu/debug/dvwpoints.cpp @@ -224,10 +224,10 @@ void debug_view_watchpoints::pad_ostream_to_length(std::ostream& str, int len) void debug_view_watchpoints::gather_watchpoints() { m_buffer.resize(0); - for (const debug_view_source *source = m_source_list.first(); source != nullptr; source = source->next()) + for (const debug_view_source &source : m_source_list) { // Collect - device_debug &debugInterface = *source->device()->debug(); + device_debug &debugInterface = *source.device()->debug(); for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum) { for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != nullptr; wp = wp->next()) diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index 62324092a28..7a9ed4697ae 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -1395,17 +1395,17 @@ UINT64 parsed_expression::execute_tokens() // loop over the entire sequence parse_token t1, t2, result; - for (parse_token *token = m_tokenlist.first(); token != nullptr; token = token->next()) + for (parse_token &token : m_tokenlist) { // symbols/numbers/strings just get pushed - if (!token->is_operator()) + if (!token.is_operator()) { - push_token(*token); + push_token(token); continue; } // otherwise, switch off the operator - switch (token->optype()) + switch (token.optype()) { case TVL_PREINCREMENT: pop_token_lval(t1); @@ -1616,7 +1616,7 @@ UINT64 parsed_expression::execute_tokens() break; case TVL_COMMA: - if (!token->is_function_separator()) + if (!token.is_function_separator()) { pop_token_rval(t2); pop_token_rval(t1); push_token(t2); @@ -1625,15 +1625,15 @@ UINT64 parsed_expression::execute_tokens() case TVL_MEMORYAT: pop_token_rval(t1); - push_token(result.configure_memory(t1.value(), *token)); + push_token(result.configure_memory(t1.value(), token)); break; case TVL_EXECUTEFUNC: - execute_function(*token); + execute_function(token); break; default: - throw expression_error(expression_error::SYNTAX, token->offset()); + throw expression_error(expression_error::SYNTAX, token.offset()); } } diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index fad3e478cf8..bbbac044691 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -169,7 +169,7 @@ public: symbol_table(void *globalref, symbol_table *parent = nullptr); // getters - symbol_entry *first() const { return m_symlist.first(); } + const tagged_list &entries() const { return m_symlist; } symbol_table *parent() const { return m_parent; } void *globalref() const { return m_globalref; } diff --git a/src/emu/device.cpp b/src/emu/device.cpp index e6bfa46f051..59e4162314c 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -33,11 +33,6 @@ device_t::device_t(const machine_config &mconfig, device_type type, const char * m_owner(owner), m_next(nullptr), - m_interface_list(nullptr), - m_execute(nullptr), - m_memory(nullptr), - m_state(nullptr), - m_configured_clock(clock), m_unscaled_clock(clock), m_clock(clock), @@ -79,13 +74,10 @@ device_t::~device_t() // info for a given region //------------------------------------------------- -// NOTE: this being NULL in a C++ member function can lead to undefined behavior. -// However, it is relied on throughout MAME, so will remain for now. - memory_region *device_t::memregion(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().region(subtag(_tag).c_str()); + return machine().memory().regions().find(subtag(_tag).c_str()); } @@ -97,7 +89,7 @@ memory_region *device_t::memregion(const char *_tag) const memory_share *device_t::memshare(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().shared(subtag(_tag).c_str()); + return machine().memory().shares().find(subtag(_tag).c_str()); } @@ -109,7 +101,7 @@ memory_share *device_t::memshare(const char *_tag) const memory_bank *device_t::membank(const char *_tag) const { // build a fully-qualified name and look it up - return machine().memory().bank(subtag(_tag).c_str()); + return machine().memory().banks().find(subtag(_tag).c_str()); } @@ -164,8 +156,8 @@ void device_t::static_set_clock(device_t &device, UINT32 clock) void device_t::config_complete() { // first notify the interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_config_complete(); + for (device_interface &intf : interfaces()) + intf.interface_config_complete(); // then notify the device itself device_config_complete(); @@ -183,8 +175,8 @@ void device_t::config_complete() void device_t::validity_check(validity_checker &valid) const { // validate via the interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_validity_check(valid); + for (device_interface &intf : interfaces()) + intf.interface_validity_check(valid); // let the device itself validate device_validity_check(valid); @@ -198,22 +190,22 @@ void device_t::validity_check(validity_checker &valid) const void device_t::reset() { // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_reset(); + for (device_interface &intf : interfaces()) + intf.interface_pre_reset(); // reset the device device_reset(); // reset all child devices - for (device_t *child = m_subdevice_list.first(); child != nullptr; child = child->next()) - child->reset(); + for (device_t &child : subdevices()) + child.reset(); // now allow for some post-child reset action device_reset_after_children(); // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_reset(); + for (device_interface &intf : interfaces()) + intf.interface_post_reset(); } @@ -334,8 +326,8 @@ void device_t::start() throw emu_fatalerror("Missing some required objects, unable to proceed"); // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_start(); + for (device_interface &intf : interfaces()) + intf.interface_pre_start(); // remember the number of state registrations int state_registrations = machine().save().registration_count(); @@ -355,8 +347,8 @@ void device_t::start() } // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_start(); + for (device_interface &intf : interfaces()) + intf.interface_post_start(); // force an update of the clock notify_clock_changed(); @@ -385,15 +377,15 @@ void device_t::start() void device_t::stop() { // let the interfaces do their pre-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_stop(); + for (device_interface &intf : interfaces()) + intf.interface_pre_stop(); // stop the device device_stop(); // let the interfaces do their post-work - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_stop(); + for (device_interface &intf : interfaces()) + intf.interface_post_stop(); // free any debugging info m_debug.reset(); @@ -411,8 +403,8 @@ void device_t::stop() void device_t::debug_setup() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_debug_setup(); + for (device_interface &intf : interfaces()) + intf.interface_debug_setup(); // notify the device device_debug_setup(); @@ -427,8 +419,8 @@ void device_t::debug_setup() void device_t::pre_save() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_pre_save(); + for (device_interface &intf : interfaces()) + intf.interface_pre_save(); // notify the device device_pre_save(); @@ -443,8 +435,8 @@ void device_t::pre_save() void device_t::post_load() { // notify the interface - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_post_load(); + for (device_interface &intf : interfaces()) + intf.interface_post_load(); // notify the device device_post_load(); @@ -459,8 +451,8 @@ void device_t::post_load() void device_t::notify_clock_changed() { // first notify interfaces - for (device_interface *intf = m_interface_list; intf != nullptr; intf = intf->interface_next()) - intf->interface_clock_changed(); + for (device_interface &intf : interfaces()) + intf.interface_clock_changed(); // then notify the device device_clock_changed(); @@ -643,14 +635,12 @@ device_t *device_t::subdevice_slow(const char *tag) const for (int start = 1, end = fulltag.find_first_of(':', start); start != 0 && curdevice != nullptr; start = end + 1, end = fulltag.find_first_of(':', start)) { std::string part(fulltag, start, (end == -1) ? -1 : end - start); - for (curdevice = curdevice->m_subdevice_list.first(); curdevice != nullptr; curdevice = curdevice->next()) - if (part.compare(curdevice->m_basetag)==0) - break; + curdevice = curdevice->subdevices().find(part); } // if we got a match, add to the fast map if (curdevice != nullptr) - m_device_map.insert(std::make_pair(tag, curdevice)); + m_subdevices.m_tagmap.insert(std::make_pair(tag, curdevice)); return curdevice; } @@ -711,65 +701,6 @@ std::string device_t::subtag(const char *tag) const } -//------------------------------------------------- -// add_subdevice - create a new device and add it -// as a subdevice -//------------------------------------------------- - -device_t *device_t::add_subdevice(device_type type, const char *tag, UINT32 clock) -{ - // allocate the device and append to our list - device_t *device = (*type)(mconfig(), tag, this, clock); - m_subdevice_list.append(*device); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = device->machine_config_additions(); - if (additions != nullptr) - (*additions)(const_cast(mconfig()), device, nullptr); - return device; -} - - -//------------------------------------------------- -// add_subdevice - create a new device and use it -// to replace an existing subdevice -//------------------------------------------------- - -device_t *device_t::replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock) -{ - // iterate over all devices and remove any references to the old device - device_iterator iter(mconfig().root_device()); - for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) - scan->m_device_map.clear(); //remove(&old); - - // create a new device, and substitute it for the old one - device_t *device = (*type)(mconfig(), tag, this, clock); - m_subdevice_list.replace_and_remove(*device, old); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = device->machine_config_additions(); - if (additions != nullptr) - (*additions)(const_cast(mconfig()), device, nullptr); - return device; -} - - -//------------------------------------------------- -// remove_subdevice - remove a given subdevice -//------------------------------------------------- - -void device_t::remove_subdevice(device_t &device) -{ - // iterate over all devices and remove any references - device_iterator iter(mconfig().root_device()); - for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) - scan->m_device_map.clear(); //remove(&device); - - // remove from our list - m_subdevice_list.remove(device); -} - - //------------------------------------------------- // register_auto_finder - add a new item to the // list of stuff to find after we go live @@ -797,7 +728,7 @@ device_interface::device_interface(device_t &device, const char *type) m_type(type) { device_interface **tailptr; - for (tailptr = &device.m_interface_list; *tailptr != nullptr; tailptr = &(*tailptr)->m_interface_next) { } + for (tailptr = &device.interfaces().m_head; *tailptr != nullptr; tailptr = &(*tailptr)->m_interface_next) { } *tailptr = this; } diff --git a/src/emu/device.h b/src/emu/device.h index bf04b26d956..9681e43943c 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -93,16 +93,85 @@ class device_t : public delegate_late_bind { DISABLE_COPYING(device_t); - friend class device_interface; - friend class device_memory_interface; - friend class device_state_interface; - friend class device_execute_interface; friend class simple_list; - friend class device_list; - friend class machine_config; friend class running_machine; friend class finder_base; + class subdevice_list + { + friend class device_t; + friend class machine_config; + +public: + // construction/destruction + subdevice_list() { } + + // getters + device_t *first() const { return m_list.first(); } + + // range iterators + using auto_iterator = simple_list::auto_iterator; + auto_iterator begin() const { return m_list.begin(); } + auto_iterator end() const { return m_list.end(); } + +private: + // private helpers + device_t *find(const std::string &name) const + { + device_t *curdevice; + for (curdevice = m_list.first(); curdevice != nullptr; curdevice = curdevice->next()) + if (name.compare(curdevice->m_basetag) == 0) + return curdevice; + return nullptr; + } + + // private state + simple_list m_list; // list of sub-devices we own + mutable std::unordered_map m_tagmap; // map of devices looked up and found by subtag + }; + + class interface_list + { + friend class device_t; + friend class device_interface; + friend class device_memory_interface; + friend class device_state_interface; + friend class device_execute_interface; + +public: + class auto_iterator + { +public: + // construction/destruction + auto_iterator(device_interface *intf) : m_current(intf) { } + + // required operator overrides + bool operator!=(const auto_iterator &iter) const { return m_current != iter.m_current; } + device_interface &operator*() const { return *m_current; } + const auto_iterator &operator++(); + +private: + // private state + device_interface *m_current; + }; + + // construction/destruction + interface_list() : m_head(nullptr), m_execute(nullptr), m_memory(nullptr), m_state(nullptr) { } + + // getters + device_interface *first() const { return m_head; } + + // range iterators + auto_iterator begin() const { return auto_iterator(m_head); } + auto_iterator end() const { return auto_iterator(nullptr); } + +private: + device_interface * m_head; // head of interface list + device_execute_interface *m_execute; // pre-cached pointer to execute interface + device_memory_interface *m_memory; // pre-cached pointer to memory interface + device_state_interface *m_state; // pre-cached pointer to state interface + }; + protected: // construction/destruction device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); @@ -130,26 +199,30 @@ public: UINT8 default_bios() const { return m_default_bios; } UINT8 system_bios() const { return m_system_bios; } std::string default_bios_tag() const { return m_default_bios_tag; } - std::string parameter(const char *tag) const; + memory_region *region() const { return m_region; } // interface helpers - device_interface *first_interface() const { return m_interface_list; } + interface_list &interfaces() { return m_interfaces; } + const interface_list &interfaces() const { return m_interfaces; } template bool interface(_DeviceClass *&intf) { intf = dynamic_cast<_DeviceClass *>(this); return (intf != nullptr); } template bool interface(_DeviceClass *&intf) const { intf = dynamic_cast(this); return (intf != nullptr); } // specialized helpers for common core interfaces - bool interface(device_execute_interface *&intf) { intf = m_execute; return (intf != nullptr); } - bool interface(device_execute_interface *&intf) const { intf = m_execute; return (intf != nullptr); } - bool interface(device_memory_interface *&intf) { intf = m_memory; return (intf != nullptr); } - bool interface(device_memory_interface *&intf) const { intf = m_memory; return (intf != nullptr); } - bool interface(device_state_interface *&intf) { intf = m_state; return (intf != nullptr); } - bool interface(device_state_interface *&intf) const { intf = m_state; return (intf != nullptr); } - device_execute_interface &execute() const { assert(m_execute != nullptr); return *m_execute; } - device_memory_interface &memory() const { assert(m_memory != nullptr); return *m_memory; } - device_state_interface &state() const { assert(m_state != nullptr); return *m_state; } + bool interface(device_execute_interface *&intf) { intf = m_interfaces.m_execute; return (intf != nullptr); } + bool interface(device_execute_interface *&intf) const { intf = m_interfaces.m_execute; return (intf != nullptr); } + bool interface(device_memory_interface *&intf) { intf = m_interfaces.m_memory; return (intf != nullptr); } + bool interface(device_memory_interface *&intf) const { intf = m_interfaces.m_memory; return (intf != nullptr); } + bool interface(device_state_interface *&intf) { intf = m_interfaces.m_state; return (intf != nullptr); } + bool interface(device_state_interface *&intf) const { intf = m_interfaces.m_state; return (intf != nullptr); } + device_execute_interface &execute() const { assert(m_interfaces.m_execute != nullptr); return *m_interfaces.m_execute; } + device_memory_interface &memory() const { assert(m_interfaces.m_memory != nullptr); return *m_interfaces.m_memory; } + device_state_interface &state() const { assert(m_interfaces.m_state != nullptr); return *m_interfaces.m_state; } // owned object helpers - device_t *first_subdevice() const { return m_subdevice_list.first(); } + subdevice_list &subdevices() { return m_subdevices; } + const subdevice_list &subdevices() const { return m_subdevices; } + + // device-relative tag lookups std::string subtag(const char *tag) const; std::string siblingtag(const char *tag) const { return (m_owner != nullptr) ? m_owner->subtag(tag) : std::string(tag); } memory_region *memregion(const char *tag) const; @@ -160,7 +233,7 @@ public: device_t *siblingdevice(const char *tag) const; template inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); } template inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); } - memory_region *region() const { return m_region; } + std::string parameter(const char *tag) const; // configuration helpers static void static_set_clock(device_t &device, UINT32 clock); @@ -247,17 +320,11 @@ protected: std::string m_searchpath; // search path, used for media loading std::string m_source; // device source file name - // device relationships + // device relationships & interfaces device_t * m_owner; // device that owns us device_t * m_next; // next device by the same owner (of any type/class) - simple_list m_subdevice_list; // list of sub-devices we own - mutable std::unordered_map m_device_map; // map of device names looked up and found - - // device interfaces - device_interface * m_interface_list; // head of interface list - device_execute_interface *m_execute; // pre-cached pointer to execute interface - device_memory_interface *m_memory; // pre-cached pointer to memory interface - device_state_interface *m_state; // pre-cached pointer to state interface + subdevice_list m_subdevices; // container for list of subdevices + interface_list m_interfaces; // container for list of interfaces // device clocks UINT32 m_configured_clock; // originally configured device clock @@ -277,10 +344,7 @@ protected: std::string m_default_bios_tag; // tag of the default system BIOS private: - // private helpers - device_t *add_subdevice(device_type type, const char *tag, UINT32 clock); - device_t *replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock); - void remove_subdevice(device_t &device); + // internal helpers device_t *subdevice_slow(const char *tag) const; // private state; accessor use required @@ -317,7 +381,6 @@ public: // iteration helpers device_interface *interface_next() const { return m_interface_next; } - template bool next(_InterfaceClass *&intf) const { return m_device.next(intf); } // optional operation overrides // @@ -379,7 +442,7 @@ public: // search down first if (m_curdepth < m_maxdepth) { - m_current = start->first_subdevice(); + m_current = start->subdevices().first(); if (m_current != nullptr) { m_curdepth++; @@ -593,8 +656,8 @@ inline device_t *device_t::subdevice(const char *tag) const return const_cast(this); // do a quick lookup and return that if possible - auto quick = m_device_map.find(tag); - return (quick != m_device_map.end()) ? quick->second : subdevice_slow(tag); + auto quick = m_subdevices.m_tagmap.find(tag); + return (quick != m_subdevices.m_tagmap.end()) ? quick->second : subdevice_slow(tag); } @@ -620,4 +683,13 @@ inline device_t *device_t::siblingdevice(const char *tag) const return (tag[0] == ':') ? subdevice(tag) : nullptr; } + +// this operator requires device_interface to be a complete type +inline const device_t::interface_list::auto_iterator &device_t::interface_list::auto_iterator::operator++() +{ + m_current = m_current->interface_next(); + return *this; +} + + #endif /* __DEVICE_H__ */ diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index 02684095b04..fb3011bc59f 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -67,7 +67,7 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig memset(&m_localtime, 0, sizeof(m_localtime)); // configure the fast accessor - device.m_execute = this; + device.interfaces().m_execute = this; } diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index f225f6cd444..f20c9b7733d 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -199,9 +199,9 @@ image_error_t device_image_interface::set_image_filename(const char *filename) const image_device_format *device_image_interface::device_get_named_creatable_format(const char *format_name) { - for (const image_device_format *format = m_formatlist.first(); format != nullptr; format = format->next()) - if (strcmp(format->name(), format_name) == 0) - return format; + for (const image_device_format &format : m_formatlist) + if (strcmp(format.name(), format_name) == 0) + return &format; return nullptr; } diff --git a/src/emu/diimage.h b/src/emu/diimage.h index f15e0e555a9..248db9cbbd2 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -228,7 +228,7 @@ public: const char *instance_name() const { return m_instance_name.c_str(); } const char *brief_instance_name() const { return m_brief_instance_name.c_str(); } bool uses_file_extension(const char *file_extension) const; - image_device_format *formatlist() const { return m_formatlist.first(); } + const simple_list &formatlist() const { return m_formatlist; } bool load(const char *path); bool open_image_file(emu_options &options); diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index dbe3647ec01..56543ae551a 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -127,7 +127,7 @@ device_memory_interface::device_memory_interface(const machine_config &mconfig, memset(m_addrspace, 0, sizeof(m_addrspace)); // configure the fast accessor - device.m_memory = this; + device.interfaces().m_memory = this; } diff --git a/src/emu/dislot.h b/src/emu/dislot.h index 573d8fa2221..7aaf28d004d 100644 --- a/src/emu/dislot.h +++ b/src/emu/dislot.h @@ -114,7 +114,7 @@ public: static void static_set_option_clock(device_t &device, const char *option, UINT32 default_clock) { static_option(device, option)->m_clock = default_clock; } bool fixed() const { return m_fixed; } const char *default_option() const { return m_default_option; } - device_slot_option *first_option() const { return m_options.first(); } + const tagged_list &option_list() const { return m_options; } device_slot_option *option(const char *name) const { if (name) return m_options.find(name); return nullptr; } virtual std::string get_default_card_software() { return std::string(); } device_t *get_card_device(); diff --git a/src/emu/disound.cpp b/src/emu/disound.cpp index 7134b588963..1a3544b5d60 100644 --- a/src/emu/disound.cpp +++ b/src/emu/disound.cpp @@ -91,9 +91,9 @@ int device_sound_interface::inputs() const { // scan the list counting streams we own and summing their inputs int inputs = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) - inputs += stream->input_count(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) + inputs += stream.input_count(); return inputs; } @@ -107,9 +107,9 @@ int device_sound_interface::outputs() const { // scan the list counting streams we own and summing their outputs int outputs = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) - outputs += stream->output_count(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) + outputs += stream.output_count(); return outputs; } @@ -125,15 +125,15 @@ sound_stream *device_sound_interface::input_to_stream_input(int inputnum, int &s assert(inputnum >= 0); // scan the list looking for streams owned by this device - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &m_device) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &m_device) { - if (inputnum < stream->input_count()) + if (inputnum < stream.input_count()) { stream_inputnum = inputnum; - return stream; + return &stream; } - inputnum -= stream->input_count(); + inputnum -= stream.input_count(); } // not found @@ -152,15 +152,15 @@ sound_stream *device_sound_interface::output_to_stream_output(int outputnum, int assert(outputnum >= 0); // scan the list looking for streams owned by this device - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) { - if (outputnum < stream->output_count()) + if (outputnum < stream.output_count()) { stream_outputnum = outputnum; - return stream; + return &stream; } - outputnum -= stream->output_count(); + outputnum -= stream.output_count(); } // not found @@ -192,10 +192,10 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) // handle ALL_OUTPUTS as a special case if (outputnum == ALL_OUTPUTS) { - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - for (int num = 0; num < stream->output_count(); num++) - stream->set_output_gain(num, gain); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + for (int num = 0; num < stream.output_count(); num++) + stream.set_output_gain(num, gain); } // look up the stream and stream output index @@ -217,10 +217,10 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) int device_sound_interface::inputnum_from_device(device_t &source_device, int outputnum) const { int overall = 0; - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - for (int inputnum = 0; inputnum < stream->input_count(); inputnum++, overall++) - if (stream->input_source_device(inputnum) == &source_device && stream->input_source_outputnum(inputnum) == outputnum) + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + for (int inputnum = 0; inputnum < stream.input_count(); inputnum++, overall++) + if (stream.input_source_device(inputnum) == &source_device && stream.input_source_outputnum(inputnum) == outputnum) return overall; return -1; } @@ -235,17 +235,17 @@ int device_sound_interface::inputnum_from_device(device_t &source_device, int ou void device_sound_interface::interface_validity_check(validity_checker &valid) const { // loop over all the routes - for (const sound_route *route = first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : routes()) { // find a device with the requested tag - const device_t *target = device().siblingdevice(route->m_target.c_str()); + const device_t *target = device().siblingdevice(route.m_target.c_str()); if (target == nullptr) - osd_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.c_str()); + osd_printf_error("Attempting to route sound to non-existant device '%s'\n", route.m_target.c_str()); // if it's not a speaker or a sound device, error const device_sound_interface *sound; if (target != nullptr && target->type() != SPEAKER && !target->interface(sound)) - osd_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route->m_target.c_str(), target->name()); + osd_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route.m_target.c_str(), target->name()); } } @@ -262,10 +262,10 @@ void device_sound_interface::interface_pre_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // see if we are the target of this route; if we are, make sure the source device is started - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); if (target_device == &m_device && !sound->device().started()) throw device_missing_dependencies(); } @@ -276,14 +276,14 @@ void device_sound_interface::interface_pre_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (sound_route &route : sound->routes()) { // see if we are the target of this route - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); - if (target_device == &m_device && route->m_input == AUTO_ALLOC_INPUT) + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); + if (target_device == &m_device && route.m_input == AUTO_ALLOC_INPUT) { - const_cast(route)->m_input = m_auto_allocated_inputs; - m_auto_allocated_inputs += (route->m_output == ALL_OUTPUTS) ? sound->outputs() : 1; + route.m_input = m_auto_allocated_inputs; + m_auto_allocated_inputs += (route.m_output == ALL_OUTPUTS) ? sound->outputs() : 1; } } } @@ -302,32 +302,32 @@ void device_sound_interface::interface_post_start() for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) { // scan each route on the device - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // if we are the target of this route, hook it up - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); if (target_device == &m_device) { // iterate over all outputs, matching any that apply - int inputnum = route->m_input; + int inputnum = route.m_input; int numoutputs = sound->outputs(); for (int outputnum = 0; outputnum < numoutputs; outputnum++) - if (route->m_output == outputnum || route->m_output == ALL_OUTPUTS) + if (route.m_output == outputnum || route.m_output == ALL_OUTPUTS) { // find the output stream to connect from int streamoutputnum; sound_stream *outputstream = sound->output_to_stream_output(outputnum, streamoutputnum); if (outputstream == nullptr) - fatalerror("Sound device '%s' specifies route for non-existant output #%d\n", route->m_target.c_str(), outputnum); + fatalerror("Sound device '%s' specifies route for non-existant output #%d\n", route.m_target.c_str(), outputnum); // find the input stream to connect to int streaminputnum; sound_stream *inputstream = input_to_stream_input(inputnum++, streaminputnum); if (inputstream == nullptr) - fatalerror("Sound device '%s' targeted output #%d to non-existant device '%s' input %d\n", route->m_target.c_str(), outputnum, m_device.tag(), inputnum - 1); + fatalerror("Sound device '%s' targeted output #%d to non-existant device '%s' input %d\n", route.m_target.c_str(), outputnum, m_device.tag(), inputnum - 1); // set the input - inputstream->set_input(streaminputnum, outputstream, streamoutputnum, route->m_gain); + inputstream->set_input(streaminputnum, outputstream, streamoutputnum, route.m_gain); } } } @@ -343,9 +343,9 @@ void device_sound_interface::interface_post_start() void device_sound_interface::interface_pre_reset() { // update all streams on this device prior to reset - for (sound_stream *stream = m_device.machine().sound().first_stream(); stream != nullptr; stream = stream->next()) - if (&stream->device() == &device()) - stream->update(); + for (sound_stream &stream : m_device.machine().sound().streams()) + if (&stream.device() == &device()) + stream.update(); } @@ -418,15 +418,15 @@ void device_mixer_interface::interface_pre_start() // iterate through all routes that point to us and note their mixer output sound_interface_iterator iter(m_device.machine().root_device()); for (device_sound_interface *sound = iter.first(); sound != nullptr; sound = iter.next()) - for (const sound_route *route = sound->first_route(); route != nullptr; route = route->next()) + for (const sound_route &route : sound->routes()) { // see if we are the target of this route - device_t *target_device = sound->device().siblingdevice(route->m_target.c_str()); - if (target_device == &device() && route->m_input < m_auto_allocated_inputs) + device_t *target_device = sound->device().siblingdevice(route.m_target.c_str()); + if (target_device == &device() && route.m_input < m_auto_allocated_inputs) { - int count = (route->m_output == ALL_OUTPUTS) ? sound->outputs() : 1; + int count = (route.m_output == ALL_OUTPUTS) ? sound->outputs() : 1; for (int output = 0; output < count; output++) - m_outputmap[route->m_input + output] = route->m_mixoutput; + m_outputmap[route.m_input + output] = route.m_mixoutput; } } diff --git a/src/emu/disound.h b/src/emu/disound.h index 7f6f6868b98..6ee07690c92 100644 --- a/src/emu/disound.h +++ b/src/emu/disound.h @@ -73,7 +73,7 @@ public: public: sound_route(int output, int input, float gain, const char *target, UINT32 mixoutput); - const sound_route *next() const { return m_next; } + sound_route *next() const { return m_next; } sound_route * m_next; // pointer to next route UINT32 m_output; // output index, or ALL_OUTPUTS @@ -88,7 +88,7 @@ public: virtual ~device_sound_interface(); // configuration access - const sound_route *first_route() const { return m_route_list.first(); } + const simple_list &routes() const { return m_route_list; } // static inline configuration helpers static sound_route &static_add_route(device_t &device, UINT32 output, const char *target, double gain, UINT32 input = AUTO_ALLOC_INPUT, UINT32 mixoutput = 0); diff --git a/src/emu/distate.cpp b/src/emu/distate.cpp index dcf14c02ee8..3fa2fd8e03b 100644 --- a/src/emu/distate.cpp +++ b/src/emu/distate.cpp @@ -397,7 +397,7 @@ device_state_interface::device_state_interface(const machine_config &mconfig, de memset(m_fast_state, 0, sizeof(m_fast_state)); // configure the fast accessor - device.m_state = this; + device.interfaces().m_state = this; } diff --git a/src/emu/distate.h b/src/emu/distate.h index 67734fefa4b..960a9036f52 100644 --- a/src/emu/distate.h +++ b/src/emu/distate.h @@ -61,7 +61,7 @@ public: device_state_entry &noshow() { m_flags |= DSF_NOSHOW; return *this; } // iteration helpers - const device_state_entry *next() const { return m_next; } + device_state_entry *next() const { return m_next; } // query information int index() const { return m_index; } @@ -124,7 +124,7 @@ public: virtual ~device_state_interface(); // configuration access - const device_state_entry *state_first() const { return m_state_list.first(); } + const simple_list &state_entries() const { return m_state_list; } // state getters UINT64 state_int(int index); @@ -197,7 +197,7 @@ typedef device_interface_iterator state_interface_iterat inline offs_t device_t::safe_pc() const { - return (m_state != nullptr) ? m_state->pc() : 0; + return (m_interfaces.m_state != nullptr) ? m_interfaces.m_state->pc() : 0; } @@ -208,7 +208,7 @@ inline offs_t device_t::safe_pc() const inline offs_t device_t::safe_pcbase() const { - return (m_state != nullptr) ? m_state->pcbase() : 0; + return (m_interfaces.m_state != nullptr) ? m_interfaces.m_state->pcbase() : 0; } diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index 8db25068436..e05a16a5dd5 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -311,7 +311,7 @@ void emu_options::update_slot_options(const software_part *swpart) { // retrieve info about the device instance const char *name = slot->device().tag() + 1; - if (exists(name) && slot->first_option() != nullptr) + if (exists(name) && !slot->option_list().empty()) { std::string defvalue = slot->get_default_card_software(); if (defvalue.length() > 0) diff --git a/src/emu/info.cpp b/src/emu/info.cpp index dff761d5dcd..d9e76cd72d9 100644 --- a/src/emu/info.cpp +++ b/src/emu/info.cpp @@ -335,9 +335,9 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag) for (device_t *dev = iptiter.first(); dev != nullptr; dev = iptiter.next()) portlist.append(*dev, errors); // check if the device adds player inputs (other than dsw and configs) to the system - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() >= IPT_START1 && field->type() < IPT_UI_FIRST) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) { has_input = TRUE; break; @@ -409,11 +409,11 @@ void info_xml_creator::output_devices() slot_interface_iterator iter(m_drivlist.config().root_device()); for (const device_slot_interface *slot = iter.first(); slot != nullptr; slot = iter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); @@ -842,33 +842,33 @@ void info_xml_creator::output_input(const ioport_list &portlist) bool gambling = false; // iterate over the ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) { int analogtype = -1; // track the highest player number - if (nplayer < field->player() + 1) - nplayer = field->player() + 1; + if (nplayer < field.player() + 1) + nplayer = field.player() + 1; // switch off of the type - switch (field->type()) + switch (field.type()) { // map which joystick directions are present - case IPT_JOYSTICK_UP: joytype[0] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_DOWN: joytype[0] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_LEFT: joytype[0] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICK_RIGHT: joytype[0] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_UP: joytype[0] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_DOWN: joytype[0] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_LEFT: joytype[0] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICK_RIGHT: joytype[0] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_UP: joytype[1] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_DOWN: joytype[1] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_LEFT: joytype[1] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKLEFT_RIGHT: joytype[1] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_UP: joytype[1] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_DOWN: joytype[1] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_LEFT: joytype[1] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKLEFT_RIGHT: joytype[1] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_UP: joytype[2] |= DIR_UP | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_DOWN: joytype[2] |= DIR_DOWN | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_LEFT: joytype[2] |= DIR_LEFT | ((field->way() == 4) ? DIR_4WAY : 0); break; - case IPT_JOYSTICKRIGHT_RIGHT: joytype[2] |= DIR_RIGHT | ((field->way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_UP: joytype[2] |= DIR_UP | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_DOWN: joytype[2] |= DIR_DOWN | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_LEFT: joytype[2] |= DIR_LEFT | ((field.way() == 4) ? DIR_4WAY : 0); break; + case IPT_JOYSTICKRIGHT_RIGHT: joytype[2] |= DIR_RIGHT | ((field.way() == 4) ? DIR_4WAY : 0); break; // mark as an analog input, and get analog stats after switch case IPT_AD_STICK_X: @@ -930,7 +930,7 @@ void info_xml_creator::output_input(const ioport_list &portlist) case IPT_BUTTON14: case IPT_BUTTON15: case IPT_BUTTON16: - nbutton = MAX(nbutton, field->type() - IPT_BUTTON1 + 1); + nbutton = MAX(nbutton, field.type() - IPT_BUTTON1 + 1); break; // track maximum coin index @@ -942,7 +942,7 @@ void info_xml_creator::output_input(const ioport_list &portlist) case IPT_COIN6: case IPT_COIN7: case IPT_COIN8: - ncoin = MAX(ncoin, field->type() - IPT_COIN1 + 1); + ncoin = MAX(ncoin, field.type() - IPT_COIN1 + 1); break; // track presence of these guys @@ -964,11 +964,11 @@ void info_xml_creator::output_input(const ioport_list &portlist) break; default: - if (field->type() > IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST) + if (field.type() > IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) mahjong = true; - else if (field->type() > IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST) + else if (field.type() > IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) hanafuda = true; - else if (field->type() > IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST) + else if (field.type() > IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) gambling = true; break; } @@ -976,15 +976,15 @@ void info_xml_creator::output_input(const ioport_list &portlist) // get the analog stats if (analogtype != -1) { - if (field->minval() != 0) - control_info[analogtype].min = field->minval(); - if (field->maxval() != 0) - control_info[analogtype].max = field->maxval(); - if (field->sensitivity() != 0) - control_info[analogtype].sensitivity = field->sensitivity(); - if (field->delta() != 0) - control_info[analogtype].keydelta = field->delta(); - if (field->analog_reverse() != 0) + if (field.minval() != 0) + control_info[analogtype].min = field.minval(); + if (field.maxval() != 0) + control_info[analogtype].max = field.maxval(); + if (field.sensitivity() != 0) + control_info[analogtype].sensitivity = field.sensitivity(); + if (field.delta() != 0) + control_info[analogtype].keydelta = field.delta(); + if (field.analog_reverse() != 0) control_info[analogtype].reverse = true; } } @@ -1092,24 +1092,24 @@ void info_xml_creator::output_input(const ioport_list &portlist) void info_xml_creator::output_switches(const ioport_list &portlist, const char *root_tag, int type, const char *outertag, const char *innertag) { // iterate looking for DIP switches - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == type) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() == type) { std::ostringstream output; - std::string newtag(port->tag()), oldtag(":"); + std::string newtag(port.tag()), oldtag(":"); newtag = newtag.substr(newtag.find(oldtag.append(root_tag)) + oldtag.length()); // output the switch name information - std::string normalized_field_name(xml_normalize_string(field->name())); + std::string normalized_field_name(xml_normalize_string(field.name())); std::string normalized_newtag(xml_normalize_string(newtag.c_str())); - util::stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field->mask()); + util::stream_format(output,"\t\t<%s name=\"%s\" tag=\"%s\" mask=\"%u\">\n", outertag, normalized_field_name.c_str(), normalized_newtag.c_str(), field.mask()); // loop over settings - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + for (ioport_setting &setting : field.settings()) { - util::stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting->name()), setting->value(), setting->value() == field->defvalue() ? " default=\"yes\"" : ""); + util::stream_format(output,"\t\t\t<%s name=\"%s\" value=\"%u\"%s/>\n", innertag, xml_normalize_string(setting.name()), setting.value(), setting.value() == field.defvalue() ? " default=\"yes\"" : ""); } // terminate the switch entry @@ -1126,13 +1126,13 @@ void info_xml_creator::output_switches(const ioport_list &portlist, const char * void info_xml_creator::output_ports(const ioport_list &portlist) { // cycle through ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) + for (ioport_port &port : portlist) { - fprintf(m_output,"\t\t\n",port->tag()); - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + fprintf(m_output,"\t\t\n", xml_normalize_string(port.tag())); + for (ioport_field &field : port.fields()) { - if(field->is_analog()) - fprintf(m_output,"\t\t\t\n",field->mask()); + if(field.is_analog()) + fprintf(m_output,"\t\t\t\n", field.mask()); } // close element fprintf(m_output,"\t\t\n"); @@ -1148,10 +1148,10 @@ void info_xml_creator::output_ports(const ioport_list &portlist) void info_xml_creator::output_adjusters(const ioport_list &portlist) { // iterate looking for Adjusters - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_ADJUSTER) - fprintf(m_output, "\t\t\n", xml_normalize_string(field->name()), field->defvalue()); + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_ADJUSTER) + fprintf(m_output, "\t\t\n", xml_normalize_string(field.name()), field.defvalue()); } @@ -1298,18 +1298,18 @@ void info_xml_creator::output_slots(device_t &device, const char *root_tag) fprintf(m_output, " interface=\"%s\"", xml_normalize_string(slot->slot_interface())); */ - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option->selectable()) + if (option.selectable()) { - device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", option->devtype(), 0); + device_t *dev = const_cast(m_drivlist.config()).device_add(&m_drivlist.config().root_device(), "dummy", option.devtype(), 0); if (!dev->configured()) dev->config_complete(); fprintf(m_output, "\t\t\tname())); + fprintf(m_output, " name=\"%s\"", xml_normalize_string(option.name())); fprintf(m_output, " devname=\"%s\"", xml_normalize_string(dev->shortname())); - if (slot->default_option() != nullptr && strcmp(slot->default_option(),option->name())==0) + if (slot->default_option() != nullptr && strcmp(slot->default_option(),option.name())==0) fprintf(m_output, " default=\"yes\""); fprintf(m_output, "/>\n"); const_cast(m_drivlist.config()).device_remove(&m_drivlist.config().root_device(), "dummy"); diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index dc197ed8734..3d50bcf9e5e 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -659,8 +659,8 @@ void ioport_list::append(device_t &device, std::string &errorbuf) (*constructor)(device, *this, errorbuf); // collapse fields and sort the list - for (ioport_port *port = first(); port != nullptr; port = port->next()) - port->collapse_fields(errorbuf); + for (ioport_port &port : *this) + port.collapse_fields(errorbuf); } @@ -770,10 +770,10 @@ void digital_joystick::frame_update() // read all the associated ports running_machine *machine = nullptr; for (direction_t direction = JOYDIR_UP; direction < JOYDIR_COUNT; ++direction) - for (const simple_list_wrapper *i = m_field[direction].first(); i != nullptr; i = i->next()) + for (const simple_list_wrapper &i : m_field[direction]) { - machine = &i->object()->machine(); - if (machine->input().seq_pressed(i->object()->seq(SEQ_TYPE_STANDARD))) + machine = &i.object()->machine(); + if (machine->input().seq_pressed(i.object()->seq(SEQ_TYPE_STANDARD))) m_current |= 1 << direction; } @@ -903,7 +903,7 @@ void natural_keyboard::post(unicode_char ch) if (LOG_NATURAL_KEYBOARD) { const keycode_map_entry *code = find_code(ch); - machine().logerror("natural_keyboard::post(): code=%i (%s) field->name='%s'\n", int(ch), unicode_to_string(ch).c_str(), (code != nullptr && code->field[0] != nullptr) ? code->field[0]->name() : ""); + machine().logerror("natural_keyboard::post(): code=%i (%s) field.name='%s'\n", int(ch), unicode_to_string(ch).c_str(), (code != nullptr && code->field[0] != nullptr) ? code->field[0]->name() : ""); } // can we post this key in the queue directly? @@ -1074,18 +1074,18 @@ void natural_keyboard::build_codes(ioport_manager &manager) if (curshift == 0 || shift[curshift - 1] != nullptr) // iterate over ports and fields - for (ioport_port *port = manager.first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_KEYBOARD) + for (ioport_port &port : manager.ports()) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_KEYBOARD) { // fetch the code, ignoring 0 - unicode_char code = field->keyboard_code(curshift); + unicode_char code = field.keyboard_code(curshift); if (code == 0) continue; // is this a shifter key? if (code >= UCHAR_SHIFT_BEGIN && code <= UCHAR_SHIFT_END) - shift[code - UCHAR_SHIFT_BEGIN] = field; + shift[code - UCHAR_SHIFT_BEGIN] = &field; // not a shifter key; record normally else @@ -1093,20 +1093,20 @@ void natural_keyboard::build_codes(ioport_manager &manager) keycode_map_entry newcode; if (curshift == 0) { - newcode.field[0] = field; + newcode.field[0] = &field; newcode.field[1] = nullptr; } else { newcode.field[0] = shift[curshift - 1]; - newcode.field[1] = field; + newcode.field[1] = &field; } newcode.ch = code; m_keycode_map.push_back(newcode); if (LOG_NATURAL_KEYBOARD) { - machine().logerror("natural_keyboard: code=%i (%s) port=%p field->name='%s'\n", int(code), unicode_to_string(code).c_str(), (void *)port, field->name()); + machine().logerror("natural_keyboard: code=%i (%s) port=%p field.name='%s'\n", int(code), unicode_to_string(code).c_str(), (void *)&port, field.name()); } } } @@ -1687,7 +1687,7 @@ void ioport_field::get_user_settings(user_settings &settings) settings.seq[seqtype] = seq(seqtype); // if there's a list of settings or we're an adjuster, copy the current value - if (first_setting() != nullptr || m_type == IPT_ADJUSTER) + if (!m_settinglist.empty() || m_type == IPT_ADJUSTER) settings.value = m_live->value; // if there's analog data, extract the analog settings @@ -1726,7 +1726,7 @@ void ioport_field::set_user_settings(const user_settings &settings) } // if there's a list of settings or we're an adjuster, copy the current value - if (first_setting() != nullptr || m_type == IPT_ADJUSTER) + if (!m_settinglist.empty() || m_type == IPT_ADJUSTER) m_live->value = settings.value; // if there's analog data, extract the analog settings @@ -1755,13 +1755,13 @@ void ioport_field::set_user_settings(const user_settings &settings) const char *ioport_field::setting_name() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) - if (setting->value() == m_live->value) - return setting->name(); + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) + if (setting.value() == m_live->value) + return setting.name(); return "INVALID"; } @@ -1775,12 +1775,12 @@ const char *ioport_field::setting_name() const bool ioport_field::has_previous_setting() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) - return (setting->value() != m_live->value); + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) + return (setting.value() != m_live->value); return false; } @@ -1794,27 +1794,27 @@ bool ioport_field::has_previous_setting() const void ioport_field::select_previous_setting() { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value ioport_setting *prevsetting = nullptr; bool found_match = false; - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) { - if (setting->value() == m_live->value) + if (setting.value() == m_live->value) { found_match = true; if (prevsetting != nullptr) break; } - prevsetting = setting; + prevsetting = &setting; } // if we didn't find a matching value, select the first if (!found_match) { - for (prevsetting = first_setting(); prevsetting != nullptr; prevsetting = prevsetting->next()) + for (prevsetting = m_settinglist.first(); prevsetting != nullptr; prevsetting = prevsetting->next()) if (prevsetting->enabled()) break; } @@ -1833,16 +1833,16 @@ void ioport_field::select_previous_setting() bool ioport_field::has_next_setting() const { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value bool found = false; - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - if (setting->enabled()) + for (ioport_setting &setting : m_settinglist) + if (setting.enabled()) { if (found) return true; - if (setting->value() == m_live->value) + if (setting.value() == m_live->value) found = true; } @@ -1858,12 +1858,12 @@ bool ioport_field::has_next_setting() const void ioport_field::select_next_setting() { // only makes sense if we have settings - assert(first_setting() != nullptr); + assert(!m_settinglist.empty()); // scan the list of settings looking for a match on the current value ioport_setting *nextsetting = nullptr; ioport_setting *setting; - for (setting = first_setting(); setting != nullptr; setting = setting->next()) + for (setting = m_settinglist.first(); setting != nullptr; setting = setting->next()) if (setting->enabled()) if (setting->value() == m_live->value) break; @@ -1876,7 +1876,7 @@ void ioport_field::select_next_setting() // if we hit the end, search from the beginning if (nextsetting == nullptr) - for (nextsetting = first_setting(); nextsetting != nullptr; nextsetting = nextsetting->next()) + for (nextsetting = m_settinglist.first(); nextsetting != nullptr; nextsetting = nextsetting->next()) if (nextsetting->enabled()) break; @@ -2154,8 +2154,8 @@ void ioport_field::init_live_state(analog_field *analog) m_condition.initialize(device()); - for (ioport_setting *setting = first_setting(); setting != nullptr; setting = setting->next()) - setting->condition().initialize(setting->device()); + for (ioport_setting &setting : m_settinglist) + setting.condition().initialize(setting.device()); } @@ -2267,12 +2267,12 @@ ioport_manager &ioport_port::manager() const // that intersects the given mask //------------------------------------------------- -ioport_field *ioport_port::field(ioport_value mask) +ioport_field *ioport_port::field(ioport_value mask) const { // if we got the port, look for the field - for (ioport_field *field = first_field(); field != nullptr; field = field->next()) - if ((field->mask() & mask) != 0) - return field; + for (ioport_field &field : fields()) + if ((field.mask() & mask) != 0) + return &field; return nullptr; } @@ -2289,15 +2289,15 @@ ioport_value ioport_port::read() ioport_value result = m_live->digital; // insert dynamic read values - for (dynamic_field *dynfield = m_live->readlist.first(); dynfield != nullptr; dynfield = dynfield->next()) - dynfield->read(result); + for (dynamic_field &dynfield : m_live->readlist) + dynfield.read(result); // apply active high/low state to digital and dynamic read inputs result ^= m_live->defvalue; // insert analog portions - for (analog_field *analog = m_live->analoglist.first(); analog != nullptr; analog = analog->next()) - analog->read(result); + for (analog_field &analog : m_live->analoglist) + analog.read(result); return result; } @@ -2311,9 +2311,9 @@ void ioport_port::write(ioport_value data, ioport_value mem_mask) { // call device line write handlers COMBINE_DATA(&m_live->outputvalue); - for (dynamic_field *dynfield = m_live->writelist.first(); dynfield != nullptr; dynfield = dynfield->next()) - if (dynfield->field().type() == IPT_OUTPUT) - dynfield->write(m_live->outputvalue ^ dynfield->field().defvalue()); + for (dynamic_field &dynfield : m_live->writelist) + if (dynfield.field().type() == IPT_OUTPUT) + dynfield.write(m_live->outputvalue ^ dynfield.field().defvalue()); } @@ -2327,8 +2327,8 @@ void ioport_port::frame_update(ioport_field *mouse_field) m_live->digital = 0; // now loop back and modify based on the inputs - for (ioport_field *field = first_field(); field != nullptr; field = field->next()) - field->frame_update(m_live->digital, field == mouse_field); + for (ioport_field &field : fields()) + field.frame_update(m_live->digital, &field == mouse_field); // hook for MESS's natural keyboard support manager().natkeyboard().frame_update(*this, m_live->digital); @@ -2381,7 +2381,7 @@ void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedb // first modify/nuke any entries that intersect our maskbits ioport_field *nextfield; - for (ioport_field *field = first_field(); field != nullptr; field = nextfield) + for (ioport_field *field = m_fieldlist.first(); field != nullptr; field = nextfield) { nextfield = field->next(); if ((field->mask() & newfield.mask()) != 0 && @@ -2401,7 +2401,7 @@ void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedb // scan forward to find where to insert ourselves ioport_field *field; - for (field = first_field(); field != nullptr; field = field->next()) + for (field = m_fieldlist.first(); field != nullptr; field = field->next()) if (field->mask() > lowbit) break; @@ -2435,23 +2435,23 @@ ioport_port_live::ioport_port_live(ioport_port &port) outputvalue(0) { // iterate over fields - for (ioport_field *field = port.first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { // allocate analog state if it's analog analog_field *analog = nullptr; - if (field->is_analog()) - analog = &analoglist.append(*global_alloc(analog_field(*field))); + if (field.is_analog()) + analog = &analoglist.append(*global_alloc(analog_field(field))); // allocate a dynamic field for reading - if (field->has_dynamic_read()) - readlist.append(*global_alloc(dynamic_field(*field))); + if (field.has_dynamic_read()) + readlist.append(*global_alloc(dynamic_field(field))); // allocate a dynamic field for writing - if (field->has_dynamic_write()) - writelist.append(*global_alloc(dynamic_field(*field))); + if (field.has_dynamic_write()) + writelist.append(*global_alloc(dynamic_field(field))); // let the field initialize its live state - field->init_live_state(analog); + field.init_live_state(analog); } } @@ -2518,15 +2518,15 @@ time_t ioport_manager::initialize() for (device_t *device = iter.first(); device != nullptr; device = iter.next()) { int players = 0; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { - if (&port->device()==device) + if (&port.device() == device) { - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class()==INPUT_CLASS_CONTROLLER) + for (ioport_field &field : port.fields()) + if (field.type_class()==INPUT_CLASS_CONTROLLER) { - if (players < field->player() + 1) players = field->player() + 1; - field->set_player(field->player() + player_offset); + if (players < field.player() + 1) players = field.player() + 1; + field.set_player(field.player() + player_offset); } } } @@ -2534,8 +2534,8 @@ time_t ioport_manager::initialize() } // allocate live structures to mirror the configuration - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - port->init_live_state(); + for (ioport_port &port : m_portlist) + port.init_live_state(); // handle autoselection of devices init_autoselect_devices(IPT_AD_STICK_X, IPT_AD_STICK_Y, IPT_AD_STICK_Z, OPTION_ADSTICK_DEVICE, "analog joystick"); @@ -2550,9 +2550,9 @@ time_t ioport_manager::initialize() // look for 4-way diagonal joysticks and change the default map if we find any const char *joystick_map_default = machine().options().joystick_map(); if (joystick_map_default[0] == 0 || strcmp(joystick_map_default, "auto") == 0) - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->live().joystick != nullptr && field->rotated()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.live().joystick != nullptr && field.rotated()) { machine().input().set_global_joystick_map(joystick_map_4way_diagonal); break; @@ -2570,14 +2570,14 @@ time_t ioport_manager::initialize() m_has_bioses = false; // scan the input port array to see what options we need to enable - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) { - if (field->type() == IPT_DIPSWITCH) + if (field.type() == IPT_DIPSWITCH) m_has_dips = true; - if (field->type() == IPT_CONFIG) + if (field.type() == IPT_CONFIG) m_has_configs = true; - if (field->is_analog()) + if (field.is_analog()) m_has_analog = true; } device_iterator deviter(machine().root_device()); @@ -2609,13 +2609,13 @@ void ioport_manager::init_port_types() machine().osd().customize_input_type_list(m_typelist); // now iterate over the OSD-modified types - for (input_type_entry *curtype = first_type(); curtype != nullptr; curtype = curtype->next()) + for (input_type_entry &curtype : m_typelist) { // first copy all the OSD-updated sequences into our current state - curtype->restore_default_seq(); + curtype.restore_default_seq(); // also make a lookup table mapping type/player to the appropriate type list entry - m_type_to_entry[curtype->type()][curtype->player()] = curtype; + m_type_to_entry[curtype.type()][curtype.player()] = &curtype; } } @@ -2660,12 +2660,12 @@ void ioport_manager::init_autoselect_devices(int type1, int type2, int type3, co osd_printf_error("Invalid %s value %s; reverting to keyboard\n", option, stemp); // only scan the list if we haven't already enabled this class of control - if (first_port() != nullptr && !machine().input().device_class(autoenable).enabled()) - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + if (!m_portlist.empty() && !machine().input().device_class(autoenable).enabled()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) // if this port type is in use, apply the autoselect criteria - if ((type1 != 0 && field->type() == type1) || (type2 != 0 && field->type() == type2) || (type3 != 0 && field->type() == type3)) + if ((type1 != 0 && field.type() == type1) || (type2 != 0 && field.type() == type2) || (type3 != 0 && field.type() == type3)) { osd_printf_verbose("Input: Autoenabling %s due to presence of a %s\n", autostring, ananame); machine().input().device_class(autoenable).enable(); @@ -2772,9 +2772,9 @@ bool ioport_manager::type_pressed(ioport_type type, int player) bool ioport_manager::type_class_present(ioport_type_class inputclass) { - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class() == inputclass) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.type_class() == inputclass) return true; return false; } @@ -2788,15 +2788,15 @@ bool ioport_manager::type_class_present(ioport_type_class inputclass) bool ioport_manager::has_keyboard() const { // iterate over ports and fields - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) { // if we are at init, check IPT_KEYBOARD - if (!m_safe_to_read && field->type() == IPT_KEYBOARD) + if (!m_safe_to_read && field.type() == IPT_KEYBOARD) return true; // else, check if there is a keyboard and if such a keyboard is enabled - if (field->type() == IPT_KEYBOARD && field->enabled()) + if (field.type() == IPT_KEYBOARD && field.enabled()) return true; } @@ -2811,10 +2811,10 @@ bool ioport_manager::has_keyboard() const int ioport_manager::count_players() const { int max_player = 0; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->type_class() == INPUT_CLASS_CONTROLLER && max_player <= field->player() + 1) - max_player = field->player() + 1; + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.type_class() == INPUT_CLASS_CONTROLLER && max_player <= field.player() + 1) + max_player = field.player() + 1; return max_player; } @@ -2829,11 +2829,11 @@ bool ioport_manager::crosshair_position(int player, float &x, float &y) { // read all the lightgun values bool gotx = false, goty = false; - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->player() == player && field->crosshair_axis() != CROSSHAIR_AXIS_NONE && field->enabled()) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (field.player() == player && field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.enabled()) { - field->crosshair_position(x, y, gotx, goty); + field.crosshair_position(x, y, gotx, goty); // if we got both, stop if (gotx && goty) @@ -2855,16 +2855,16 @@ void ioport_manager::update_defaults() for (int loopnum = 0; loopnum < 2; loopnum++) { // loop over all input ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { // only clear on the first pass if (loopnum == 0) - port->live().defvalue = 0; + port.live().defvalue = 0; // first compute the default value for the entire port - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (field->enabled()) - port->live().defvalue = (port->live().defvalue & ~field->mask()) | (field->live().value & field->mask()); + for (ioport_field &field : port.fields()) + if (field.enabled()) + port.live().defvalue = (port.live().defvalue & ~field.mask()) | (field.live().value & field.mask()); } } } @@ -2878,9 +2878,9 @@ void ioport_manager::update_defaults() digital_joystick &ioport_manager::digjoystick(int player, int number) { // find it in the list - for (digital_joystick *joystick = m_joystick_list.first(); joystick != nullptr; joystick = joystick->next()) - if (joystick->player() == player && joystick->number() == number) - return *joystick; + for (digital_joystick &joystick : m_joystick_list) + if (joystick.player() == player && joystick.number() == number) + return joystick; // create a new one return m_joystick_list.append(*global_alloc(digital_joystick(player, number))); @@ -2918,8 +2918,8 @@ g_profiler.start(PROFILER_INPUT); m_last_frame_time = curtime; // update the digital joysticks - for (digital_joystick *joystick = m_joystick_list.first(); joystick != nullptr; joystick = joystick->next()) - joystick->frame_update(); + for (digital_joystick &joystick : m_joystick_list) + joystick.frame_update(); // compute default values for all the ports update_defaults(); @@ -2944,19 +2944,19 @@ g_profiler.start(PROFILER_INPUT); } // loop over all input ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : m_portlist) { - port->frame_update(mouse_field); + port.frame_update(mouse_field); // handle playback/record - playback_port(*port); - record_port(*port); + playback_port(port); + record_port(port); // call device line write handlers - ioport_value newvalue = port->read(); - for (dynamic_field *dynfield = port->live().writelist.first(); dynfield != nullptr; dynfield = dynfield->next()) - if (dynfield->field().type() != IPT_OUTPUT) - dynfield->write(newvalue); + ioport_value newvalue = port.read(); + for (dynamic_field &dynfield : port.live().writelist) + if (dynfield.field().type() != IPT_OUTPUT) + dynfield.write(newvalue); } g_profiler.stop(); @@ -3038,9 +3038,9 @@ void ioport_manager::load_config(config_type cfg_type, xml_data_node *parentnode // after applying the controller config, push that back into the backup, since that is // what we will diff against if (cfg_type == config_type::CONFIG_TYPE_CONTROLLER) - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - entry->defseq(seqtype) = entry->seq(seqtype); + entry.defseq(seqtype) = entry.seq(seqtype); } @@ -3079,9 +3079,9 @@ void ioport_manager::load_remap_table(xml_data_node *parentnode) // loop over the remapping table, then over default ports, replacing old with new for (int remapnum = 0; remapnum < count; remapnum++) - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - entry->m_seq[seqtype].replace(oldtable[remapnum], newtable[remapnum]); + entry.m_seq[seqtype].replace(oldtable[remapnum], newtable[remapnum]); } } @@ -3094,12 +3094,12 @@ void ioport_manager::load_remap_table(xml_data_node *parentnode) bool ioport_manager::load_default_config(xml_data_node *portnode, int type, int player, const input_seq *newseq) { // find a matching port in the list - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) - if (entry->type() == type && entry->player() == player) + for (input_type_entry &entry : m_typelist) + if (entry.type() == type && entry.player() == player) { for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) if (newseq[seqtype][0] != INPUT_CODE_INVALID) - entry->m_seq[seqtype] = newseq[seqtype]; + entry.m_seq[seqtype] = newseq[seqtype]; return true; } @@ -3120,44 +3120,44 @@ bool ioport_manager::load_game_config(xml_data_node *portnode, int type, int pla ioport_value defvalue = xml_get_attribute_int(portnode, "defvalue", 0); // find the port we want; if no tag, search them all - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - if (tag == nullptr || strcmp(port->tag(), tag) == 0) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : m_portlist) + if (tag == nullptr || strcmp(port.tag(), tag) == 0) + for (ioport_field &field : port.fields()) // find the matching mask and defvalue - if (field->type() == type && field->player() == player && - field->mask() == mask && (field->defvalue() & mask) == (defvalue & mask)) + if (field.type() == type && field.player() == player && + field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask)) { // if a sequence was specified, copy it in for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) if (newseq[seqtype][0] != INPUT_CODE_INVALID) - field->live().seq[seqtype] = newseq[seqtype]; + field.live().seq[seqtype] = newseq[seqtype]; // fetch configurable attributes // for non-analog fields - if (field->live().analog == nullptr) + if (field.live().analog == nullptr) { // fetch the value - field->live().value = xml_get_attribute_int(portnode, "value", field->defvalue()); + field.live().value = xml_get_attribute_int(portnode, "value", field.defvalue()); // fetch yes/no for toggle setting const char *togstring = xml_get_attribute_string(portnode, "toggle", nullptr); if (togstring != nullptr) - field->live().toggle = (strcmp(togstring, "yes") == 0); + field.live().toggle = (strcmp(togstring, "yes") == 0); } // for analog fields else { // get base attributes - field->live().analog->m_delta = xml_get_attribute_int(portnode, "keydelta", field->delta()); - field->live().analog->m_centerdelta = xml_get_attribute_int(portnode, "centerdelta", field->centerdelta()); - field->live().analog->m_sensitivity = xml_get_attribute_int(portnode, "sensitivity", field->sensitivity()); + field.live().analog->m_delta = xml_get_attribute_int(portnode, "keydelta", field.delta()); + field.live().analog->m_centerdelta = xml_get_attribute_int(portnode, "centerdelta", field.centerdelta()); + field.live().analog->m_sensitivity = xml_get_attribute_int(portnode, "sensitivity", field.sensitivity()); // fetch yes/no for reverse setting const char *revstring = xml_get_attribute_string(portnode, "reverse", nullptr); if (revstring != nullptr) - field->live().analog->m_reverse = (strcmp(revstring, "yes") == 0); + field.live().analog->m_reverse = (strcmp(revstring, "yes") == 0); } return true; } @@ -3241,15 +3241,15 @@ bool ioport_manager::save_this_input_field_type(ioport_type type) void ioport_manager::save_default_inputs(xml_data_node *parentnode) { // iterate over ports - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : m_typelist) { // only save if this port is a type we save - if (save_this_input_field_type(entry->type())) + if (save_this_input_field_type(entry.type())) { // see if any of the sequences have changed input_seq_type seqtype; for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - if (entry->seq(seqtype) != entry->defseq(seqtype)) + if (entry.seq(seqtype) != entry.defseq(seqtype)) break; // if so, we need to add a node @@ -3260,12 +3260,12 @@ void ioport_manager::save_default_inputs(xml_data_node *parentnode) if (portnode != nullptr) { // add the port information and attributes - xml_set_attribute(portnode, "type", input_type_to_token(entry->type(), entry->player()).c_str()); + xml_set_attribute(portnode, "type", input_type_to_token(entry.type(), entry.player()).c_str()); // add only the sequences that have changed from the defaults for (input_seq_type type = SEQ_TYPE_STANDARD; type < SEQ_TYPE_TOTAL; ++type) - if (entry->seq(type) != entry->defseq(type)) - save_sequence(portnode, type, entry->type(), entry->seq(type)); + if (entry.seq(type) != entry.defseq(type)) + save_sequence(portnode, type, entry.type(), entry.seq(type)); } } } @@ -3281,29 +3281,29 @@ void ioport_manager::save_default_inputs(xml_data_node *parentnode) void ioport_manager::save_game_inputs(xml_data_node *parentnode) { // iterate over ports - for (ioport_port *port = first_port(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) - if (save_this_input_field_type(field->type())) + for (ioport_port &port : m_portlist) + for (ioport_field &field : port.fields()) + if (save_this_input_field_type(field.type())) { // determine if we changed bool changed = false; for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - changed |= (field->seq(seqtype) != field->defseq(seqtype)); + changed |= (field.seq(seqtype) != field.defseq(seqtype)); // non-analog changes - if (!field->is_analog()) + if (!field.is_analog()) { - changed |= ((field->live().value & field->mask()) != (field->defvalue() & field->mask())); - changed |= (field->live().toggle != field->toggle()); + changed |= ((field.live().value & field.mask()) != (field.defvalue() & field.mask())); + changed |= (field.live().toggle != field.toggle()); } // analog changes else { - changed |= (field->live().analog->m_delta != field->delta()); - changed |= (field->live().analog->m_centerdelta != field->centerdelta()); - changed |= (field->live().analog->m_sensitivity != field->sensitivity()); - changed |= (field->live().analog->m_reverse != field->analog_reverse()); + changed |= (field.live().analog->m_delta != field.delta()); + changed |= (field.live().analog->m_centerdelta != field.centerdelta()); + changed |= (field.live().analog->m_sensitivity != field.sensitivity()); + changed |= (field.live().analog->m_reverse != field.analog_reverse()); } // if we did change, add a new node @@ -3314,36 +3314,36 @@ void ioport_manager::save_game_inputs(xml_data_node *parentnode) if (portnode != nullptr) { // add the identifying information and attributes - xml_set_attribute(portnode, "tag", port->tag()); - xml_set_attribute(portnode, "type", input_type_to_token(field->type(), field->player()).c_str()); - xml_set_attribute_int(portnode, "mask", field->mask()); - xml_set_attribute_int(portnode, "defvalue", field->defvalue() & field->mask()); + xml_set_attribute(portnode, "tag", port.tag()); + xml_set_attribute(portnode, "type", input_type_to_token(field.type(), field.player()).c_str()); + xml_set_attribute_int(portnode, "mask", field.mask()); + xml_set_attribute_int(portnode, "defvalue", field.defvalue() & field.mask()); // add sequences if changed for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) - if (field->seq(seqtype) != field->defseq(seqtype)) - save_sequence(portnode, seqtype, field->type(), field->seq(seqtype)); + if (field.seq(seqtype) != field.defseq(seqtype)) + save_sequence(portnode, seqtype, field.type(), field.seq(seqtype)); // write out non-analog changes - if (!field->is_analog()) + if (!field.is_analog()) { - if ((field->live().value & field->mask()) != (field->defvalue() & field->mask())) - xml_set_attribute_int(portnode, "value", field->live().value & field->mask()); - if (field->live().toggle != field->toggle()) - xml_set_attribute(portnode, "toggle", field->live().toggle ? "yes" : "no"); + if ((field.live().value & field.mask()) != (field.defvalue() & field.mask())) + xml_set_attribute_int(portnode, "value", field.live().value & field.mask()); + if (field.live().toggle != field.toggle()) + xml_set_attribute(portnode, "toggle", field.live().toggle ? "yes" : "no"); } // write out analog changes else { - if (field->live().analog->m_delta != field->delta()) - xml_set_attribute_int(portnode, "keydelta", field->live().analog->m_delta); - if (field->live().analog->m_centerdelta != field->centerdelta()) - xml_set_attribute_int(portnode, "centerdelta", field->live().analog->m_centerdelta); - if (field->live().analog->m_sensitivity != field->sensitivity()) - xml_set_attribute_int(portnode, "sensitivity", field->live().analog->m_sensitivity); - if (field->live().analog->m_reverse != field->analog_reverse()) - xml_set_attribute(portnode, "reverse", field->live().analog->m_reverse ? "yes" : "no"); + if (field.live().analog->m_delta != field.delta()) + xml_set_attribute_int(portnode, "keydelta", field.live().analog->m_delta); + if (field.live().analog->m_centerdelta != field.centerdelta()) + xml_set_attribute_int(portnode, "centerdelta", field.live().analog->m_centerdelta); + if (field.live().analog->m_sensitivity != field.sensitivity()) + xml_set_attribute_int(portnode, "sensitivity", field.live().analog->m_sensitivity); + if (field.live().analog->m_reverse != field.analog_reverse()) + xml_set_attribute(portnode, "reverse", field.live().analog->m_reverse ? "yes" : "no"); } } } @@ -3508,15 +3508,15 @@ void ioport_manager::playback_port(ioport_port &port) playback_read(port.live().digital); // loop over analog ports and save their data - for (analog_field *analog = port.live().analoglist.first(); analog != nullptr; analog = analog->next()) + for (analog_field &analog : port.live().analoglist) { // read current and previous values - playback_read(analog->m_accum); - playback_read(analog->m_previous); + playback_read(analog.m_accum); + playback_read(analog.m_previous); // read configuration information - playback_read(analog->m_sensitivity); - playback_read(analog->m_reverse); + playback_read(analog.m_sensitivity); + playback_read(analog.m_reverse); } } } @@ -3799,15 +3799,15 @@ void ioport_manager::record_port(ioport_port &port) record_write(port.live().digital); // loop over analog ports and save their data - for (analog_field *analog = port.live().analoglist.first(); analog != nullptr; analog = analog->next()) + for (analog_field &analog : port.live().analoglist) { // store current and previous values - record_write(analog->m_accum); - record_write(analog->m_previous); + record_write(analog.m_accum); + record_write(analog.m_previous); // store configuration information - record_write(analog->m_sensitivity); - record_write(analog->m_reverse); + record_write(analog.m_sensitivity); + record_write(analog.m_reverse); } } } @@ -4570,11 +4570,11 @@ ioport_type ioport_manager::token_to_input_type(const char *string, int &player) return ioport_type(ipnum); // find the token in the list - for (input_type_entry *entry = m_typelist.first(); entry != nullptr; entry = entry->next()) - if (entry->token() != nullptr && !strcmp(entry->token(), string)) + for (input_type_entry &entry : m_typelist) + if (entry.token() != nullptr && !strcmp(entry.token(), string)) { - player = entry->player(); - return entry->type(); + player = entry.player(); + return entry.type(); } // if we fail, return IPT_UNKNOWN diff --git a/src/emu/ioport.h b/src/emu/ioport.h index c7fbd8ddd79..5155005569b 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -1105,8 +1105,8 @@ public: ioport_manager &manager() const; running_machine &machine() const; int modcount() const { return m_modcount; } - ioport_setting *first_setting() const { return m_settinglist.first(); } - ioport_diplocation *first_diplocation() const { return m_diploclist.first(); } + const simple_list &settings() const { return m_settinglist; } + const simple_list &diplocations() const { return m_diploclist; } ioport_value mask() const { return m_mask; } ioport_value defvalue() const { return m_defvalue; } @@ -1291,7 +1291,7 @@ public: ioport_manager &manager() const; device_t &device() const { return m_device; } running_machine &machine() const; - ioport_field *first_field() const { return m_fieldlist.first(); } + const simple_list &fields() const { return m_fieldlist; } const char *tag() const { return m_tag.c_str(); } int modcount() const { return m_modcount; } ioport_value active() const { return m_active; } @@ -1302,7 +1302,7 @@ public: void write(ioport_value value, ioport_value mask = ~0); // other operations - ioport_field *field(ioport_value mask); + ioport_field *field(ioport_value mask) const; void collapse_fields(std::string &errorbuf); void frame_update(ioport_field *mouse_field); void init_live_state(); @@ -1466,7 +1466,7 @@ public: // getters running_machine &machine() const { return m_machine; } - ioport_port *first_port() const { return m_portlist.first(); } + const ioport_list &ports() const { return m_portlist; } bool safe_to_read() const { return m_safe_to_read; } natural_keyboard &natkeyboard() { return m_natkeyboard; } @@ -1477,7 +1477,7 @@ public: bool has_bioses() const { return m_has_bioses; } // type helpers - input_type_entry *first_type() const { return m_typelist.first(); } + const simple_list &types() const { return m_typelist; } bool type_pressed(ioport_type type, int player = 0); const char *type_name(ioport_type type, UINT8 player); ioport_group type_group(ioport_type type, int player); diff --git a/src/emu/luaengine.cpp b/src/emu/luaengine.cpp index 18ae0172bf7..62667ee0eef 100644 --- a/src/emu/luaengine.cpp +++ b/src/emu/luaengine.cpp @@ -392,9 +392,9 @@ luabridge::LuaRef lua_engine::l_options_get_entries(const T *o) luabridge::LuaRef entries_table = luabridge::LuaRef::newTable(L); int unadorned_index = 0; - for (typename T::entry *curentry = options->first(); curentry != nullptr; curentry = curentry->next()) + for (typename T::entry &curentry : *options) { - const char *name = curentry->name(); + const char *name = curentry.name(); bool is_unadorned = false; // check if it's unadorned if (name && strlen(name) && !strcmp(name, options->unadorned(unadorned_index))) @@ -402,8 +402,8 @@ luabridge::LuaRef lua_engine::l_options_get_entries(const T *o) unadorned_index++; is_unadorned = true; } - if (!curentry->is_header() && !curentry->is_command() && !curentry->is_internal() && !is_unadorned) - entries_table[name] = curentry; + if (!curentry.is_header() && !curentry.is_command() && !curentry.is_internal() && !is_unadorned) + entries_table[name] = &curentry; } return entries_table; @@ -458,8 +458,8 @@ luabridge::LuaRef lua_engine::l_cheat_get_entries(const cheat_manager *c) luabridge::LuaRef entry_table = luabridge::LuaRef::newTable(L); int cheatnum = 0; - for (cheat_entry *entry = cm->first(); entry != nullptr; entry = entry->next()) { - entry_table[cheatnum++] = entry; + for (cheat_entry &entry : cm->entries()) { + entry_table[cheatnum++] = &entry; } return entry_table; @@ -496,10 +496,9 @@ luabridge::LuaRef lua_engine::l_ioport_get_ports(const ioport_manager *m) ioport_manager *im = const_cast(m); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef port_table = luabridge::LuaRef::newTable(L); - ioport_port *port; - for (port = im->first_port(); port != nullptr; port = port->next()) { - port_table[port->tag()] = port; + for (ioport_port &port : im->ports()) { + port_table[port.tag()] = &port; } return port_table; @@ -515,10 +514,9 @@ luabridge::LuaRef lua_engine::l_ioports_port_get_fields(const ioport_port *i) ioport_port *p = const_cast(i); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef f_table = luabridge::LuaRef::newTable(L); - ioport_field *field; - for (field = p->first_field(); field != nullptr; field = field->next()) { - f_table[field->name()] = field; + for (ioport_field &field : p->fields()) { + f_table[field.name()] = &field; } return f_table; @@ -535,9 +533,9 @@ luabridge::LuaRef lua_engine::l_render_get_targets(const render_manager *r) luabridge::LuaRef target_table = luabridge::LuaRef::newTable(L); int tc = 0; - for (render_target *curr_rt = r->first_target(); curr_rt != nullptr; curr_rt = curr_rt->next()) + for (render_target &curr_rt : r->targets()) { - target_table[tc++] = curr_rt; + target_table[tc++] = &curr_rt; } return target_table; @@ -547,10 +545,10 @@ luabridge::LuaRef lua_engine::l_render_get_targets(const render_manager *r) luabridge::LuaRef lua_engine::devtree_dfs(device_t *root, luabridge::LuaRef devs_table) { if (root) { - for (device_t *dev = root->first_subdevice(); dev != nullptr; dev = dev->next()) { - if (dev && dev->configured() && dev->started()) { - devs_table[dev->tag()] = dev; - devtree_dfs(dev, devs_table); + for (device_t &dev : root->subdevices()) { + if (dev.configured() && dev.started()) { + devs_table[dev.tag()] = &dev; + devtree_dfs(&dev, devs_table); } } } @@ -587,11 +585,10 @@ luabridge::LuaRef lua_engine::l_dev_get_states(const device_t *d) device_t *dev = const_cast(d); lua_State *L = luaThis->m_lua_state; luabridge::LuaRef st_table = luabridge::LuaRef::newTable(L); - for (const device_state_entry *s = dev->state().state_first(); s != nullptr; s = s->next()) { + for (device_state_entry &s : dev->state().state_entries()) + { // XXX: refrain from exporting non-visible entries? - if (s) { - st_table[s->symbol()] = const_cast(s); - } + st_table[s.symbol()] = &s; } return st_table; @@ -1385,17 +1382,16 @@ void lua_engine::update_machine() if (m_machine!=nullptr) { // Create the ioport array - ioport_port *port = machine().ioport().first_port(); - while(port) { - ioport_field *field = port->first_field(); - while(field) { - if(field->name()) { - push(m_lua_state, field, tname_ioport); - lua_setfield(m_lua_state, -2, field->name()); + for (ioport_port &port : machine().ioport().ports()) + { + for (ioport_field &field : port.fields()) + { + if (field.name()) + { + push(m_lua_state, &field, tname_ioport); + lua_setfield(m_lua_state, -2, field.name()); } - field = field->next(); } - port = port->next(); } } lua_setglobal(m_lua_state, "ioport"); diff --git a/src/emu/mame.cpp b/src/emu/mame.cpp index 7f22c8abcb7..3c4b35df058 100644 --- a/src/emu/mame.cpp +++ b/src/emu/mame.cpp @@ -192,19 +192,19 @@ void machine_manager::start_luaengine() osd_printf_error("**Error loading plugin.ini**"); } } - for (auto curentry = m_plugins->first(); curentry != nullptr; curentry = curentry->next()) + for (auto &curentry : *m_plugins) { - if (!curentry->is_header()) + if (!curentry.is_header()) { - if (std::find(include.begin(), include.end(), curentry->name()) != include.end()) + if (std::find(include.begin(), include.end(), curentry.name()) != include.end()) { std::string error_string; - m_plugins->set_value(curentry->name(), "1", OPTION_PRIORITY_CMDLINE, error_string); + m_plugins->set_value(curentry.name(), "1", OPTION_PRIORITY_CMDLINE, error_string); } - if (std::find(exclude.begin(), exclude.end(), curentry->name()) != exclude.end()) + if (std::find(exclude.begin(), exclude.end(), curentry.name()) != exclude.end()) { std::string error_string; - m_plugins->set_value(curentry->name(), "0", OPTION_PRIORITY_CMDLINE, error_string); + m_plugins->set_value(curentry.name(), "0", OPTION_PRIORITY_CMDLINE, error_string); } } } diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp index 6c052d7ce23..793da15c1a0 100644 --- a/src/emu/mconfig.cpp +++ b/src/emu/mconfig.cpp @@ -125,31 +125,27 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty const char *next = strchr(tag, ':'); assert(next != tag); std::string part(tag, next-tag); - device_t *curdevice; - for (curdevice = owner->m_subdevice_list.first(); curdevice != nullptr; curdevice = curdevice->next()) - if (part.compare(curdevice->m_basetag)==0) - break; - if (!curdevice) + owner = owner->subdevices().find(part); + if (owner == nullptr) throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part.c_str(), orig_tag); - owner = curdevice; tag = next+1; } - assert(tag[0]); + assert(tag[0] != '\0'); - // if there's an owner, let the owner do the work if (owner != nullptr) - return owner->add_subdevice(type, tag, clock); + { + // allocate the new device + device_t *device = (*type)(*this, tag, owner, clock); - // otherwise, allocate the device directly + // append it to the owner's list + return &config_new_device(owner->subdevices().m_list.append(*device)); + } + + // allocate the root device directly assert(m_root_device == nullptr); - m_root_device.reset((*type)(*this, tag, owner, clock)); - - // apply any machine configuration owned by the device now - machine_config_constructor additions = m_root_device->machine_config_additions(); - if (additions != nullptr) - (*additions)(*this, m_root_device.get(), nullptr); - return m_root_device.get(); + m_root_device.reset((*type)(*this, tag, nullptr, clock)); + return &config_new_device(*m_root_device); } @@ -160,17 +156,27 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); - device_t *device = owner->subdevice(tag); - if (device == nullptr) + device_t *old_device = owner->subdevice(tag); + if (old_device == nullptr) { osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag); return device_add(owner, tag, type, clock); } - // let the device's owner do the work - return device->owner()->replace_subdevice(*device, type, tag, clock); + // make sure we have the old device's actual owner + owner = old_device->owner(); + assert(owner != nullptr); + + // remove references to the old device + remove_references(*old_device); + + // allocate the new device + device_t *new_device = (*type)(*this, tag, owner, clock); + + // substitute it for the old one in the owner's list + return &config_new_device(owner->subdevices().m_list.replace_and_remove(*new_device, *old_device)); } @@ -181,7 +187,7 @@ device_t *machine_config::device_replace(device_t *owner, const char *tag, devic device_t *machine_config::device_remove(device_t *owner, const char *tag) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); device_t *device = owner->subdevice(tag); if (device == nullptr) @@ -190,8 +196,15 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag) return nullptr; } + // make sure we have the old device's actual owner + owner = device->owner(); + assert(owner != nullptr); + + // remove references to the old device + remove_references(*device); + // let the device's owner do the work - device->owner()->remove_subdevice(*device); + owner->subdevices().m_list.remove(*device); return nullptr; } @@ -203,7 +216,7 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag) device_t *machine_config::device_find(device_t *owner, const char *tag) { - // find the original device by this name (must exist) + // find the original device by relative tag (must exist) assert(owner != nullptr); device_t *device = owner->subdevice(tag); assert(device != nullptr); @@ -213,3 +226,34 @@ device_t *machine_config::device_find(device_t *owner, const char *tag) // return the device return device; } + + +//------------------------------------------------- +// remove_references - globally remove references +// to a device about to be removed from the tree +//------------------------------------------------- + +void machine_config::remove_references(ATTR_UNUSED device_t &device) +{ + // iterate over all devices and remove any references + device_iterator iter(root_device()); + for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) + scan->subdevices().m_tagmap.clear(); //remove(&device); +} + + +//------------------------------------------------- +// config_new_device - helper for recursive +// configuration of newly added devices +//------------------------------------------------- + +device_t &machine_config::config_new_device(device_t &device) +{ + // apply any machine configuration owned by the device now + machine_config_constructor additions = device.machine_config_additions(); + if (additions != nullptr) + (*additions)(*this, &device, nullptr); + + // return the new device + return device; +} diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index c552812348c..412c2c12e82 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -84,6 +84,10 @@ public: device_t *device_find(device_t *owner, const char *tag); private: + // internal helpers + void remove_references(ATTR_UNUSED device_t &device); + device_t &config_new_device(device_t &device); + // internal state const game_driver & m_gamedrv; emu_options & m_options; diff --git a/src/emu/memory.cpp b/src/emu/memory.cpp index 59d1f6d69e2..331345ea63d 100644 --- a/src/emu/memory.cpp +++ b/src/emu/memory.cpp @@ -1558,26 +1558,26 @@ void memory_manager::initialize() } // construct and preprocess the address_map for each space - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->prepare_map(); + for (address_space &space : m_spacelist) + space.prepare_map(); // create the handlers from the resulting address maps - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->populate_from_map(); + for (address_space &space : m_spacelist) + space.populate_from_map(); // allocate memory needed to back each address space - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->allocate_memory(); + for (address_space &space : m_spacelist) + space.allocate_memory(); // find all the allocated pointers - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) - space->locate_memory(); + for (address_space &space : m_spacelist) + space.locate_memory(); // disable logging of unmapped access when no one receives it - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) + for (address_space &space : m_spacelist) { if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED)) - space->set_log_unmap(false); + space.set_log_unmap(false); } // register a callback to reset banks when reloading state @@ -1603,19 +1603,19 @@ void memory_manager::dump(FILE *file) return; // loop over address spaces - for (address_space *space = m_spacelist.first(); space != nullptr; space = space->next()) + for (address_space &space : m_spacelist) { fprintf(file, "\n\n" "====================================================\n" "Device '%s' %s address space read handler dump\n" - "====================================================\n", space->device().tag(), space->name()); - space->dump_map(file, ROW_READ); + "====================================================\n", space.device().tag(), space.name()); + space.dump_map(file, ROW_READ); fprintf(file, "\n\n" "====================================================\n" "Device '%s' %s address space write handler dump\n" - "====================================================\n", space->device().tag(), space->name()); - space->dump_map(file, ROW_WRITE); + "====================================================\n", space.device().tag(), space.name()); + space.dump_map(file, ROW_WRITE); } } @@ -1647,6 +1647,25 @@ void memory_manager::region_free(const char *name) } +//------------------------------------------------- +// region_containing - helper to determine if +// a block of memory is part of a region +//------------------------------------------------- + +memory_region *memory_manager::region_containing(const void *memory, offs_t bytes) const +{ + const UINT8 *data = reinterpret_cast(memory); + + // look through the region list and return the first match + for (memory_region ®ion : m_regionlist) + if (data >= region.base() && (data + bytes) <= region.end()) + return ®ion; + + // didn't find one + return nullptr; +} + + //------------------------------------------------- // generate_memdump - internal memory dump //------------------------------------------------- @@ -1672,9 +1691,9 @@ static void generate_memdump(running_machine &machine) void memory_manager::bank_reattach() { // for each non-anonymous bank, explicitly reset its entry - for (memory_bank *bank = m_banklist.first(); bank != nullptr; bank = bank->next()) - if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED) - bank->set_entry(bank->entry()); + for (memory_bank &bank : m_banklist) + if (!bank.anonymous() && bank.entry() != BANK_ENTRY_UNSPECIFIED) + bank.set_entry(bank.entry()); } @@ -1848,63 +1867,63 @@ void address_space::prepare_map() } // make a pass over the address map, adjusting for the device and getting memory pointers - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { // computed adjusted addresses first - entry->m_bytestart = entry->m_addrstart; - entry->m_byteend = entry->m_addrend; - entry->m_bytemirror = entry->m_addrmirror; - entry->m_bytemask = entry->m_addrmask; - adjust_addresses(entry->m_bytestart, entry->m_byteend, entry->m_bytemask, entry->m_bytemirror); + entry.m_bytestart = entry.m_addrstart; + entry.m_byteend = entry.m_addrend; + entry.m_bytemirror = entry.m_addrmirror; + entry.m_bytemask = entry.m_addrmask; + adjust_addresses(entry.m_bytestart, entry.m_byteend, entry.m_bytemask, entry.m_bytemirror); // if we have a share entry, add it to our map - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) { // if we can't find it, add it to our map - std::string fulltag = entry->m_devbase.subtag(entry->m_share); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); if (manager().m_sharelist.find(fulltag.c_str()) == nullptr) { - VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry->m_byteend + 1 - entry->m_bytestart)); - auto share = global_alloc(memory_share(m_map->m_databits, entry->m_byteend + 1 - entry->m_bytestart, endianness())); + VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry.m_byteend + 1 - entry.m_bytestart)); + auto share = global_alloc(memory_share(m_map->m_databits, entry.m_byteend + 1 - entry.m_bytestart, endianness())); manager().m_sharelist.append(fulltag.c_str(), *share); } } // if this is a ROM handler without a specified region, attach it to the implicit region - if (m_spacenum == AS_0 && entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr) + if (m_spacenum == AS_0 && entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { // make sure it fits within the memory region before doing so, however - if (entry->m_byteend < devregionsize) + if (entry.m_byteend < devregionsize) { - entry->m_region = m_device.tag(); - entry->m_rgnoffs = entry->m_bytestart; + entry.m_region = m_device.tag(); + entry.m_rgnoffs = entry.m_bytestart; } } // validate adjusted addresses against implicit regions - if (entry->m_region != nullptr && entry->m_share == nullptr) + if (entry.m_region != nullptr && entry.m_share == nullptr) { // determine full tag - std::string fulltag = entry->m_devbase.subtag(entry->m_region); + std::string fulltag = entry.m_devbase.subtag(entry.m_region); // find the region memory_region *region = machine().root_device().memregion(fulltag.c_str()); if (region == nullptr) - fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); + fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); // validate the region - if (entry->m_rgnoffs + (entry->m_byteend - entry->m_bytestart + 1) > region->bytes()) - fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes()); + if (entry.m_rgnoffs + (entry.m_byteend - entry.m_bytestart + 1) > region->bytes()) + fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, region->bytes()); } // convert any region-relative entries to their memory pointers - if (entry->m_region != nullptr) + if (entry.m_region != nullptr) { // determine full tag - std::string fulltag = entry->m_devbase.subtag(entry->m_region); + std::string fulltag = entry.m_devbase.subtag(entry.m_region); // set the memory address - entry->m_memory = machine().root_device().memregion(fulltag.c_str())->base() + entry->m_rgnoffs; + entry.m_memory = machine().root_device().memregion(fulltag.c_str())->base() + entry.m_rgnoffs; } } @@ -2039,9 +2058,9 @@ void address_space::allocate_memory() // make a first pass over the memory map and track blocks with hardcoded pointers // we do this to make sure they are found by space_find_backing_memory first memory_block *prev_memblock_tail = blocklist.last(); - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_memory != nullptr) - blocklist.append(*global_alloc(memory_block(*this, entry->m_bytestart, entry->m_byteend, entry->m_memory))); + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_memory != nullptr) + blocklist.append(*global_alloc(memory_block(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory))); // loop over all blocks just allocated and assign pointers from them address_map_entry *unassigned = nullptr; @@ -2067,12 +2086,12 @@ void address_space::allocate_memory() changed = false; // scan for unmapped blocks in the adjusted map - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_memory == nullptr && entry != unassigned && needs_backing_store(entry)) + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_memory == nullptr && &entry != unassigned && needs_backing_store(entry)) { // get block start/end blocks for this block - offs_t blockstart = entry->m_bytestart / MEMORY_BLOCK_CHUNK; - offs_t blockend = entry->m_byteend / MEMORY_BLOCK_CHUNK; + offs_t blockstart = entry.m_bytestart / MEMORY_BLOCK_CHUNK; + offs_t blockend = entry.m_byteend / MEMORY_BLOCK_CHUNK; // if we intersect or are adjacent, adjust the start/end if (blockstart <= curblockend + 1 && blockend >= curblockstart - 1) @@ -2104,21 +2123,21 @@ void address_space::allocate_memory() void address_space::locate_memory() { // once this is done, find the starting bases for the banks - for (memory_bank *bank = manager().m_banklist.first(); bank != nullptr; bank = bank->next()) - if (bank->base() == nullptr && bank->references_space(*this, ROW_READWRITE)) + for (memory_bank &bank : manager().banks()) + if (bank.base() == nullptr && bank.references_space(*this, ROW_READWRITE)) { // set the initial bank pointer - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) - if (entry->m_bytestart == bank->bytestart() && entry->m_memory != nullptr) + for (address_map_entry &entry : m_map->m_entrylist) + if (entry.m_bytestart == bank.bytestart() && entry.m_memory != nullptr) { - bank->set_base(entry->m_memory); - VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank->tag(), entry->m_addrstart, entry->m_addrend, entry->m_memory)); + bank.set_base(entry.m_memory); + VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank.tag(), entry.m_addrstart, entry.m_addrend, entry.m_memory)); break; } // if the entry was set ahead of time, override the automatically found pointer - if (!bank->anonymous() && bank->entry() != BANK_ENTRY_UNSPECIFIED) - bank->set_entry(bank->entry()); + if (!bank.anonymous() && bank.entry() != BANK_ENTRY_UNSPECIFIED) + bank.set_entry(bank.entry()); } } @@ -2135,46 +2154,46 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of address_map_entry *unassigned = nullptr; // loop over the adjusted map and assign memory to any blocks we can - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { // if we haven't assigned this block yet, see if we have a mapped shared pointer for it - if (entry->m_memory == nullptr && entry->m_share != nullptr) + if (entry.m_memory == nullptr && entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() != nullptr) { - entry->m_memory = share->ptr(); - VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry->m_addrstart, entry->m_addrend, entry->m_share, entry->m_memory)); + entry.m_memory = share->ptr(); + VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' [%p]\n", entry.m_addrstart, entry.m_addrend, entry.m_share, entry.m_memory)); } else { - VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' but not found\n", entry->m_addrstart, entry->m_addrend, entry->m_share)); + VPRINTF(("memory range %08X-%08X -> shared_ptr '%s' but not found\n", entry.m_addrstart, entry.m_addrend, entry.m_share)); } } // otherwise, look for a match in this block - if (entry->m_memory == nullptr && entry->m_bytestart >= bytestart && entry->m_byteend <= byteend) + if (entry.m_memory == nullptr && entry.m_bytestart >= bytestart && entry.m_byteend <= byteend) { - entry->m_memory = base + (entry->m_bytestart - bytestart); - VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, bytestart, byteend, entry->m_memory)); + entry.m_memory = base + (entry.m_bytestart - bytestart); + VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, bytestart, byteend, entry.m_memory)); } // if we're the first match on a shared pointer, assign it now - if (entry->m_memory != nullptr && entry->m_share != nullptr) + if (entry.m_memory != nullptr && entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() == nullptr) { - share->set_ptr(entry->m_memory); - VPRINTF(("setting shared_ptr '%s' = %p\n", entry->m_share, entry->m_memory)); + share->set_ptr(entry.m_memory); + VPRINTF(("setting shared_ptr '%s' = %p\n", entry.m_share, entry.m_memory)); } } // keep track of the first unassigned entry - if (entry->m_memory == nullptr && unassigned == nullptr && needs_backing_store(entry)) - unassigned = entry; + if (entry.m_memory == nullptr && unassigned == nullptr && needs_backing_store(entry)) + unassigned = &entry; } return unassigned; @@ -2584,23 +2603,23 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) return nullptr; // look in the address map first - for (address_map_entry *entry = m_map->m_entrylist.first(); entry != nullptr; entry = entry->next()) + for (address_map_entry &entry : m_map->m_entrylist) { - offs_t maskstart = bytestart & entry->m_bytemask; - offs_t maskend = byteend & entry->m_bytemask; - if (entry->m_memory != nullptr && maskstart >= entry->m_bytestart && maskend <= entry->m_byteend) + offs_t maskstart = bytestart & entry.m_bytemask; + offs_t maskend = byteend & entry.m_bytemask; + if (entry.m_memory != nullptr && maskstart >= entry.m_bytestart && maskend <= entry.m_byteend) { - VPRINTF(("found in entry %08X-%08X [%p]\n", entry->m_addrstart, entry->m_addrend, (UINT8 *)entry->m_memory + (maskstart - entry->m_bytestart))); - return (UINT8 *)entry->m_memory + (maskstart - entry->m_bytestart); + VPRINTF(("found in entry %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, (UINT8 *)entry.m_memory + (maskstart - entry.m_bytestart))); + return (UINT8 *)entry.m_memory + (maskstart - entry.m_bytestart); } } // if not found there, look in the allocated blocks - for (memory_block *block = manager().m_blocklist.first(); block != nullptr; block = block->next()) - if (block->contains(*this, bytestart, byteend)) + for (memory_block &block : manager().m_blocklist) + if (block.contains(*this, bytestart, byteend)) { - VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart()))); - return block->data() + bytestart - block->bytestart(); + VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block.bytestart(), block.byteend(), block.data() + (bytestart - block.bytestart()))); + return block.data() + bytestart - block.bytestart(); } VPRINTF(("did not find\n")); @@ -2614,25 +2633,25 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) // allocating and registering memory //------------------------------------------------- -bool address_space::needs_backing_store(const address_map_entry *entry) +bool address_space::needs_backing_store(const address_map_entry &entry) { // if we are sharing, and we don't have a pointer yet, create one - if (entry->m_share != nullptr) + if (entry.m_share != nullptr) { - std::string fulltag = entry->m_devbase.subtag(entry->m_share); - memory_share *share = manager().m_sharelist.find(fulltag.c_str()); + std::string fulltag = entry.m_devbase.subtag(entry.m_share); + memory_share *share = manager().shares().find(fulltag.c_str()); if (share != nullptr && share->ptr() == nullptr) return true; } // if we're writing to any sort of bank or RAM, then yes, we do need backing - if (entry->m_write.m_type == AMH_BANK || entry->m_write.m_type == AMH_RAM) + if (entry.m_write.m_type == AMH_BANK || entry.m_write.m_type == AMH_RAM) return true; // if we're reading from RAM or from ROM outside of address space 0 or its region, then yes, we do need backing memory_region *region = machine().root_device().memregion(m_device.tag()); - if (entry->m_read.m_type == AMH_RAM || - (entry->m_read.m_type == AMH_ROM && (m_spacenum != AS_0 || region == nullptr || entry->m_addrstart >= region->bytes()))) + if (entry.m_read.m_type == AMH_RAM || + (entry.m_read.m_type == AMH_ROM && (m_spacenum != AS_0 || region == nullptr || entry.m_addrstart >= region->bytes()))) return true; // all other cases don't need backing @@ -2660,16 +2679,8 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst offs_t byteend = addrend; adjust_addresses(bytestart, byteend, bytemask, bytemirror); - // if this bank is named, look it up - memory_bank *membank = nullptr; - if (tag != nullptr) - membank = manager().bank(tag); - - // else try to find an exact match - else - for (membank = manager().m_banklist.first(); membank != nullptr; membank = membank->next()) - if (membank->anonymous() && membank->references_space(*this, ROW_READWRITE) && membank->matches_exactly(bytestart, byteend)) - break; + // look up the bank by name, or else by byte range + memory_bank *membank = (tag != nullptr) ? manager().banks().find(tag) : bank_find_anonymous(bytestart, byteend); // if we don't have a bank yet, find a free one if (membank == nullptr) @@ -2700,6 +2711,21 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst } +//------------------------------------------------- +// bank_find_anonymous - try to find an anonymous +// bank matching the given byte range +//------------------------------------------------- +memory_bank *address_space::bank_find_anonymous(offs_t bytestart, offs_t byteend) const +{ + // try to find an exact match + for (memory_bank &bank : manager().banks()) + if (bank.anonymous() && bank.references_space(*this, ROW_READWRITE) && bank.matches_exactly(bytestart, byteend)) + return &bank; + + // not found + return nullptr; +} + //************************************************************************** // TABLE MANAGEMENT @@ -3502,9 +3528,9 @@ const char *address_table::handler_name(UINT16 entry) const { // banks have names if (entry >= STATIC_BANK1 && entry <= STATIC_BANKMAX) - for (memory_bank *info = m_space.manager().first_bank(); info != nullptr; info = info->next()) - if (info->index() == entry) - return info->name(); + for (memory_bank &info : m_space.manager().banks()) + if (info.index() == entry) + return info.name(); // constant strings for static entries if (entry == STATIC_INVALID) return "invalid"; @@ -3753,9 +3779,9 @@ direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, entry = m_space.read().lookup_live_nowp(byteaddress); // scan our table - for (direct_range *range = m_rangelist[entry].first(); range != nullptr; range = range->next()) - if (byteaddress >= range->m_bytestart && byteaddress <= range->m_byteend) - return range; + for (direct_range &range : m_rangelist[entry]) + if (byteaddress >= range.m_bytestart && byteaddress <= range.m_byteend) + return ⦥ // didn't find out; allocate a new one direct_range *range = m_freerangelist.first(); @@ -3844,12 +3870,12 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen m_byteend(byteend), m_data(reinterpret_cast(memory)) { + offs_t length = byteend + 1 - bytestart; VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space.device().tag(), space.name(), bytestart, byteend, memory)); // allocate a block if needed if (m_data == nullptr) { - offs_t length = byteend + 1 - bytestart; if (length < 4096) { m_allocated.resize(length); @@ -3865,20 +3891,13 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen } // register for saving, but only if we're not part of a memory region - memory_region *region; - for (region = space.machine().memory().first_region(); region != nullptr; region = region->next()) - if (m_data >= region->base() && (m_data + (byteend - bytestart + 1)) < region->end()) - { - VPRINTF(("skipping save of this memory block as it is covered by a memory region\n")); - break; - } - - // if we didn't find a match, register - if (region == nullptr) + if (space.manager().region_containing(m_data, length) != nullptr) + VPRINTF(("skipping save of this memory block as it is covered by a memory region\n")); + else { int bytes_per_element = space.data_width() / 8; std::string name = string_format("%08x-%08x", bytestart, byteend); - space.machine().save().save_memory(nullptr, "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (UINT32)(byteend + 1 - bytestart) / bytes_per_element); + space.machine().save().save_memory(nullptr, "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (UINT32)length / bytes_per_element); } } @@ -3943,10 +3962,10 @@ memory_bank::~memory_bank() // and read/write //------------------------------------------------- -bool memory_bank::references_space(address_space &space, read_or_write readorwrite) const +bool memory_bank::references_space(const address_space &space, read_or_write readorwrite) const { - for (bank_reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - if (ref->matches(space, readorwrite)) + for (bank_reference &ref : m_reflist) + if (ref.matches(space, readorwrite)) return true; return false; } @@ -3974,8 +3993,8 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite) void memory_bank::invalidate_references() { // invalidate all the direct references to any referenced address spaces - for (bank_reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - ref->space().direct().force_update(); + for (bank_reference &ref : m_reflist) + ref.space().direct().force_update(); } diff --git a/src/emu/memory.h b/src/emu/memory.h index 0b2b493a27d..9fa42b49a93 100644 --- a/src/emu/memory.h +++ b/src/emu/memory.h @@ -457,8 +457,9 @@ private: void install_bank_generic(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, memory_bank *rbank, memory_bank *wbank); void adjust_addresses(offs_t &start, offs_t &end, offs_t &mask, offs_t &mirror); void *find_backing_memory(offs_t addrstart, offs_t addrend); - bool needs_backing_store(const address_map_entry *entry); + bool needs_backing_store(const address_map_entry &entry); memory_bank &bank_find_or_allocate(const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read_or_write readorwrite); + memory_bank *bank_find_anonymous(offs_t bytestart, offs_t byteend) const; address_map_entry *block_assign_intersecting(offs_t bytestart, offs_t byteend, UINT8 *base); protected: @@ -551,7 +552,7 @@ class memory_bank address_space &space() const { return m_space; } // does this reference match the space+read/write combination? - bool matches(address_space &space, read_or_write readorwrite) const + bool matches(const address_space &space, read_or_write readorwrite) const { return (&space == &m_space && (readorwrite == ROW_READWRITE || readorwrite == m_readorwrite)); } @@ -592,7 +593,7 @@ public: bool straddles(offs_t bytestart, offs_t byteend) const { return (m_bytestart < byteend && m_byteend > bytestart); } // track and verify address space references to this bank - bool references_space(address_space &space, read_or_write readorwrite) const; + bool references_space(const address_space &space, read_or_write readorwrite) const; void add_reference(address_space &space, read_or_write readorwrite); // set the base explicitly @@ -718,9 +719,6 @@ private: class memory_manager { friend class address_space; - friend class address_table; - friend class device_t; - friend class memory_block; public: // construction/destruction @@ -729,8 +727,9 @@ public: // getters running_machine &machine() const { return m_machine; } - address_space *first_space() const { return m_spacelist.first(); } - memory_region *first_region() const { return m_regionlist.first(); } + const tagged_list &banks() const { return m_banklist; } + const tagged_list ®ions() const { return m_regionlist; } + const tagged_list &shares() const { return m_sharelist; } // dump the internal memory tables to the given file void dump(FILE *file); @@ -741,13 +740,10 @@ public: // regions memory_region *region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian); void region_free(const char *name); + memory_region *region_containing(const void *memory, offs_t bytes) const; private: // internal helpers - memory_bank *first_bank() const { return m_banklist.first(); } - memory_bank *bank(const char *tag) const { return m_banklist.find(tag); } - memory_region *region(const char *tag) { return m_regionlist.find(tag); } - memory_share *shared(const char *tag) { return m_sharelist.find(tag); } void bank_reattach(); // internal state diff --git a/src/emu/render.cpp b/src/emu/render.cpp index aafd0007e4e..a340e226c50 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -183,7 +183,7 @@ inline item_layer get_layer_and_blendmode(const layout_view &view, int index, in // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) const int *layer_order = layer_order_standard; - if (view.first_item(ITEM_LAYER_BACKDROP) != nullptr && view.first_item(ITEM_LAYER_BACKDROP)->next() != nullptr && view.first_item(ITEM_LAYER_OVERLAY) == nullptr) + if (view.items(ITEM_LAYER_BACKDROP).count() > 1 && view.items(ITEM_LAYER_OVERLAY).empty()) layer_order = layer_order_alternate; // select the layer @@ -267,8 +267,8 @@ inline void render_primitive_list::add_reference(void *refptr) inline bool render_primitive_list::has_reference(void *refptr) const { // skip if we already have one - for (reference *ref = m_reflist.first(); ref != nullptr; ref = ref->next()) - if (ref->m_refptr == refptr) + for (reference &ref : m_reflist) + if (ref.m_refptr == refptr) return true; return false; } @@ -1261,16 +1261,16 @@ void render_target::compute_minimum_size(INT32 &minwidth, INT32 &minheight) for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) // iterate over items in the layer - for (layout_view::item *curitem = m_curview->first_item(layer); curitem != nullptr; curitem = curitem->next()) - if (curitem->screen() != nullptr) + for (layout_view::item &curitem : m_curview->items(layer)) + if (curitem.screen() != nullptr) { // use a hard-coded default visible area for vector screens - screen_device *screen = curitem->screen(); + screen_device *screen = curitem.screen(); const rectangle vectorvis(0, 639, 0, 479); const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area(); // apply target orientation to the bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, m_orientation); normalize_bounds(bounds); @@ -1348,10 +1348,10 @@ render_primitive_list &render_target::get_primitives() if (m_curview->layer_enabled(layer)) { // iterate over items in the layer - for (layout_view::item *curitem = m_curview->first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (layout_view::item &curitem : m_curview->items(layer)) { // first apply orientation to the bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, root_xform.orientation); normalize_bounds(bounds); @@ -1361,18 +1361,18 @@ render_primitive_list &render_target::get_primitives() item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; - item_xform.color.r = curitem->color().r * root_xform.color.r; - item_xform.color.g = curitem->color().g * root_xform.color.g; - item_xform.color.b = curitem->color().b * root_xform.color.b; - item_xform.color.a = curitem->color().a * root_xform.color.a; - item_xform.orientation = orientation_add(curitem->orientation(), root_xform.orientation); + item_xform.color.r = curitem.color().r * root_xform.color.r; + item_xform.color.g = curitem.color().g * root_xform.color.g; + item_xform.color.b = curitem.color().b * root_xform.color.b; + item_xform.color.a = curitem.color().a * root_xform.color.a; + item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); item_xform.no_center = false; // if there is no associated element, it must be a screen element - if (curitem->screen() != nullptr) - add_container_primitives(list, item_xform, curitem->screen()->container(), blendmode); + if (curitem.screen() != nullptr) + add_container_primitives(list, item_xform, curitem.screen()->container(), blendmode); else - add_element_primitives(list, item_xform, *curitem->element(), curitem->state(), blendmode); + add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), blendmode); } } } @@ -1399,7 +1399,7 @@ render_primitive_list &render_target::get_primitives() } // process the debug containers - for (render_container *debug = m_debug_containers.first(); debug != nullptr; debug = debug->next()) + for (render_container &debug : m_debug_containers) { object_transform ui_xform; ui_xform.xoffs = 0; @@ -1412,7 +1412,7 @@ render_primitive_list &render_target::get_primitives() ui_xform.no_center = true; // add UI elements - add_container_primitives(list, ui_xform, *debug, BLENDMODE_ALPHA); + add_container_primitives(list, ui_xform, debug, BLENDMODE_ALPHA); } // process the UI if we are the UI target @@ -1523,11 +1523,11 @@ void render_target::debug_append(render_container &container) void render_target::resolve_tags() { - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) + for (layout_file &file : m_filelist) { - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) + for (layout_view &view : file.views()) { - view->resolve_tags(); + view.resolve_tags(); } } } @@ -1783,10 +1783,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const } // iterate over elements - for (render_container::item *curitem = container.first_item(); curitem != nullptr; curitem = curitem->next()) + for (render_container::item &curitem : container.items()) { // compute the oriented bounds - render_bounds bounds = curitem->bounds(); + render_bounds bounds = curitem.bounds(); apply_orientation(bounds, container_xform.orientation); // allocate the primitive and set the transformed bounds/color data @@ -1796,7 +1796,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->bounds.x0 = render_round_nearest(container_xform.xoffs + bounds.x0 * container_xform.xscale); prim->bounds.y0 = render_round_nearest(container_xform.yoffs + bounds.y0 * container_xform.yscale); - if (curitem->internal() & INTERNAL_FLAG_CHAR) + if (curitem.internal() & INTERNAL_FLAG_CHAR) { prim->bounds.x1 = prim->bounds.x0 + render_round_nearest((bounds.x1 - bounds.x0) * container_xform.xscale); prim->bounds.y1 = prim->bounds.y0 + render_round_nearest((bounds.y1 - bounds.y0) * container_xform.yscale); @@ -1808,14 +1808,14 @@ void render_target::add_container_primitives(render_primitive_list &list, const } // compute the color of the primitive - prim->color.r = container_xform.color.r * curitem->color().r; - prim->color.g = container_xform.color.g * curitem->color().g; - prim->color.b = container_xform.color.b * curitem->color().b; - prim->color.a = container_xform.color.a * curitem->color().a; + prim->color.r = container_xform.color.r * curitem.color().r; + prim->color.g = container_xform.color.g * curitem.color().g; + prim->color.b = container_xform.color.b * curitem.color().b; + prim->color.a = container_xform.color.a * curitem.color().a; // now switch off the type bool clipped = true; - switch (curitem->type()) + switch (curitem.type()) { case CONTAINER_ITEM_LINE: // adjust the color for brightness/contrast/gamma @@ -1829,8 +1829,8 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->flags |= PRIMFLAG_TYPE_LINE; // scale the width by the minimum of X/Y scale factors - prim->width = curitem->width() * MIN(container_xform.xscale, container_xform.yscale); - prim->flags |= curitem->flags(); + prim->width = curitem.width() * MIN(container_xform.xscale, container_xform.yscale); + prim->flags |= curitem.flags(); // clip the primitive clipped = render_clip_line(&prim->bounds, &cliprect); @@ -1845,10 +1845,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const normalize_bounds(prim->bounds); // get the scaled bitmap and set the resulting palette - if (curitem->texture() != nullptr) + if (curitem.texture() != nullptr) { // determine the final orientation - int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(curitem->flags()), container_xform.orientation); + int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(curitem.flags()), container_xform.orientation); // based on the swap values, get the scaled final texture int width = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.y1 - prim->bounds.y0) : (prim->bounds.x1 - prim->bounds.x0); @@ -1856,10 +1856,10 @@ void render_target::add_container_primitives(render_primitive_list &list, const width = MIN(width, m_maxtexwidth); height = MIN(height, m_maxtexheight); - curitem->texture()->get_scaled(width, height, prim->texture, list, curitem->flags()); + curitem.texture()->get_scaled(width, height, prim->texture, list, curitem.flags()); // set the palette - prim->texture.palette = curitem->texture()->get_adjusted_palette(container); + prim->texture.palette = curitem.texture()->get_adjusted_palette(container); // determine UV coordinates prim->texcoords = oriented_texcoords[finalorient]; @@ -1868,16 +1868,16 @@ void render_target::add_container_primitives(render_primitive_list &list, const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); // apply the final orientation from the quad flags and then build up the final flags - prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) + prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | PRIMFLAG_TEXORIENT(finalorient) - | PRIMFLAG_TEXFORMAT(curitem->texture()->format()); + | PRIMFLAG_TEXFORMAT(curitem.texture()->format()); prim->flags |= blendmode != -1 ? PRIMFLAG_BLENDMODE(blendmode) - : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); + : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem.flags())); } else { - if (curitem->flags() & PRIMFLAG_VECTORBUF_MASK) + if (curitem.flags() & PRIMFLAG_VECTORBUF_MASK) { // determine UV coordinates prim->texcoords = oriented_texcoords[0]; @@ -1892,7 +1892,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->texture.base = nullptr; // set the basic flags - prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK) + prim->flags = (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); // apply clipping @@ -2041,25 +2041,25 @@ bool render_target::map_point_internal(INT32 target_x, INT32 target_y, render_co if (m_curview->layer_enabled(layer)) { // iterate over items in the layer - for (layout_view::item *item = m_curview->first_item(layer); item != nullptr; item = item->next()) + for (layout_view::item &item : m_curview->items(layer)) { bool checkit; // if we're looking for a particular container, verify that we have the right one if (container != nullptr) - checkit = (item->screen() != nullptr && &item->screen()->container() == container); + checkit = (item.screen() != nullptr && &item.screen()->container() == container); // otherwise, assume we're looking for an input else - checkit = item->has_input(); + checkit = item.has_input(); // this target is worth looking at; now check the point - if (checkit && target_fx >= item->bounds().x0 && target_fx < item->bounds().x1 && target_fy >= item->bounds().y0 && target_fy < item->bounds().y1) + if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1) { // point successfully mapped - mapped_x = (target_fx - item->bounds().x0) / (item->bounds().x1 - item->bounds().x0); - mapped_y = (target_fy - item->bounds().y0) / (item->bounds().y1 - item->bounds().y0); - mapped_input_port = item->input_tag_and_mask(mapped_input_mask); + mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0); + mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0); + mapped_input_port = item.input_tag_and_mask(mapped_input_mask); return true; } } @@ -2077,11 +2077,11 @@ bool render_target::map_point_internal(INT32 target_x, INT32 target_y, render_co layout_view *render_target::view_by_index(int index) const { // scan the list of views within each layout, skipping those that don't apply - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) - if (!(m_flags & RENDER_CREATE_NO_ART) || !view->has_art()) + for (layout_file &file : m_filelist) + for (layout_view &view : file.views()) + if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) if (index-- == 0) - return view; + return &view; return nullptr; } @@ -2097,11 +2097,11 @@ int render_target::view_index(layout_view &targetview) const int index = 0; // scan the list of views within each layout, skipping those that don't apply - for (layout_file *file = m_filelist.first(); file != nullptr; file = file->next()) - for (layout_view *view = file->first_view(); view != nullptr; view = view->next()) - if (!(m_flags & RENDER_CREATE_NO_ART) || !view->has_art()) + for (layout_file &file : m_filelist) + for (layout_view &view : file.views()) + if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) { - if (&targetview == view) + if (&targetview == &view) return index; index++; } @@ -2448,10 +2448,10 @@ void render_target::add_clear_and_optimize_primitive_list(render_primitive_list init_clear_extents(); // scan the list until we hit an intersection quad or a line - for (render_primitive *prim = list.first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : list) { // switch off the type - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: goto done; @@ -2459,32 +2459,32 @@ void render_target::add_clear_and_optimize_primitive_list(render_primitive_list case render_primitive::QUAD: { // stop when we hit an alpha texture - if (PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_PALETTEA16) + if (PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_PALETTEA16) goto done; // if this quad can't be cleanly removed from the extents list, we're done - if (!remove_clear_extent(prim->bounds)) + if (!remove_clear_extent(prim.bounds)) goto done; // change the blendmode on the first primitive to be NONE - if (PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_RGB_MULTIPLY) + if (PRIMFLAG_GET_BLENDMODE(prim.flags) == BLENDMODE_RGB_MULTIPLY) { // RGB multiply will multiply against 0, leaving nothing - set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); - prim->texture.base = nullptr; - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + set_render_color(&prim.color, 1.0f, 0.0f, 0.0f, 0.0f); + prim.texture.base = nullptr; + prim.flags = (prim.flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); } else { // for alpha or add modes, we will blend against 0 or add to 0; treat it like none - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + prim.flags = (prim.flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); } // since alpha is disabled, premultiply the RGB values and reset the alpha to 1.0 - prim->color.r *= prim->color.a; - prim->color.g *= prim->color.a; - prim->color.b *= prim->color.a; - prim->color.a = 1.0f; + prim.color.r *= prim.color.a; + prim.color.g *= prim.color.a; + prim.color.b *= prim.color.a; + prim.color.a = 1.0f; break; } @@ -2546,8 +2546,8 @@ render_manager::~render_manager() bool render_manager::is_live(screen_device &screen) const { // iterate over all live targets and or together their screen masks - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (!target->hidden() && target->view_screens(target->view()).contains(screen)) + for (render_target &target : m_targetlist) + if (!target.hidden() && target.view_screens(target.view()).contains(screen)) return true; return false; } @@ -2562,13 +2562,13 @@ float render_manager::max_update_rate() const { // iterate over all live targets and or together their screen masks float minimum = 0; - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (target->max_update_rate() != 0) + for (render_target &target : m_targetlist) + if (target.max_update_rate() != 0) { if (minimum == 0) - minimum = target->max_update_rate(); + minimum = target.max_update_rate(); else - minimum = MIN(target->max_update_rate(), minimum); + minimum = MIN(target.max_update_rate(), minimum); } return minimum; @@ -2603,10 +2603,10 @@ void render_manager::target_free(render_target *target) render_target *render_manager::target_by_index(int index) const { // count up the targets until we hit the requested index - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - if (!target->hidden()) + for (render_target &target : m_targetlist) + if (!target.hidden()) if (index-- == 0) - return target; + return ⌖ return nullptr; } @@ -2724,8 +2724,8 @@ void render_manager::invalidate_all(void *refptr) return; // loop over targets - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - target->invalidate_all(refptr); + for (render_target &target : m_targetlist) + target.invalidate_all(refptr); } @@ -2735,10 +2735,8 @@ void render_manager::invalidate_all(void *refptr) void render_manager::resolve_tags() { - for (render_target *target = m_targetlist.first(); target != nullptr; target = target->next()) - { - target->resolve_tags(); - } + for (render_target &target : m_targetlist) + target.resolve_tags(); } diff --git a/src/emu/render.h b/src/emu/render.h index 1267d402b1f..623e65a56f6 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -372,6 +372,11 @@ public: // getters render_primitive *first() const { return m_primlist.first(); } + // range iterators + using auto_iterator = simple_list::auto_iterator; + auto_iterator begin() const { return m_primlist.begin(); } + auto_iterator end() const { return m_primlist.end(); } + // lock management void acquire_lock() { m_lock.lock(); } void release_lock() { m_lock.unlock(); } @@ -573,7 +578,7 @@ private: static void overlay_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param); // internal helpers - item *first_item() const { return m_itemlist.first(); } + const simple_list &items() const { return m_itemlist; } item &add_generic(UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb); void recompute_lookups(); void update_palette(); @@ -817,7 +822,7 @@ public: // getters layout_view *next() const { return m_next; } - item *first_item(item_layer layer) const; + const simple_list &items(item_layer layer) const; const char *name() const { return m_name.c_str(); } const render_bounds &bounds() const { return m_bounds; } const render_bounds &screen_bounds() const { return m_scrbounds; } @@ -868,8 +873,8 @@ public: // getters layout_file *next() const { return m_next; } - layout_element *first_element() const { return m_elemlist.first(); } - layout_view *first_view() const { return m_viewlist.first(); } + const simple_list &elements() const { return m_elemlist; } + const simple_list &views() const { return m_viewlist; } private: // internal state @@ -1047,6 +1052,7 @@ public: // targets render_target *target_alloc(const internal_layout *layoutfile = nullptr, UINT32 flags = 0); void target_free(render_target *target); + const simple_list &targets() const { return m_targetlist; } render_target *first_target() const { return m_targetlist.first(); } render_target *target_by_index(int index) const; diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp index 0c5e5d1a51e..8697e681cd2 100644 --- a/src/emu/rendfont.cpp +++ b/src/emu/rendfont.cpp @@ -416,8 +416,19 @@ float render_font::string_width(float height, float aspect, const char *string) { // loop over the string and accumulate widths int totwidth = 0; - for (const unsigned char *ptr = (const unsigned char *)string; *ptr != 0; ptr++) - totwidth += get_char(*ptr).width; + + const char *ends = string + strlen(string); + const char *s = string; + unicode_char schar; + + // loop over characters + while (*s != 0) + { + int scharcount = uchar_from_utf8(&schar, s, ends - s); + totwidth += get_char(schar).width; + s += scharcount; + } + // scale the final result based on height return float(totwidth) * m_scale * height * aspect; diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index bca0afc9b25..5995c16eed2 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -453,7 +453,7 @@ layout_element::layout_element(running_machine &machine, xml_data_node &elemnode m_maxstate = 65536; } - if (m_complist.first() != nullptr) + if (!m_complist.empty()) { // determine the scale/offset for normalization float xoffs = bounds.x0; @@ -462,12 +462,12 @@ layout_element::layout_element(running_machine &machine, xml_data_node &elemnode float yscale = 1.0f / (bounds.y1 - bounds.y0); // normalize all the component bounds - for (component *curcomp = m_complist.first(); curcomp != nullptr; curcomp = curcomp->next()) + for (component &curcomp : m_complist) { - curcomp->m_bounds.x0 = (curcomp->m_bounds.x0 - xoffs) * xscale; - curcomp->m_bounds.x1 = (curcomp->m_bounds.x1 - xoffs) * xscale; - curcomp->m_bounds.y0 = (curcomp->m_bounds.y0 - yoffs) * yscale; - curcomp->m_bounds.y1 = (curcomp->m_bounds.y1 - yoffs) * yscale; + curcomp.m_bounds.x0 = (curcomp.m_bounds.x0 - xoffs) * xscale; + curcomp.m_bounds.x1 = (curcomp.m_bounds.x1 - xoffs) * xscale; + curcomp.m_bounds.y0 = (curcomp.m_bounds.y0 - yoffs) * yscale; + curcomp.m_bounds.y1 = (curcomp.m_bounds.y1 - yoffs) * yscale; } } @@ -515,19 +515,19 @@ void layout_element::element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, c texture *elemtex = (texture *)param; // iterate over components that are part of the current state - for (component *curcomp = elemtex->m_element->m_complist.first(); curcomp != nullptr; curcomp = curcomp->next()) - if (curcomp->m_state == -1 || curcomp->m_state == elemtex->m_state) + for (component &curcomp : elemtex->m_element->m_complist) + if (curcomp.m_state == -1 || curcomp.m_state == elemtex->m_state) { // get the local scaled bounds rectangle bounds; - bounds.min_x = render_round_nearest(curcomp->bounds().x0 * dest.width()); - bounds.min_y = render_round_nearest(curcomp->bounds().y0 * dest.height()); - bounds.max_x = render_round_nearest(curcomp->bounds().x1 * dest.width()); - bounds.max_y = render_round_nearest(curcomp->bounds().y1 * dest.height()); + bounds.min_x = render_round_nearest(curcomp.bounds().x0 * dest.width()); + bounds.min_y = render_round_nearest(curcomp.bounds().y0 * dest.height()); + bounds.max_x = render_round_nearest(curcomp.bounds().x1 * dest.width()); + bounds.max_y = render_round_nearest(curcomp.bounds().y1 * dest.height()); bounds &= dest.cliprect(); // based on the component type, add to the texture - curcomp->draw(elemtex->m_element->machine(), dest, bounds, elemtex->m_state); + curcomp.draw(elemtex->m_element->machine(), dest, bounds, elemtex->m_state); } } @@ -942,11 +942,22 @@ void layout_element::component::draw_text(running_machine &machine, bitmap_argb3 bitmap_argb32 tempbitmap(dest.width(), dest.height()); // loop over characters - for (const char *s = m_string.c_str(); *s != 0; s++) + const char *origs = m_string.c_str(); + const char *ends = origs + strlen(origs); + const char *s = origs; + unicode_char schar; + + // loop over characters + while (*s != 0) { + int scharcount = uchar_from_utf8(&schar, s, ends - s); + + if (scharcount == -1) + break; + // get the font bitmap rectangle chbounds; - font->get_scaled_bitmap_and_bounds(tempbitmap, bounds.height(), aspect, *s, chbounds); + font->get_scaled_bitmap_and_bounds(tempbitmap, bounds.height(), aspect, schar, chbounds); // copy the data into the target for (int y = 0; y < chbounds.height(); y++) @@ -977,7 +988,8 @@ void layout_element::component::draw_text(running_machine &machine, bitmap_argb3 } // advance in the X direction - curx += font->char_width(bounds.height(), aspect, *s); + curx += font->char_width(bounds.height(), aspect, schar); + s += scharcount; } // free the temporary bitmap and font @@ -1100,12 +1112,22 @@ void layout_element::component::draw_reel(running_machine &machine, bitmap_argb3 // allocate a temporary bitmap bitmap_argb32 tempbitmap(dest.width(), dest.height()); + const char *origs = m_stopnames[fruit].c_str(); + const char *ends = origs + strlen(origs); + const char *s = origs; + unicode_char schar; + // loop over characters - for (const char *s = m_stopnames[fruit].c_str(); *s != 0; s++) + while (*s != 0) { + int scharcount = uchar_from_utf8(&schar, s, ends - s); + + if (scharcount == -1) + break; + // get the font bitmap rectangle chbounds; - font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, *s, chbounds); + font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, schar, chbounds); // copy the data into the target for (int y = 0; y < chbounds.height(); y++) @@ -1137,8 +1159,8 @@ void layout_element::component::draw_reel(running_machine &machine, bitmap_argb3 } // advance in the X direction - curx += font->char_width(ourheight/num_shown, aspect, *s); - + curx += font->char_width(ourheight/num_shown, aspect, schar); + s += scharcount; } } @@ -1250,12 +1272,23 @@ void layout_element::component::draw_beltreel(running_machine &machine, bitmap_a // allocate a temporary bitmap bitmap_argb32 tempbitmap(dest.width(), dest.height()); + + const char *origs =m_stopnames[fruit].c_str(); + const char *ends = origs + strlen(origs); + const char *s = origs; + unicode_char schar; + // loop over characters - for (const char *s = m_stopnames[fruit].c_str(); *s != 0; s++) + while (*s != 0) { + int scharcount = uchar_from_utf8(&schar, s, ends - s); + + if (scharcount == -1) + break; + // get the font bitmap rectangle chbounds; - font->get_scaled_bitmap_and_bounds(tempbitmap, dest.height(), aspect, *s, chbounds); + font->get_scaled_bitmap_and_bounds(tempbitmap, dest.height(), aspect, schar, chbounds); // copy the data into the target for (int y = 0; y < chbounds.height(); y++) @@ -1287,8 +1320,8 @@ void layout_element::component::draw_beltreel(running_machine &machine, bitmap_a } // advance in the X direction - curx += font->char_width(dest.height(), aspect, *s); - + curx += font->char_width(dest.height(), aspect, schar); + s += scharcount; } } @@ -2186,21 +2219,22 @@ layout_view::~layout_view() //------------------------------------------------- -// first_item - return the first item in the -// appropriate list +// items - return the appropriate list //------------------------------------------------- -layout_view::item *layout_view::first_item(item_layer layer) const +const simple_list &layout_view::items(item_layer layer) const { + static simple_list s_null_list; + switch (layer) { - case ITEM_LAYER_BACKDROP: return m_backdrop_list.first(); - case ITEM_LAYER_SCREEN: return m_screen_list.first(); - case ITEM_LAYER_OVERLAY: return m_overlay_list.first(); - case ITEM_LAYER_BEZEL: return m_bezel_list.first(); - case ITEM_LAYER_CPANEL: return m_cpanel_list.first(); - case ITEM_LAYER_MARQUEE: return m_marquee_list.first(); - default: return nullptr; + case ITEM_LAYER_BACKDROP: return m_backdrop_list; + case ITEM_LAYER_SCREEN: return m_screen_list; + case ITEM_LAYER_OVERLAY: return m_overlay_list; + case ITEM_LAYER_BEZEL: return m_bezel_list; + case ITEM_LAYER_CPANEL: return m_cpanel_list; + case ITEM_LAYER_MARQUEE: return m_marquee_list; + default: return s_null_list; } } @@ -2235,26 +2269,26 @@ void layout_view::recompute(render_layer_config layerconfig) // only do it if requested if (m_layenabled[layer]) - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { // accumulate bounds if (first) - m_bounds = curitem->m_rawbounds; + m_bounds = curitem.m_rawbounds; else - union_render_bounds(&m_bounds, &curitem->m_rawbounds); + union_render_bounds(&m_bounds, &curitem.m_rawbounds); first = false; // accumulate screen bounds - if (curitem->m_screen != nullptr) + if (curitem.m_screen != nullptr) { if (scrfirst) - m_scrbounds = curitem->m_rawbounds; + m_scrbounds = curitem.m_rawbounds; else - union_render_bounds(&m_scrbounds, &curitem->m_rawbounds); + union_render_bounds(&m_scrbounds, &curitem.m_rawbounds); scrfirst = false; // accumulate the screens in use while we're scanning - m_screens.add(*curitem->m_screen); + m_screens.add(*curitem.m_screen); } } } @@ -2296,12 +2330,12 @@ void layout_view::recompute(render_layer_config layerconfig) // normalize all the item bounds for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { - curitem->m_bounds.x0 = target_bounds.x0 + (curitem->m_rawbounds.x0 - xoffs) * xscale; - curitem->m_bounds.x1 = target_bounds.x0 + (curitem->m_rawbounds.x1 - xoffs) * xscale; - curitem->m_bounds.y0 = target_bounds.y0 + (curitem->m_rawbounds.y0 - yoffs) * yscale; - curitem->m_bounds.y1 = target_bounds.y0 + (curitem->m_rawbounds.y1 - yoffs) * yscale; + curitem.m_bounds.x0 = target_bounds.x0 + (curitem.m_rawbounds.x0 - xoffs) * xscale; + curitem.m_bounds.x1 = target_bounds.x0 + (curitem.m_rawbounds.x1 - xoffs) * xscale; + curitem.m_bounds.y0 = target_bounds.y0 + (curitem.m_rawbounds.y0 - yoffs) * yscale; + curitem.m_bounds.y1 = target_bounds.y0 + (curitem.m_rawbounds.y1 - yoffs) * yscale; } } @@ -2314,9 +2348,9 @@ void layout_view::resolve_tags() { for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) { - for (item *curitem = first_item(layer); curitem != nullptr; curitem = curitem->next()) + for (item &curitem : items(layer)) { - curitem->resolve_tags(); + curitem.resolve_tags(); } } } @@ -2350,9 +2384,12 @@ layout_view::item::item(running_machine &machine, xml_data_node &itemnode, simpl if (name != nullptr) { // search the list of elements for a match - for (m_element = elemlist.first(); m_element != nullptr; m_element = m_element->next()) - if (strcmp(name, m_element->name()) == 0) + for (layout_element &elem : elemlist) + if (strcmp(name, elem.name()) == 0) + { + m_element = &elem; break; + } // error if not found if (m_element == nullptr) diff --git a/src/emu/save.cpp b/src/emu/save.cpp index 6c875bc08ff..d288b9905c7 100644 --- a/src/emu/save.cpp +++ b/src/emu/save.cpp @@ -112,9 +112,9 @@ void save_manager::register_presave(save_prepost_delegate func) fatalerror("Attempt to register callback function after state registration is closed!\n"); // scan for duplicates and push through to the end - for (state_callback *cb = m_presave_list.first(); cb != nullptr; cb = cb->next()) - if (cb->m_func == func) - fatalerror("Duplicate save state function (%s/%s)\n", cb->m_func.name(), func.name()); + for (state_callback &cb : m_presave_list) + if (cb.m_func == func) + fatalerror("Duplicate save state function (%s/%s)\n", cb.m_func.name(), func.name()); // allocate a new entry m_presave_list.append(*global_alloc(state_callback(func))); @@ -133,9 +133,9 @@ void save_manager::register_postload(save_prepost_delegate func) fatalerror("Attempt to register callback function after state registration is closed!\n"); // scan for duplicates and push through to the end - for (state_callback *cb = m_postload_list.first(); cb != nullptr; cb = cb->next()) - if (cb->m_func == func) - fatalerror("Duplicate save state function (%s/%s)\n", cb->m_func.name(), func.name()); + for (state_callback &cb : m_postload_list) + if (cb.m_func == func) + fatalerror("Duplicate save state function (%s/%s)\n", cb.m_func.name(), func.name()); // allocate a new entry m_postload_list.append(*global_alloc(state_callback(func))); @@ -170,15 +170,15 @@ void save_manager::save_memory(device_t *device, const char *module, const char // look for duplicates and an entry to insert in front of state_entry *insert_after = nullptr; - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { // stop when we find an entry whose name is after ours - if (entry->m_name.compare(totalname)>0) + if (entry.m_name.compare(totalname)>0) break; - insert_after = entry; + insert_after = &entry; // error if we are equal - if (entry->m_name.compare(totalname)==0) + if (entry.m_name.compare(totalname)==0) fatalerror("Duplicate save state registration entry (%s)\n", totalname.c_str()); } @@ -221,8 +221,8 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co void save_manager::dispatch_postload() { - for (state_callback *func = m_postload_list.first(); func != nullptr; func = func->next()) - func->m_func(); + for (state_callback &func : m_postload_list) + func.m_func(); } //------------------------------------------------- @@ -252,15 +252,15 @@ save_error save_manager::read_file(emu_file &file) bool flip = NATIVE_ENDIAN_VALUE_LE_BE((header[9] & SS_MSB_FIRST) != 0, (header[9] & SS_MSB_FIRST) == 0); // read all the data, flipping if necessary - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { - UINT32 totalsize = entry->m_typesize * entry->m_typecount; - if (file.read(entry->m_data, totalsize) != totalsize) + UINT32 totalsize = entry.m_typesize * entry.m_typecount; + if (file.read(entry.m_data, totalsize) != totalsize) return STATERR_READ_ERROR; // handle flipping if (flip) - entry->flip_data(); + entry.flip_data(); } // call the post-load functions @@ -277,8 +277,8 @@ save_error save_manager::read_file(emu_file &file) void save_manager::dispatch_presave() { - for (state_callback *func = m_presave_list.first(); func != nullptr; func = func->next()) - func->m_func(); + for (state_callback &func : m_presave_list) + func.m_func(); } //------------------------------------------------- @@ -311,10 +311,10 @@ save_error save_manager::write_file(emu_file &file) dispatch_presave(); // then write all the data - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { - UINT32 totalsize = entry->m_typesize * entry->m_typecount; - if (file.write(entry->m_data, totalsize) != totalsize) + UINT32 totalsize = entry.m_typesize * entry.m_typecount; + if (file.write(entry.m_data, totalsize) != totalsize) return STATERR_WRITE_ERROR; } return STATERR_NONE; @@ -330,15 +330,15 @@ UINT32 save_manager::signature() const { // iterate over entries UINT32 crc = 0; - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + for (state_entry &entry : m_entry_list) { // add the entry name to the CRC - crc = core_crc32(crc, (UINT8 *)entry->m_name.c_str(), entry->m_name.length()); + crc = core_crc32(crc, (UINT8 *)entry.m_name.c_str(), entry.m_name.length()); // add the type and size to the CRC UINT32 temp[2]; - temp[0] = LITTLE_ENDIANIZE_INT32(entry->m_typecount); - temp[1] = LITTLE_ENDIANIZE_INT32(entry->m_typesize); + temp[0] = LITTLE_ENDIANIZE_INT32(entry.m_typecount); + temp[1] = LITTLE_ENDIANIZE_INT32(entry.m_typesize); crc = core_crc32(crc, (UINT8 *)&temp[0], sizeof(temp)); } return crc; @@ -352,8 +352,8 @@ UINT32 save_manager::signature() const void save_manager::dump_registry() const { - for (state_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) - LOG(("%s: %d x %d\n", entry->m_name.c_str(), entry->m_typesize, entry->m_typecount)); + for (state_entry &entry : m_entry_list) + LOG(("%s: %d x %d\n", entry.m_name.c_str(), entry.m_typesize, entry.m_typecount)); } diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp index e0bc57c2fff..2e87a62b06f 100644 --- a/src/emu/schedule.cpp +++ b/src/emu/schedule.cpp @@ -726,8 +726,8 @@ void device_scheduler::compute_perfect_interleave() { // adjust all the actuals; this doesn't affect the current m_quantum_minimum = perfect; - for (quantum_slot *quant = m_quantum_list.first(); quant != nullptr; quant = quant->next()) - quant->m_actual = MAX(quant->m_requested, m_quantum_minimum); + for (quantum_slot &quant : m_quantum_list) + quant.m_actual = MAX(quant.m_requested, m_quantum_minimum); } } } @@ -742,7 +742,7 @@ void device_scheduler::compute_perfect_interleave() void device_scheduler::rebuild_execute_list() { // if we haven't yet set a scheduling quantum, do it now - if (m_quantum_list.first() == nullptr) + if (m_quantum_list.empty()) { // set the core scheduling quantum attotime min_quantum = machine().config().m_minimum_quantum; diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp index 111a1b3232a..952c84ca30a 100644 --- a/src/emu/screen.cpp +++ b/src/emu/screen.cpp @@ -566,8 +566,8 @@ void screen_device::realloc_screen_bitmaps() INT32 effheight = MAX(m_height, m_visarea.max_y + 1); // reize all registered screen bitmaps - for (auto_bitmap_item *item = m_auto_bitmap_list.first(); item != nullptr; item = item->next()) - item->m_bitmap.resize(effwidth, effheight); + for (auto_bitmap_item &item : m_auto_bitmap_list) + item.m_bitmap.resize(effwidth, effheight); // re-set up textures if (m_palette != nullptr) @@ -910,15 +910,13 @@ void screen_device::register_vblank_callback(vblank_state_delegate vblank_callba // validate arguments assert(!vblank_callback.isnull()); - // check if we already have this callback registered - callback_item *item; - for (item = m_callback_list.first(); item != nullptr; item = item->next()) - if (item->m_callback == vblank_callback) - break; + // do nothing if we already have this callback registered + for (callback_item &item : m_callback_list) + if (item.m_callback == vblank_callback) + return; // if not found, register - if (item == nullptr) - m_callback_list.append(*global_alloc(callback_item(vblank_callback))); + m_callback_list.append(*global_alloc(callback_item(vblank_callback))); } @@ -955,8 +953,8 @@ void screen_device::vblank_begin() machine().video().frame_update(); // call the screen specific callbacks - for (callback_item *item = m_callback_list.first(); item != nullptr; item = item->next()) - item->m_callback(*this, true); + for (callback_item &item : m_callback_list) + item.m_callback(*this, true); if (!m_screen_vblank.isnull()) m_screen_vblank(*this, true); @@ -979,8 +977,8 @@ void screen_device::vblank_begin() void screen_device::vblank_end() { // call the screen specific callbacks - for (callback_item *item = m_callback_list.first(); item != nullptr; item = item->next()) - item->m_callback(*this, false); + for (callback_item &item : m_callback_list) + item.m_callback(*this, false); if (!m_screen_vblank.isnull()) m_screen_vblank(*this, false); diff --git a/src/emu/softlist.cpp b/src/emu/softlist.cpp index d554b394c21..e86415b3d35 100644 --- a/src/emu/softlist.cpp +++ b/src/emu/softlist.cpp @@ -128,9 +128,9 @@ const char *software_part::feature(const char *feature_name) const assert(feature_name != nullptr); // scan the feature list for an entry matching feature_name and return the value - for (const feature_list_item *feature = m_featurelist.first(); feature != nullptr; feature = feature->next()) - if (strcmp(feature->name(), feature_name) == 0) - return feature->value(); + for (const feature_list_item &feature : m_featurelist) + if (strcmp(feature.name(), feature_name) == 0) + return feature.value(); return nullptr; } @@ -232,14 +232,14 @@ software_part *software_info::find_part(const char *partname, const char *interf return m_partdata.first(); // look for the part by name and match against the interface if provided - for (software_part *part = m_partdata.first(); part != nullptr; part = part->next()) - if (partname != nullptr && strcmp(partname, part->name()) == 0) + for (software_part &part : m_partdata) + if (partname != nullptr && strcmp(partname, part.name()) == 0) { - if (interface == nullptr || part->matches_interface(interface)) - return part; + if (interface == nullptr || part.matches_interface(interface)) + return ∂ } - else if (partname == nullptr && part->matches_interface(interface)) - return part; + else if (partname == nullptr && part.matches_interface(interface)) + return ∂ return nullptr; } @@ -255,8 +255,8 @@ bool software_info::has_multiple_parts(const char *interface) const int count = 0; // increment the count for each match and stop if we hit more than 1 - for (software_part *part = first_part(); part != nullptr; part = part->next()) - if (part->matches_interface(interface)) + for (software_part &part : m_partdata) + if (part.matches_interface(interface)) if (++count > 1) return true; @@ -338,14 +338,14 @@ void software_list_device::find_approx_matches(const char *name, int matches, so } // iterate over our info (will cause a parse if needed) - for (software_info *swinfo = first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : get_info()) { - software_part *part = swinfo->first_part(); + software_part *part = swinfo.first_part(); if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this)) { // pick the best match between driver name and description - int longpenalty = driver_list::penalty_compare(name, swinfo->longname()); - int shortpenalty = driver_list::penalty_compare(name, swinfo->shortname()); + int longpenalty = driver_list::penalty_compare(name, swinfo.longname()); + int shortpenalty = driver_list::penalty_compare(name, swinfo.shortname()); int curpenalty = MIN(longpenalty, shortpenalty); // insert into the sorted table of matches @@ -361,7 +361,7 @@ void software_list_device::find_approx_matches(const char *name, int matches, so penalty[matchnum + 1] = penalty[matchnum]; list[matchnum + 1] = list[matchnum]; } - list[matchnum] = swinfo; + list[matchnum] = &swinfo; penalty[matchnum] = curpenalty; } } @@ -455,8 +455,8 @@ software_info *software_list_device::find(const char *look_for, software_info *p bool iswild = strchr(look_for, '*') != nullptr || strchr(look_for, '?'); - // find a match (will cause a parse if needed when calling first_software_info) - for (prev = (prev != nullptr) ? prev->next() : first_software_info(); prev != nullptr; prev = prev->next()) + // find a match (will cause a parse if needed when calling get_info) + for (prev = (prev != nullptr) ? prev->next() : get_info().first(); prev != nullptr; prev = prev->next()) if ((iswild && core_strwildcmp(look_for, prev->shortname()) == 0) || core_stricmp(look_for, prev->shortname()) == 0) break; @@ -527,7 +527,7 @@ void software_list_device::internal_validity_check(validity_checker &valid) softlist_map names; softlist_map descriptions; - for (software_info *swinfo = first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : get_info()) { // first parse and output core errors if any if (m_errors.length() > 0) @@ -539,98 +539,98 @@ void software_list_device::internal_validity_check(validity_checker &valid) // Now check if the xml data is valid: // Did we lost any description? - if (swinfo->longname() == nullptr) + if (swinfo.longname() == nullptr) { - osd_printf_error("%s: %s has no description\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no description\n", filename(), swinfo.shortname()); break; } // Did we lost any year? - if (swinfo->year() == nullptr) + if (swinfo.year() == nullptr) { - osd_printf_error("%s: %s has no year\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no year\n", filename(), swinfo.shortname()); break; } // Did we lost any publisher? - if (swinfo->publisher() == nullptr) + if (swinfo.publisher() == nullptr) { - osd_printf_error("%s: %s has no publisher\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no publisher\n", filename(), swinfo.shortname()); break; } // Did we lost the software parts? - if (swinfo->num_parts() == 0) + if (swinfo.parts().empty()) { - osd_printf_error("%s: %s has no part\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s has no part\n", filename(), swinfo.shortname()); break; } // Second, since the xml is fine, run additional checks: // check for duplicate names - if (!names.insert(std::make_pair(swinfo->shortname(), swinfo)).second) + if (!names.insert(std::make_pair(swinfo.shortname(), &swinfo)).second) { - software_info *match = names.find(swinfo->shortname())->second; - osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo->shortname(), match->shortname()); + software_info *match = names.find(swinfo.shortname())->second; + osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), swinfo.shortname(), match->shortname()); } // check for duplicate descriptions - std::string longname = std::string(swinfo->longname()); - if (!descriptions.insert(std::make_pair(strmakelower(longname), swinfo)).second) - osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo->longname(), swinfo->shortname()); + std::string longname = std::string(swinfo.longname()); + if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) + osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname(), swinfo.shortname()); bool is_clone = false; - if (swinfo->parentname() != nullptr) + if (swinfo.parentname() != nullptr) { is_clone = true; - if (strcmp(swinfo->parentname(), swinfo->shortname()) == 0) + if (strcmp(swinfo.parentname(), swinfo.shortname()) == 0) { - osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s is set as a clone of itself\n", filename(), swinfo.shortname()); break; } // make sure the parent exists - software_info *swinfo2 = find(swinfo->parentname()); + software_info *swinfo2 = find(swinfo.parentname()); if (swinfo2 == nullptr) - osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo->parentname(), swinfo->shortname()); + osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname(), swinfo.shortname()); else if (swinfo2->parentname() != nullptr) - osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo->shortname()); + osd_printf_error("%s: %s is a clone of a clone\n", filename(), swinfo.shortname()); } // make sure the driver name is 8 chars or less - if ((is_clone && strlen(swinfo->shortname()) > NAME_LEN_CLONE) || (!is_clone && strlen(swinfo->shortname()) > NAME_LEN_PARENT)) - osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo->shortname(), + if ((is_clone && strlen(swinfo.shortname()) > NAME_LEN_CLONE) || (!is_clone && strlen(swinfo.shortname()) > NAME_LEN_PARENT)) + osd_printf_error("%s: %s %s driver name must be %d characters or less\n", filename(), swinfo.shortname(), is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); // make sure the year is only digits, '?' or '+' - for (const char *s = swinfo->year(); *s != 0; s++) + for (const char *s = swinfo.year(); *s != 0; s++) if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') { - osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo->shortname(), swinfo->year()); + osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), swinfo.shortname(), swinfo.year()); break; } softlist_map part_names; - for (software_part *part = swinfo->first_part(); part != nullptr; part = part->next()) + for (software_part &part : swinfo.parts()) { - if (part->interface() == nullptr) - osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo->shortname(), part->name()); + if (part.interface() == nullptr) + osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), swinfo.shortname(), part.name()); - if (part->romdata() == nullptr) - osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo->shortname(), part->name()); + if (part.romdata() == nullptr) + osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), swinfo.shortname(), part.name()); - if (!part_names.insert(std::make_pair(part->name(), swinfo)).second) - osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo->shortname(), part->name()); + if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) + osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), swinfo.shortname(), part.name()); - for (const rom_entry *data = part->romdata(); data->_name != nullptr; data++) + for (const rom_entry *data = part.romdata(); data->_name != nullptr; data++) if (data->_hashdata != nullptr) { // make sure the hash is valid hash_collection hashes; if (!hashes.from_internal_string(data->_hashdata)) - osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo->shortname(), data->_name, data->_hashdata); + osd_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", filename(), swinfo.shortname(), data->_name, data->_hashdata); } } } @@ -1253,7 +1253,7 @@ void softlist_parser::parse_soft_end(const char *tagname) // get the info; if present, copy shared data (we assume name/value strings live // in the string pool and don't need to be reallocated) if (m_current_info != nullptr) - for (feature_list_item *item = m_current_info->shared_info(); item != nullptr; item = item->next()) - m_current_part->m_featurelist.append(*global_alloc(feature_list_item(item->name(), item->value()))); + for (feature_list_item &item : m_current_info->shared_info()) + m_current_part->m_featurelist.append(*global_alloc(feature_list_item(item.name(), item.value()))); } } diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 63ce6f0da20..09fa6981cd2 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -111,7 +111,7 @@ public: software_info &info() const { return m_info; } const char *name() const { return m_name; } const char *interface() const { return m_interface; } - feature_list_item *featurelist() const { return m_featurelist.first(); } + const simple_list &featurelist() const { return m_featurelist; } rom_entry *romdata(unsigned int index = 0) { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; } // helpers @@ -150,12 +150,11 @@ public: const char *parentname() const { return m_parentname; } const char *year() const { return m_year; } const char *publisher() const { return m_publisher; } - feature_list_item *other_info() const { return m_other_info.first(); } - feature_list_item *shared_info() const { return m_shared_info.first(); } + const simple_list &other_info() const { return m_other_info; } + const simple_list &shared_info() const { return m_shared_info; } UINT32 supported() const { return m_supported; } - int num_parts() const { return m_partdata.count(); } + const simple_list &parts() const { return m_partdata; } software_part *first_part() const { return m_partdata.first(); } - software_part *last_part() const { return m_partdata.last(); } // additional operations software_part *find_part(const char *partname, const char *interface = nullptr); @@ -203,10 +202,10 @@ public: const char *description() { if (!m_parsed) parse(); return m_description; } bool valid() { if (!m_parsed) parse(); return m_infolist.count() > 0; } const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); } + const simple_list &get_info() { if (!m_parsed) parse(); return m_infolist; } // operations software_info *find(const char *look_for, software_info *prev = nullptr); - software_info *first_software_info() { if (!m_parsed) parse(); return m_infolist.first(); } void find_approx_matches(const char *name, int matches, software_info **list, const char *interface); void release(); diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index 47e7dcc90e8..12093cb0689 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -1090,15 +1090,15 @@ void sound_manager::update(void *ptr, int param) } // iterate over all the streams and update them - for (sound_stream *stream = m_stream_list.first(); stream != nullptr; stream = stream->next()) - stream->update_with_accounting(second_tick); + for (sound_stream &stream : m_stream_list) + stream.update_with_accounting(second_tick); // remember the update time m_last_update = curtime; // update sample rates if they have changed - for (sound_stream *stream = m_stream_list.first(); stream != nullptr; stream = stream->next()) - stream->apply_sample_rate_changes(); + for (sound_stream &stream : m_stream_list) + stream.apply_sample_rate_changes(); g_profiler.stop(); } diff --git a/src/emu/sound.h b/src/emu/sound.h index b3584969284..1776c07c756 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -199,7 +199,7 @@ public: // getters running_machine &machine() const { return m_machine; } int attenuation() const { return m_attenuation; } - sound_stream *first_stream() const { return m_stream_list.first(); } + const simple_list &streams() const { return m_stream_list; } attotime last_update() const { return m_last_update; } attoseconds_t update_attoseconds() const { return m_update_attoseconds; } diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp index 807c1b30cf8..69bde8821c0 100644 --- a/src/emu/tilemap.cpp +++ b/src/emu/tilemap.cpp @@ -1503,11 +1503,11 @@ tilemap_manager::~tilemap_manager() while (found) { found = false; - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - if (tmap->device() != nullptr) + for (tilemap_t &tmap : m_tilemap_list) + if (tmap.device() != nullptr) { found = true; - m_tilemap_list.detach(*tmap); + m_tilemap_list.detach(tmap); break; } } @@ -1553,8 +1553,8 @@ tilemap_t &tilemap_manager::create(device_gfx_interface &decoder, tilemap_get_in void tilemap_manager::set_flip_all(UINT32 attributes) { - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - tmap->set_flip(attributes); + for (tilemap_t &tmap : m_tilemap_list) + tmap.set_flip(attributes); } @@ -1565,8 +1565,8 @@ void tilemap_manager::set_flip_all(UINT32 attributes) void tilemap_manager::mark_all_dirty() { - for (tilemap_t *tmap = m_tilemap_list.first(); tmap != nullptr; tmap = tmap->next()) - tmap->mark_all_dirty(); + for (tilemap_t &tmap : m_tilemap_list) + tmap.mark_all_dirty(); } diff --git a/src/emu/ui/cheatopt.cpp b/src/emu/ui/cheatopt.cpp index ceb2c3301f5..fecb954cd0f 100644 --- a/src/emu/ui/cheatopt.cpp +++ b/src/emu/ui/cheatopt.cpp @@ -36,8 +36,8 @@ void ui_menu_cheat::handle() /* handle reset all + reset all cheats for reload all option */ if ((menu_event->itemref == ITEMREF_CHEATS_RESET_ALL || menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL) && menu_event->iptkey == IPT_UI_SELECT) { - for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) - if (curcheat->select_default_state()) + for (cheat_entry &curcheat : machine().cheat().entries()) + if (curcheat.select_default_state()) changed = true; } @@ -124,12 +124,12 @@ void ui_menu_cheat::populate() item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); // add other cheats - if (machine().cheat().first() != nullptr) { - for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) + if (!machine().cheat().entries().empty()) { + for (cheat_entry &curcheat : machine().cheat().entries()) { UINT32 flags; - curcheat->menu_text(text, subtext, flags); - item_append(text.c_str(), subtext.c_str(), flags, curcheat); + curcheat.menu_text(text, subtext, flags); + item_append(text.c_str(), subtext.c_str(), flags, &curcheat); } /* add a separator */ @@ -249,8 +249,6 @@ void ui_menu_autofire::handle() void ui_menu_autofire::populate() { - ioport_field *field; - ioport_port *port; char temp_text[64]; /* add autofire toggle item */ @@ -260,16 +258,16 @@ void ui_menu_autofire::populate() /* iterate over the input ports and add autofire toggle items */ int menu_items = 0; - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : machine().ioport().ports()) { bool is_first_button = true; - for (field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { - if ((field->name()) && ((field->type() >= IPT_BUTTON1 && field->type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15))) + if ((field.name()) && ((field.type() >= IPT_BUTTON1 && field.type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15))) { menu_items++; ioport_field::user_settings settings; - field->get_user_settings(settings); + field.get_user_settings(settings); if (is_first_button) { @@ -281,13 +279,13 @@ void ui_menu_autofire::populate() if (!autofire_toggle) { // item is enabled and can be switched to values on/off - item_append(field->name(), (settings.autofire ? _("On") : _("Off")), - (settings.autofire ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW), (void *)field); + item_append(field.name(), (settings.autofire ? _("On") : _("Off")), + (settings.autofire ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW), (void *)&field); } else { // item is disabled - item_append(field->name(), (settings.autofire ? _("On") : _("Off")), + item_append(field.name(), (settings.autofire ? _("On") : _("Off")), MENU_FLAG_DISABLE | MENU_FLAG_INVERT, nullptr); } } diff --git a/src/emu/ui/custui.cpp b/src/emu/ui/custui.cpp index 816875131dc..6eabfeb65b1 100644 --- a/src/emu/ui/custui.cpp +++ b/src/emu/ui/custui.cpp @@ -215,18 +215,18 @@ ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *con m_info_size = moptions.infos_size(); m_font_size = moptions.font_rows(); - for (ui_options::entry *f_entry = moptions.first(); f_entry != nullptr; f_entry = f_entry->next()) + for (ui_options::entry &f_entry : moptions) { - const char *name = f_entry->name(); - if (name && strlen(name) && !strcmp(OPTION_INFOS_SIZE, f_entry->name())) + const char *name = f_entry.name(); + if (name && strlen(name) && !strcmp(OPTION_INFOS_SIZE, f_entry.name())) { - m_info_max = atof(f_entry->maximum()); - m_info_min = atof(f_entry->minimum()); + m_info_max = atof(f_entry.maximum()); + m_info_min = atof(f_entry.minimum()); } - else if (name && strlen(name) && !strcmp(OPTION_FONT_ROWS, f_entry->name())) + else if (name && strlen(name) && !strcmp(OPTION_FONT_ROWS, f_entry.name())) { - m_font_max = atof(f_entry->maximum()); - m_font_min = atof(f_entry->minimum()); + m_font_max = atof(f_entry.maximum()); + m_font_min = atof(f_entry.minimum()); } } diff --git a/src/emu/ui/devopt.cpp b/src/emu/ui/devopt.cpp index bafb8e77114..bc99b960e81 100644 --- a/src/emu/ui/devopt.cpp +++ b/src/emu/ui/devopt.cpp @@ -189,47 +189,47 @@ void ui_menu_device_config::populate() portlist.append(*iptdev, errors); // check if the device adds inputs to the system - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_port &port : portlist) + for (ioport_field &field : port.fields()) { - if (field->type() >= IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST) + if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) input_mj++; - else if (field->type() >= IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST) + else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) input_hana++; - else if (field->type() >= IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST) + else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) input_gamble++; - else if (field->type() >= IPT_ANALOG_FIRST && field->type() < IPT_ANALOG_LAST) + else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST) input_analog++; - else if (field->type() == IPT_ADJUSTER) + else if (field.type() == IPT_ADJUSTER) input_adjust++; - else if (field->type() == IPT_KEYPAD) + else if (field.type() == IPT_KEYPAD) input_keypad++; - else if (field->type() == IPT_KEYBOARD) + else if (field.type() == IPT_KEYBOARD) input_keyboard++; - else if (field->type() >= IPT_START1 && field->type() < IPT_UI_FIRST) + else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) input++; - else if (field->type() == IPT_DIPSWITCH) + else if (field.type() == IPT_DIPSWITCH) { dips++; - dips_opt << " " << field->name(); - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + dips_opt << " " << field.name(); + for (ioport_setting &setting : field.settings()) { - if (setting->value() == field->defvalue()) + if (setting.value() == field.defvalue()) { - util::stream_format(dips_opt, " [default: %s]\n", setting->name()); + util::stream_format(dips_opt, " [default: %s]\n", setting.name()); break; } } } - else if (field->type() == IPT_CONFIG) + else if (field.type() == IPT_CONFIG) { confs++; - confs_opt << " " << field->name(); - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) + confs_opt << " " << field.name(); + for (ioport_setting &setting : field.settings()) { - if (setting->value() == field->defvalue()) + if (setting.value() == field.defvalue()) { - util::stream_format(confs_opt, " [default: %s]\n", setting->name()); + util::stream_format(confs_opt, " [default: %s]\n", setting.name()); break; } } diff --git a/src/emu/ui/filesel.cpp b/src/emu/ui/filesel.cpp index 58b3d338ffe..7acab761ea5 100644 --- a/src/emu/ui/filesel.cpp +++ b/src/emu/ui/filesel.cpp @@ -275,7 +275,7 @@ void ui_menu_file_create::populate() item_append(_("New Image Name:"), new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); // do we support multiple formats? - if (ENABLE_FORMATS) format = m_image->formatlist(); + if (ENABLE_FORMATS) format = m_image->formatlist().first(); if (ENABLE_FORMATS && (format != nullptr)) { item_append(_("Image Format:"), m_current_format->description(), 0, ITEMREF_FORMAT); diff --git a/src/emu/ui/inifile.cpp b/src/emu/ui/inifile.cpp index 33bd433a7f7..3324d56363e 100644 --- a/src/emu/ui/inifile.cpp +++ b/src/emu/ui/inifile.cpp @@ -231,21 +231,21 @@ void favorite_manager::add_favorite_game() if (swinfo->parentname()) { software_list_device *swlist = software_list_device::find_by_name(machine().config(), image->software_list_name()); - for (software_info *c_swinfo = swlist->first_software_info(); c_swinfo != nullptr; c_swinfo = c_swinfo->next()) + for (software_info &c_swinfo : swlist->get_info()) { - std::string c_parent(c_swinfo->parentname()); + std::string c_parent(c_swinfo.parentname()); if (!c_parent.empty() && c_parent == swinfo->shortname()) { - tmpmatches.parentlongname = c_swinfo->longname(); + tmpmatches.parentlongname = c_swinfo.longname(); break; } } } tmpmatches.usage.clear(); - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - if (!strcmp(flist->name(), "usage")) - tmpmatches.usage = flist->value(); + for (feature_list_item &flist : swinfo->other_info()) + if (!strcmp(flist.name(), "usage")) + tmpmatches.usage = flist.value(); tmpmatches.devicetype = strensure(image->image_type_name()); tmpmatches.available = true; diff --git a/src/emu/ui/inputmap.cpp b/src/emu/ui/inputmap.cpp index df146fcf3e1..616e3e80bfa 100644 --- a/src/emu/ui/inputmap.cpp +++ b/src/emu/ui/inputmap.cpp @@ -100,10 +100,10 @@ void ui_menu_input_general::populate() suborder[SEQ_TYPE_INCREMENT] = 2; /* iterate over the input ports and add menu items */ - for (input_type_entry *entry = machine().ioport().first_type(); entry != nullptr; entry = entry->next()) + for (input_type_entry &entry : machine().ioport().types()) /* add if we match the group and we have a valid name */ - if (entry->group() == group && entry->name() != nullptr && entry->name()[0] != 0) + if (entry.group() == group && entry.name() != nullptr && entry.name()[0] != 0) { input_seq_type seqtype; @@ -114,15 +114,15 @@ void ui_menu_input_general::populate() /* build an entry for the standard sequence */ input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); memset(item, 0, sizeof(*item)); - item->ref = entry; - if(pollingitem && pollingref == entry && pollingseq == seqtype) + item->ref = &entry; + if(pollingitem && pollingref == &entry && pollingseq == seqtype) pollingitem = item; item->seqtype = seqtype; - item->seq = machine().ioport().type_seq(entry->type(), entry->player(), seqtype); - item->defseq = &entry->defseq(seqtype); + item->seq = machine().ioport().type_seq(entry.type(), entry.player(), seqtype); + item->defseq = &entry.defseq(seqtype); item->sortorder = sortorder * 4 + suborder[seqtype]; - item->type = ioport_manager::type_is_analog(entry->type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; - item->name = entry->name(); + item->type = ioport_manager::type_is_analog(entry.type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; + item->name = entry.name(); item->owner_name = nullptr; item->next = itemlist; itemlist = item; @@ -162,29 +162,29 @@ void ui_menu_input_specific::populate() suborder[SEQ_TYPE_INCREMENT] = 2; /* iterate over the input ports and add menu items */ - for (ioport_port *port = machine().ioport().first_port(); port != nullptr; port = port->next()) + for (ioport_port &port : machine().ioport().ports()) { port_count++; - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { - const char *name = field->name(); + const char *name = field.name(); /* add if we match the group and we have a valid name */ - if (name != nullptr && field->enabled() && - ((field->type() == IPT_OTHER && field->name() != nullptr) || machine().ioport().type_group(field->type(), field->player()) != IPG_INVALID)) + if (name != nullptr && field.enabled() && + ((field.type() == IPT_OTHER && field.name() != nullptr) || machine().ioport().type_group(field.type(), field.player()) != IPG_INVALID)) { input_seq_type seqtype; UINT32 sortorder; /* determine the sorting order */ - if (field->type() >= IPT_START1 && field->type() < IPT_ANALOG_LAST) + if (field.type() >= IPT_START1 && field.type() < IPT_ANALOG_LAST) { - sortorder = (field->type() << 2) | (field->player() << 12); - if (strcmp(field->device().tag(), ":")) + sortorder = (field.type() << 2) | (field.player() << 12); + if (strcmp(field.device().tag(), ":")) sortorder |= (port_count & 0xfff) * 0x10000; } else - sortorder = field->type() | 0xf000; + sortorder = field.type() | 0xf000; /* loop over all sequence types */ for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) @@ -192,16 +192,16 @@ void ui_menu_input_specific::populate() /* build an entry for the standard sequence */ input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); memset(item, 0, sizeof(*item)); - item->ref = field; + item->ref = &field; item->seqtype = seqtype; - if(pollingitem && pollingref == field && pollingseq == seqtype) + if(pollingitem && pollingref == item->ref && pollingseq == seqtype) pollingitem = item; - item->seq = field->seq(seqtype); - item->defseq = &field->defseq(seqtype); + item->seq = field.seq(seqtype); + item->defseq = &field.defseq(seqtype); item->sortorder = sortorder + suborder[seqtype]; - item->type = field->is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; + item->type = field.is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; item->name = name; - item->owner_name = field->device().tag(); + item->owner_name = field.device().tag(); item->next = itemlist; itemlist = item; @@ -537,8 +537,6 @@ ui_menu_settings::ui_menu_settings(running_machine &machine, render_container *c void ui_menu_settings::populate() { - ioport_field *field; - ioport_port *port; dip_descriptor **diplist_tailptr; std::string prev_owner; bool first_entry = true; @@ -549,51 +547,50 @@ void ui_menu_settings::populate() diplist_tailptr = &diplist; /* loop over input ports and set up the current values */ - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == type && field->enabled()) + for (ioport_port &port : machine().ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.type() == type && field.enabled()) { UINT32 flags = 0; /* set the left/right flags appropriately */ - if (field->has_previous_setting()) + if (field.has_previous_setting()) flags |= MENU_FLAG_LEFT_ARROW; - if (field->has_next_setting()) + if (field.has_next_setting()) flags |= MENU_FLAG_RIGHT_ARROW; /* add the menu item */ - if (strcmp(field->device().tag(), prev_owner.c_str()) != 0) + if (strcmp(field.device().tag(), prev_owner.c_str()) != 0) { if (first_entry) first_entry = false; else item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); - string_format("[root%s]", field->device().tag()); - item_append(string_format("[root%s]", field->device().tag()).c_str(), nullptr, 0, nullptr); - prev_owner.assign(field->device().tag()); + string_format("[root%s]", field.device().tag()); + item_append(string_format("[root%s]", field.device().tag()).c_str(), nullptr, 0, nullptr); + prev_owner.assign(field.device().tag()); } - item_append(field->name(), field->setting_name(), flags, (void *)field); + item_append(field.name(), field.setting_name(), flags, (void *)&field); /* for DIP switches, build up the model */ - if (type == IPT_DIPSWITCH && field->first_diplocation() != nullptr) + if (type == IPT_DIPSWITCH && !field.diplocations().empty()) { - const ioport_diplocation *diploc; ioport_field::user_settings settings; - UINT32 accummask = field->mask(); + UINT32 accummask = field.mask(); /* get current settings */ - field->get_user_settings(settings); + field.get_user_settings(settings); /* iterate over each bit in the field */ - for (diploc = field->first_diplocation(); diploc != nullptr; diploc = diploc->next()) + for (const ioport_diplocation &diploc : field.diplocations()) { UINT32 mask = accummask & ~(accummask - 1); dip_descriptor *dip; /* find the matching switch name */ for (dip = diplist; dip != nullptr; dip = dip->next) - if (strcmp(dip->name, diploc->name()) == 0) + if (strcmp(dip->name, diploc.name()) == 0) break; /* allocate new if none */ @@ -601,7 +598,7 @@ void ui_menu_settings::populate() { dip = (dip_descriptor *)m_pool_alloc(sizeof(*dip)); dip->next = nullptr; - dip->name = diploc->name(); + dip->name = diploc.name(); dip->mask = dip->state = 0; *diplist_tailptr = dip; diplist_tailptr = &dip->next; @@ -609,9 +606,9 @@ void ui_menu_settings::populate() } /* apply the bits */ - dip->mask |= 1 << (diploc->number() - 1); - if (((settings.value & mask) != 0 && !diploc->inverted()) || ((settings.value & mask) == 0 && diploc->inverted())) - dip->state |= 1 << (diploc->number() - 1); + dip->mask |= 1 << (diploc.number() - 1); + if (((settings.value & mask) != 0 && !diploc.inverted()) || ((settings.value & mask) == 0 && diploc.inverted())) + dip->state |= 1 << (diploc.number() - 1); /* clear the relevant bit in the accumulated mask */ accummask &= ~mask; @@ -651,7 +648,6 @@ void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, // iterate over DIP switches for (dip_descriptor *dip = diplist; dip != nullptr; dip = dip->next) { - const ioport_diplocation *diploc; UINT32 selectedmask = 0; // determine the mask of selected bits @@ -659,10 +655,10 @@ void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, { ioport_field *field = (ioport_field *)selectedref; - if (field != nullptr && field->first_diplocation() != nullptr) - for (diploc = field->first_diplocation(); diploc != nullptr; diploc = diploc->next()) - if (strcmp(dip->name, diploc->name()) == 0) - selectedmask |= 1 << (diploc->number() - 1); + if (field != nullptr && !field->diplocations().empty()) + for (const ioport_diplocation &diploc : field->diplocations()) + if (strcmp(dip->name, diploc.name()) == 0) + selectedmask |= 1 << (diploc.number() - 1); } // draw one switch @@ -815,28 +811,26 @@ ui_menu_analog::ui_menu_analog(running_machine &machine, render_container *conta void ui_menu_analog::populate() { - ioport_field *field; - ioport_port *port; std::string text; std::string subtext; std::string prev_owner; bool first_entry = true; /* loop over input ports and add the items */ - for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->is_analog() && field->enabled()) + for (ioport_port &port : machine().ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.is_analog() && field.enabled()) { ioport_field::user_settings settings; int use_autocenter = false; int type; /* based on the type, determine if we enable autocenter */ - switch (field->type()) + switch (field.type()) { case IPT_POSITIONAL: case IPT_POSITIONAL_V: - if (field->analog_wraps()) + if (field.analog_wraps()) break; case IPT_AD_STICK_X: @@ -855,7 +849,7 @@ void ui_menu_analog::populate() } /* get the user settings */ - field->get_user_settings(settings); + field.get_user_settings(settings); /* iterate over types */ for (type = 0; type < ANALOG_ITEM_COUNT; type++) @@ -863,19 +857,19 @@ void ui_menu_analog::populate() { analog_item_data *data; UINT32 flags = 0; - if (strcmp(field->device().tag(), prev_owner.c_str()) != 0) + if (strcmp(field.device().tag(), prev_owner.c_str()) != 0) { if (first_entry) first_entry = false; else item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); - item_append(string_format("[root%s]", field->device().tag()).c_str(), nullptr, 0, nullptr); - prev_owner.assign(field->device().tag()); + item_append(string_format("[root%s]", field.device().tag()).c_str(), nullptr, 0, nullptr); + prev_owner.assign(field.device().tag()); } /* allocate a data item for tracking what this menu item refers to */ data = (analog_item_data *)m_pool_alloc(sizeof(*data)); - data->field = field; + data->field = &field; data->type = type; /* determine the properties of this item */ @@ -883,39 +877,39 @@ void ui_menu_analog::populate() { default: case ANALOG_ITEM_KEYSPEED: - text = string_format("%s Digital Speed", field->name()); + text = string_format("%s Digital Speed", field.name()); subtext = string_format("%d", settings.delta); data->min = 0; data->max = 255; data->cur = settings.delta; - data->defvalue = field->delta(); + data->defvalue = field.delta(); break; case ANALOG_ITEM_CENTERSPEED: - text = string_format("%s Autocenter Speed", field->name()); + text = string_format("%s Autocenter Speed", field.name()); subtext = string_format("%d", settings.centerdelta); data->min = 0; data->max = 255; data->cur = settings.centerdelta; - data->defvalue = field->centerdelta(); + data->defvalue = field.centerdelta(); break; case ANALOG_ITEM_REVERSE: - text = string_format("%s Reverse", field->name()); + text = string_format("%s Reverse", field.name()); subtext.assign(settings.reverse ? "On" : "Off"); data->min = 0; data->max = 1; data->cur = settings.reverse; - data->defvalue = field->analog_reverse(); + data->defvalue = field.analog_reverse(); break; case ANALOG_ITEM_SENSITIVITY: - text = string_format("%s Sensitivity", field->name()); + text = string_format("%s Sensitivity", field.name()); subtext = string_format("%d", settings.sensitivity); data->min = 1; data->max = 255; data->cur = settings.sensitivity; - data->defvalue = field->sensitivity(); + data->defvalue = field.sensitivity(); break; } diff --git a/src/emu/ui/miscmenu.cpp b/src/emu/ui/miscmenu.cpp index 3846244d73e..edca54ebd20 100644 --- a/src/emu/ui/miscmenu.cpp +++ b/src/emu/ui/miscmenu.cpp @@ -942,13 +942,13 @@ void ui_menu_plugins_configure::populate() { plugin_options& plugins = machine().manager().plugins(); - for (auto curentry = plugins.first(); curentry != nullptr; curentry = curentry->next()) + for (auto &curentry : plugins) { - if (!curentry->is_header()) + if (!curentry.is_header()) { - auto enabled = std::string(curentry->value()) == "1"; - item_append(curentry->description(), enabled ? _("On") : _("Off"), - enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)curentry->name()); + auto enabled = std::string(curentry.value()) == "1"; + item_append(curentry.description(), enabled ? _("On") : _("Off"), + enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)curentry.name()); } } item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp index a87de984694..fef44b8e542 100644 --- a/src/emu/ui/optsmenu.cpp +++ b/src/emu/ui/optsmenu.cpp @@ -346,11 +346,11 @@ void save_main_option(running_machine &machine) } } - for (emu_options::entry *f_entry = machine.options().first(); f_entry != nullptr; f_entry = f_entry->next()) + for (emu_options::entry &f_entry : machine.options()) { - if (f_entry->is_changed()) + if (f_entry.is_changed()) { - options.set_value(f_entry->name(), f_entry->value(), OPTION_PRIORITY_CMDLINE, error_string); + options.set_value(f_entry.name(), f_entry.value(), OPTION_PRIORITY_CMDLINE, error_string); } } diff --git a/src/emu/ui/selgame.cpp b/src/emu/ui/selgame.cpp index 28b3a295b05..1ac26804bb5 100644 --- a/src/emu/ui/selgame.cpp +++ b/src/emu/ui/selgame.cpp @@ -1038,7 +1038,7 @@ void ui_menu_select_game::inkey_select(const ui_menu_event *m_event) { software_list_device_iterator iter(enumerator.config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) - if (swlistdev->first_software_info() != nullptr) + if (!swlistdev->get_info().empty()) { ui_menu::stack_push(global_alloc_clear(machine(), container, driver)); return; @@ -1149,14 +1149,14 @@ void ui_menu_select_game::inkey_select_favorite(const ui_menu_event *m_event) else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); diff --git a/src/emu/ui/selsoft.cpp b/src/emu/ui/selsoft.cpp index 050b9409061..0022297f6c8 100644 --- a/src/emu/ui/selsoft.cpp +++ b/src/emu/ui/selsoft.cpp @@ -533,9 +533,9 @@ void ui_menu_select_software::build_software_list() { m_filter.swlist.name.push_back(swlist->list_name()); m_filter.swlist.description.push_back(swlist->description()); - for (software_info *swinfo = swlist->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (software_info &swinfo : swlist->get_info()) { - software_part *part = swinfo->first_part(); + software_part *part = swinfo.first_part(); if (part->is_compatible(*swlist)) { const char *instance_name = nullptr; @@ -561,12 +561,12 @@ void ui_menu_select_software::build_software_list() if (instance_name == nullptr || type_name == nullptr) continue; - tmpmatches.shortname = strensure(swinfo->shortname()); - tmpmatches.longname = strensure(swinfo->longname()); - tmpmatches.parentname = strensure(swinfo->parentname()); - tmpmatches.year = strensure(swinfo->year()); - tmpmatches.publisher = strensure(swinfo->publisher()); - tmpmatches.supported = swinfo->supported(); + tmpmatches.shortname = strensure(swinfo.shortname()); + tmpmatches.longname = strensure(swinfo.longname()); + tmpmatches.parentname = strensure(swinfo.parentname()); + tmpmatches.year = strensure(swinfo.year()); + tmpmatches.publisher = strensure(swinfo.publisher()); + tmpmatches.supported = swinfo.supported(); tmpmatches.part = strensure(part->name()); tmpmatches.driver = m_driver; tmpmatches.listname = strensure(swlist->list_name()); @@ -576,9 +576,9 @@ void ui_menu_select_software::build_software_list() tmpmatches.usage.clear(); tmpmatches.available = false; - for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) - if (!strcmp(flist->name(), "usage")) - tmpmatches.usage = flist->value(); + for (feature_list_item &flist : swinfo.other_info()) + if (!strcmp(flist.name(), "usage")) + tmpmatches.usage = flist.value(); m_swinfo.push_back(tmpmatches); m_filter.region.set(tmpmatches.longname); @@ -937,14 +937,14 @@ void ui_menu_select_software::inkey_select(const ui_menu_event *m_event) else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); @@ -2091,14 +2091,14 @@ void ui_bios_selection::handle() if (!machine().ui().options().skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str())) { s_parts parts; - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo->parts()) { - if (swpart->matches_interface(ui_swinfo->interface.c_str())) + if (swpart.matches_interface(ui_swinfo->interface.c_str())) { - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.assign("(").append(swpart->feature("part_id")).append(")"); - parts.emplace(swpart->name(), menu_part_name); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.assign("(").append(swpart.feature("part_id")).append(")"); + parts.emplace(swpart.name(), menu_part_name); } } ui_menu::stack_push(global_alloc_clear(machine(), container, parts, ui_swinfo)); diff --git a/src/emu/ui/slotopt.cpp b/src/emu/ui/slotopt.cpp index c4fd58f754f..693c28a9ba8 100644 --- a/src/emu/ui/slotopt.cpp +++ b/src/emu/ui/slotopt.cpp @@ -45,12 +45,12 @@ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) if (current != nullptr) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { - if (option == current) + if (&option == current) return val; - if (option->selectable()) + if (option.selectable()) val++; } } @@ -64,8 +64,8 @@ int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) - if (option->selectable()) + for (const device_slot_option &option : slot->option_list()) + if (option.selectable()) val++; return val; @@ -113,12 +113,12 @@ const char *ui_menu_slot_devices::slot_get_option(device_slot_interface *slot, i if (index >= 0) { int val = 0; - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { if (val == index) - return option->name(); + return option.name(); - if (option->selectable()) + if (option.selectable()) val++; } } diff --git a/src/emu/ui/swlist.cpp b/src/emu/ui/swlist.cpp index 3c2595389b2..c66435e69dc 100644 --- a/src/emu/ui/swlist.cpp +++ b/src/emu/ui/swlist.cpp @@ -76,18 +76,18 @@ void ui_menu_software_parts::populate() item_append(_("[software list]"), nullptr, 0, entry3); } - for (const software_part *swpart = m_info->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : m_info->parts()) { - if (swpart->matches_interface(m_interface)) + if (swpart.matches_interface(m_interface)) { software_part_menu_entry *entry = (software_part_menu_entry *) m_pool_alloc(sizeof(*entry)); // check if the available parts have specific part_id to be displayed (e.g. "Map Disc", "Bonus Disc", etc.) // if not, we simply display "part_name"; if yes we display "part_name (part_id)" - std::string menu_part_name(swpart->name()); - if (swpart->feature("part_id") != nullptr) - menu_part_name.append(" (").append(swpart->feature("part_id")).append(")"); + std::string menu_part_name(swpart.name()); + if (swpart.feature("part_id") != nullptr) + menu_part_name.append(" (").append(swpart.feature("part_id")).append(")"); entry->type = T_ENTRY; - entry->part = swpart; + entry->part = &swpart; item_append(m_info->shortname(), menu_part_name.c_str(), 0, entry); } } @@ -182,24 +182,24 @@ int ui_menu_software_list::compare_entries(const entry_info *e1, const entry_inf // append_software_entry - populate a specific list //------------------------------------------------- -ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(const software_info *swinfo) +ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(const software_info &swinfo) { entry_info *entry = nullptr; entry_info **entryptr; bool entry_updated = FALSE; // check if at least one of the parts has the correct interface and add a menu entry only in this case - for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next()) + for (const software_part &swpart : swinfo.parts()) { - if (swpart->matches_interface(m_interface) && swpart->is_compatible(*m_swlist)) + if (swpart.matches_interface(m_interface) && swpart.is_compatible(*m_swlist)) { entry_updated = TRUE; // allocate a new entry entry = (entry_info *) m_pool_alloc(sizeof(*entry)); memset(entry, 0, sizeof(*entry)); - entry->short_name = pool_strdup(swinfo->shortname()); - entry->long_name = pool_strdup(swinfo->longname()); + entry->short_name = pool_strdup(swinfo.shortname()); + entry->long_name = pool_strdup(swinfo.longname()); break; } } @@ -228,7 +228,7 @@ ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry( void ui_menu_software_list::populate() { // build up the list of entries for the menu - for (const software_info *swinfo = m_swlist->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) + for (const software_info &swinfo : m_swlist->get_info()) append_software_entry(swinfo); // add an entry to change ordering @@ -411,11 +411,11 @@ void ui_menu_software::populate() software_list_device_iterator iter(machine().config().root_device()); for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) - if (swlistdev->first_software_info() != nullptr && m_interface != nullptr) + if (!swlistdev->get_info().empty() && m_interface != nullptr) { bool found = false; - for (const software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - if (swinfo->first_part()->matches_interface(m_interface)) + for (const software_info &swinfo : swlistdev->get_info()) + if (swinfo.first_part()->matches_interface(m_interface)) found = true; if (found) item_append(swlistdev->description(), nullptr, 0, (void *)swlistdev); @@ -424,11 +424,11 @@ void ui_menu_software::populate() // add compatible software lists for this system for (software_list_device *swlistdev = iter.first(); swlistdev != nullptr; swlistdev = iter.next()) if (swlistdev->list_type() == SOFTWARE_LIST_COMPATIBLE_SYSTEM) - if (swlistdev->first_software_info() != nullptr && m_interface != nullptr) + if (!swlistdev->get_info().empty() && m_interface != nullptr) { bool found = false; - for (const software_info *swinfo = swlistdev->first_software_info(); swinfo != nullptr; swinfo = swinfo->next()) - if (swinfo->first_part()->matches_interface(m_interface)) + for (const software_info &swinfo : swlistdev->get_info()) + if (swinfo.first_part()->matches_interface(m_interface)) found = true; if (found) { diff --git a/src/emu/ui/swlist.h b/src/emu/ui/swlist.h index 944aeadf6c5..253eeb6e7c8 100644 --- a/src/emu/ui/swlist.h +++ b/src/emu/ui/swlist.h @@ -63,7 +63,7 @@ private: // functions int compare_entries(const entry_info *e1, const entry_info *e2, bool shortname); - entry_info *append_software_entry(const software_info *swinfo); + entry_info *append_software_entry(const software_info &swinfo); }; diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index 0b15f24edc6..9bb27762c3b 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -1905,8 +1905,6 @@ static slider_state *slider_alloc(running_machine &machine, const char *title, I static slider_state *slider_init(running_machine &machine) { - ioport_field *field; - ioport_port *port; slider_state *listhead = nullptr; slider_state **tailptr = &listhead; std::string str; @@ -1929,12 +1927,12 @@ static slider_state *slider_init(running_machine &machine) } // add analog adjusters - for (port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->type() == IPT_ADJUSTER) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.type() == IPT_ADJUSTER) { - void *param = (void *)field; - *tailptr = slider_alloc(machine, field->name(), field->minval(), field->defvalue(), field->maxval(), 1, slider_adjuster, param); + void *param = (void *)&field; + *tailptr = slider_alloc(machine, field.name(), field.minval(), field.defvalue(), field.maxval(), 1, slider_adjuster, param); tailptr = &(*tailptr)->next; } @@ -2040,15 +2038,15 @@ static slider_state *slider_init(running_machine &machine) #ifdef MAME_DEBUG // add crosshair adjusters - for (port = machine.ioport().first_port(); port != nullptr; port = port->next()) - for (field = port->first_field(); field != nullptr; field = field->next()) - if (field->crosshair_axis() != CROSSHAIR_AXIS_NONE && field->player() == 0) + for (ioport_port &port : machine.ioport().ports()) + for (ioport_field &field : port.fields()) + if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.player() == 0) { - void *param = (void *)field; - str = string_format(_("Crosshair Scale %1$s"), (field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); + void *param = (void *)&field; + str = string_format(_("Crosshair Scale %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); *tailptr = slider_alloc(machine, str.c_str(), -3000, 1000, 3000, 100, slider_crossscale, param); tailptr = &(*tailptr)->next; - str = string_format(_("Crosshair Offset %1$s"), (field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); + str = string_format(_("Crosshair Offset %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); *tailptr = slider_alloc(machine, str.c_str(), -3000, 0, 3000, 100, slider_crossoffset, param); tailptr = &(*tailptr)->next; } diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index 7feb39a1a71..bfe5c40221e 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -751,30 +751,30 @@ void validity_checker::validate_dip_settings(ioport_field &field) bool coin_error = false; // iterate through the settings - for (ioport_setting *setting = field.first_setting(); setting != nullptr; setting = setting->next()) + for (ioport_setting &setting : field.settings()) { // note any coinage strings - int strindex = get_defstr_index(setting->name()); + int strindex = get_defstr_index(setting.name()); if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end) coin_list[strindex - __input_string_coinage_start] = 1; // make sure demo sounds default to on - if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting->value()) + if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting.value()) osd_printf_error("Demo Sounds must default to On\n"); // check for bad demo sounds options if (field.name() == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name()); + osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting.name()); // check for bad flip screen options if (field.name() == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name()); + osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting.name()); // if we have a neighbor, compare ourselves to him - if (setting->next() != nullptr) + if (setting.next() != nullptr) { // check for inverted off/on dispswitch order - int next_strindex = get_defstr_index(setting->next()->name(), true); + int next_strindex = get_defstr_index(setting.next()->name(), true); if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off) osd_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name()); @@ -788,9 +788,9 @@ void validity_checker::validate_dip_settings(ioport_field &field) // check for proper coin ordering else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end && - strindex >= next_strindex && setting->condition() == setting->next()->condition()) + strindex >= next_strindex && setting.condition() == setting.next()->condition()) { - osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting->name(), setting->next()->name()); + osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting.name(), setting.next()->name()); coin_error = true; } } @@ -850,39 +850,39 @@ void validity_checker::validate_inputs() osd_printf_error("I/O port error during construction:\n%s\n", errorbuf.c_str()); // do a first pass over ports to add their names and find duplicates - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) - if (!port_map.insert(port->tag()).second) - osd_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port->tag()); + for (ioport_port &port : portlist) + if (!port_map.insert(port.tag()).second) + osd_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port.tag()); // iterate over ports - for (ioport_port *port = portlist.first(); port != nullptr; port = port->next()) + for (ioport_port &port : portlist) { - m_current_ioport = port->tag(); + m_current_ioport = port.tag(); // iterate through the fields on this port - for (ioport_field *field = port->first_field(); field != nullptr; field = field->next()) + for (ioport_field &field : port.fields()) { // verify analog inputs - if (field->is_analog()) - validate_analog_input_field(*field); + if (field.is_analog()) + validate_analog_input_field(field); // look for invalid (0) types which should be mapped to IPT_OTHER - if (field->type() == IPT_INVALID) + if (field.type() == IPT_INVALID) osd_printf_error("Field has an invalid type (0); use IPT_OTHER instead\n"); // verify dip switches - if (field->type() == IPT_DIPSWITCH) + if (field.type() == IPT_DIPSWITCH) { // dip switch fields must have a name - if (field->name() == nullptr) + if (field.name() == nullptr) osd_printf_error("DIP switch has a NULL name\n"); // verify the settings list - validate_dip_settings(*field); + validate_dip_settings(field); } // verify names - const char *name = field->specific_name(); + const char *name = field.specific_name(); if (name != nullptr) { // check for empty string @@ -902,13 +902,13 @@ void validity_checker::validate_inputs() } // verify conditions on the field - if (!field->condition().none()) - validate_condition(field->condition(), *device, port_map); + if (!field.condition().none()) + validate_condition(field.condition(), *device, port_map); // verify conditions on the settings - for (ioport_setting *setting = field->first_setting(); setting != nullptr; setting = setting->next()) - if (!setting->condition().none()) - validate_condition(setting->condition(), *device, port_map); + for (ioport_setting &setting : field.settings()) + if (!setting.condition().none()) + validate_condition(setting.condition(), *device, port_map); } // done with this port @@ -966,11 +966,11 @@ void validity_checker::validate_devices() slot_interface_iterator slotiter(m_current_config->root_device()); for (const device_slot_interface *slot = slotiter.first(); slot != nullptr; slot = slotiter.next()) { - for (const device_slot_option *option = slot->first_option(); option != nullptr; option = option->next()) + for (const device_slot_option &option : slot->option_list()) { std::string temptag("_"); - temptag.append(option->name()); - device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.c_str(), option->devtype(), 0); + temptag.append(option.name()); + device_t *dev = const_cast(*m_current_config).device_add(&m_current_config->root_device(), temptag.c_str(), option.devtype(), 0); // notify this device and all its subdevices that they are now configured device_iterator subiter(*dev); diff --git a/src/lib/util/coretmpl.h b/src/lib/util/coretmpl.h index 9201041b2d9..6ec00f63e22 100644 --- a/src/lib/util/coretmpl.h +++ b/src/lib/util/coretmpl.h @@ -41,6 +41,23 @@ template class simple_list final { public: + class auto_iterator + { +public: + // construction/destruction + auto_iterator(_ElementType *ptr) noexcept : m_current(ptr) { } + + // required operator overrides + bool operator!=(const auto_iterator &iter) const noexcept { return m_current != iter.m_current; } + _ElementType &operator*() const noexcept { return *m_current; } + // note that _ElementType::next() must not return a const ptr + const auto_iterator &operator++() noexcept { m_current = m_current->next(); return *this; } + +private: + // private state + _ElementType *m_current; + }; + // we don't support deep copying simple_list(const simple_list &) = delete; simple_list &operator=(const simple_list &) = delete; @@ -57,16 +74,21 @@ public: _ElementType *first() const noexcept { return m_head; } _ElementType *last() const noexcept { return m_tail; } int count() const noexcept { return m_count; } + bool empty() const noexcept { return m_count == 0; } + + // range iterators + auto_iterator begin() const noexcept { return auto_iterator(m_head); } + auto_iterator end() const noexcept { return auto_iterator(nullptr); } // remove (free) all objects in the list, leaving an empty list - void reset() + void reset() noexcept { while (m_head != nullptr) remove(*m_head); } // add the given object to the head of the list - _ElementType &prepend(_ElementType &object) + _ElementType &prepend(_ElementType &object) noexcept { object.m_next = m_head; m_head = &object; diff --git a/src/lib/util/options.cpp b/src/lib/util/options.cpp index 9890ae46115..7e8b993c0b2 100644 --- a/src/lib/util/options.cpp +++ b/src/lib/util/options.cpp @@ -226,11 +226,11 @@ core_options &core_options::operator=(const core_options &rhs) bool core_options::operator==(const core_options &rhs) { // iterate over options in the first list - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - if (!curentry->is_header()) + for (entry &curentry : m_entrylist) + if (!curentry.is_header()) { // if the values differ, return false - if (strcmp(curentry->value(), rhs.value(curentry->name())) != 0) + if (strcmp(curentry.value(), rhs.value(curentry.name())) != 0) return false; } @@ -468,8 +468,8 @@ bool core_options::parse_ini_file(util::core_file &inifile, int priority, int ig void core_options::revert(int priority) { // iterate over options and revert to defaults if below the given priority - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - curentry->revert(priority); + for (entry &curentry : m_entrylist) + curentry.revert(priority); } @@ -489,10 +489,10 @@ std::string core_options::output_ini(const core_options *diff) const const char *last_header = nullptr; // loop over all items - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) + for (entry &curentry : m_entrylist) { - const char *name = curentry->name(); - const char *value = curentry->value(); + const char *name = curentry.name(); + const char *value = curentry.value(); bool is_unadorned = false; // check if it's unadorned @@ -503,13 +503,13 @@ std::string core_options::output_ini(const core_options *diff) const } // header: record description - if (curentry->is_header()) - last_header = curentry->description(); + if (curentry.is_header()) + last_header = curentry.description(); // otherwise, output entries for all non-command items - else if (!curentry->is_command()) + else if (!curentry.is_command()) { - if ( !curentry->is_internal() ) + if (!curentry.is_internal()) { // look up counterpart in diff, if diff is specified if (diff == nullptr || strcmp(value, diff->value(name)) != 0) @@ -549,15 +549,15 @@ std::string core_options::output_help() const std::ostringstream buffer; // loop over all items - for (entry *curentry = m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) + for (entry &curentry : m_entrylist) { // header: just print - if (curentry->is_header()) - util::stream_format(buffer, "\n#\n# %s\n#\n", curentry->description()); + if (curentry.is_header()) + util::stream_format(buffer, "\n#\n# %s\n#\n", curentry.description()); // otherwise, output entries for all non-deprecated items - else if (curentry->description() != nullptr) - util::stream_format(buffer, "-%-20s%s\n", curentry->name(), curentry->description()); + else if (curentry.description() != nullptr) + util::stream_format(buffer, "-%-20s%s\n", curentry.name(), curentry.description()); } return buffer.str(); } @@ -744,8 +744,8 @@ void core_options::copyfrom(const core_options &src) reset(); // iterate through the src options and make our own - for (entry *curentry = src.m_entrylist.first(); curentry != nullptr; curentry = curentry->next()) - append_entry(*global_alloc(entry(curentry->name(), curentry->description(), curentry->flags(), curentry->default_value()))); + for (entry &curentry : src.m_entrylist) + append_entry(*global_alloc(entry(curentry.name(), curentry.description(), curentry.flags(), curentry.default_value()))); } /** diff --git a/src/lib/util/options.h b/src/lib/util/options.h index 4ffdf00ae35..9af9c61233e 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -132,6 +132,11 @@ public: entry *first() const { return m_entrylist.first(); } const char *command() const { return m_command.c_str(); } + // range iterators + using auto_iterator = simple_list::auto_iterator; + auto_iterator begin() const { return m_entrylist.begin(); } + auto_iterator end() const { return m_entrylist.end(); } + // configuration void add_entry(const char *name, const char *description, UINT32 flags = 0, const char *defvalue = nullptr, bool override_existing = false); void add_entry(const options_entry &data, bool override_existing = false) { add_entry(data.name, data.description, data.flags, data.defvalue, override_existing); } diff --git a/src/lib/util/tagmap.h b/src/lib/util/tagmap.h index cdbaf63d7fe..ee4f16b96e3 100644 --- a/src/lib/util/tagmap.h +++ b/src/lib/util/tagmap.h @@ -56,6 +56,12 @@ public: _ElementType *first() const { return m_list.first(); } _ElementType *last() const { return m_list.last(); } int count() const { return m_list.count(); } + bool empty() const { return m_list.empty(); } + + // range iterators + using auto_iterator = typename simple_list<_ElementType>::auto_iterator; + auto_iterator begin() const { return m_list.begin(); } + auto_iterator end() const { return m_list.end(); } // remove (free) all objects in the list, leaving an empty list void reset() { m_list.reset(); m_map.clear(); } diff --git a/src/mame/drivers/besta.cpp b/src/mame/drivers/besta.cpp index 86f81074a68..042c723027a 100644 --- a/src/mame/drivers/besta.cpp +++ b/src/mame/drivers/besta.cpp @@ -87,7 +87,7 @@ WRITE8_MEMBER( besta_state::mpcc_reg_w ) m_term_data = data; break; case 10: - dynamic_cast(devconf)->write(*machine().memory().first_space(), 0, data); + dynamic_cast(devconf)->write(generic_space(), 0, data); default: m_mpcc_regs[offset] = data; break; diff --git a/src/mame/drivers/galaxian.cpp b/src/mame/drivers/galaxian.cpp index 7c9b7fff23c..0ec73f982b8 100644 --- a/src/mame/drivers/galaxian.cpp +++ b/src/mame/drivers/galaxian.cpp @@ -6351,7 +6351,7 @@ DRIVER_INIT_MEMBER(galaxian_state,gmgalax) membank("bank1")->configure_entries(0, 2, memregion("maincpu")->base() + 0x10000, 0x4000); /* callback when the game select is toggled */ - gmgalax_game_changed(*machine().ioport().first_port()->first_field(), nullptr, 0, 0); + gmgalax_game_changed(*machine().ioport().ports().first()->fields().first(), nullptr, 0, 0); save_item(NAME(m_gmgalax_selected_game)); } diff --git a/src/mame/drivers/hh_hmcs40.cpp b/src/mame/drivers/hh_hmcs40.cpp index 783f16be481..3bc28b5a538 100644 --- a/src/mame/drivers/hh_hmcs40.cpp +++ b/src/mame/drivers/hh_hmcs40.cpp @@ -77,6 +77,7 @@ - Though very uncommon when compared to games with LED/lamp display, some games may manipulate VFD plate brightness by strobing it longer, eg. cgalaxn when the player ship explodes. + - bzaxxon 3D effect is difficult to simulate ***************************************************************************/ diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp index 47ee327b394..0ae16c2b1ef 100644 --- a/src/mame/drivers/hh_sm510.cpp +++ b/src/mame/drivers/hh_sm510.cpp @@ -165,10 +165,6 @@ WRITE8_MEMBER(hh_sm510_state::sm511_melody_w) * PCB label BH003 * Sharp SM510 under epoxy (die label CMS54C, KMS598) - The ROM listing "BH003 Top Gun" from patent US5137277 is identical to the - released version, except for 2 probable bit errors and filler bytes. Unused - pages list data too, of what looks like assembler leftover garbage. - ***************************************************************************/ class ktopgun_state : public hh_sm510_state @@ -239,9 +235,6 @@ MACHINE_CONFIG_END Konami Teenage Mutant Ninja Turtles * Sharp SM511 under epoxy (die label KMS 73B, KMS 774) - The ROM listing "BH005 TMNT" from patent US5150899 is identical to the - released version, excluding filler bytes. - ***************************************************************************/ class ktmnt_state : public hh_sm510_state @@ -372,27 +365,27 @@ MACHINE_CONFIG_END ***************************************************************************/ -ROM_START( ktopgun ) +ROM_START( ktopgun ) // except for filler/unused bytes, ROM listing in patent US5137277 "BH003 Top Gun" is same ROM_REGION( 0x1000, "maincpu", 0 ) ROM_LOAD( "cms54c_kms598", 0x0000, 0x1000, CRC(50870b35) SHA1(cda1260c2e1c180995eced04b7d7ff51616dcef5) ) ROM_END -ROM_START( ktmnt ) +ROM_START( ktmnt ) // except for filler/unused bytes, ROM listing in patent US5150899 "BH005 TMNT" prog/music is same ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "kms_73b_774.prog", 0x0000, 0x1000, CRC(a1064f87) SHA1(92156c35fbbb414007ee6804fe635128a741d5f1) ) + ROM_LOAD( "kms73b_774.prog", 0x0000, 0x1000, CRC(a1064f87) SHA1(92156c35fbbb414007ee6804fe635128a741d5f1) ) ROM_REGION( 0x100, "maincpu:music", 0 ) - ROM_LOAD( "kms_73b_774.music", 0x000, 0x100, CRC(8270d626) SHA1(bd91ca1d5cd7e2a62eef05c0033b19dcdbe441ca) ) + ROM_LOAD( "kms73b_774.music", 0x000, 0x100, CRC(8270d626) SHA1(bd91ca1d5cd7e2a62eef05c0033b19dcdbe441ca) ) ROM_END -ROM_START( kcontra ) +ROM_START( kcontra ) // except for filler/unused bytes, ROM listing in patent US5120057 "BH002 C (Contra)" prog/music is same ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "bh002_c.prog", 0x0000, 0x1000, BAD_DUMP CRC(5496d84a) SHA1(7e31f8ff8037a1a9ec510798c2197d55a8e9799a) ) // from patent US5120057, may have errors + ROM_LOAD( "kms73b_774.prog", 0x0000, 0x1000, CRC(bf834877) SHA1(055dd56ec16d63afba61ab866481fd9c029fb54d) ) ROM_REGION( 0x100, "maincpu:music", 0 ) - ROM_LOAD( "bh002_c.music", 0x000, 0x100, CRC(e678a199) SHA1(beff871b0aa52690f0fe456401ca75abb746a5cc) ) + ROM_LOAD( "kms73b_774.music", 0x000, 0x100, CRC(23d02b99) SHA1(703938e496db0eeacd14fe7605d4b5c39e0a5bc8) ) ROM_END diff --git a/src/mame/drivers/hh_ucom4.cpp b/src/mame/drivers/hh_ucom4.cpp index fb866b8b410..d3411390e2b 100644 --- a/src/mame/drivers/hh_ucom4.cpp +++ b/src/mame/drivers/hh_ucom4.cpp @@ -47,6 +47,7 @@ @209 uPD553C 1982, Tomy Caveman (TN-12) @258 uPD553C 1984, Tomy Alien Chase (TN-16) + *511 uPD557LC?1980, Gakken Game Robot 9/Mego Fabulous Fred @512 uPD557LC 1980, Castle Toy Tactix @060 uPD650C 1979, Mattel Computer Gin diff --git a/src/mame/drivers/multfish.cpp b/src/mame/drivers/multfish.cpp index f60695b574e..a73c8117e1e 100644 --- a/src/mame/drivers/multfish.cpp +++ b/src/mame/drivers/multfish.cpp @@ -2701,117 +2701,117 @@ Most games had a revision in early 2007 to meet the standards of the "Government -GAME( 2002, goldfish, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gold Fish (020903, prototype)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2002, mfish_3, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021124)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2002, mfish_6, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030124)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2002, mfish_8, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030522)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2002, mfish_11, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031124)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2002, mfish_12, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (040308)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, goldfish, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gold Fish (020903, prototype)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, mfish_3, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021124)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, mfish_6, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030124)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, mfish_8, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030522)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, mfish_11, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031124)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2002, mfish_12, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (040308)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2002, mfish_13, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (040316)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2002, windjamr, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Windjammer (021216)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, czmon_5, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030421 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, czmon_7, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (031110 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, czmon_8, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (050120 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, czmon_9, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (070315 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, czmon_5, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030421 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, czmon_7, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (031110 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, czmon_8, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (050120 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, czmon_9, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (070315 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ GAME( 2003, czmon_13, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (100311 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, czmon_15, czmon_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, crzmonent,ROT0, "Igrosoft", "Crazy Monkey (100311 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2003, czmon_16, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (100312 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, czmon_15, czmon_13, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, crzmonent,ROT0, "Igrosoft", "Crazy Monkey (100311 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2003, czmon_16, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (100312 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, fcockt_3, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030623 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, fcockt_5, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (031111 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, fcockt_6, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, fcockt_7, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (050118 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, fcockt_3, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030623 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, fcockt_5, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (031111 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, fcockt_6, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, fcockt_7, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (050118 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2003, fcockt_8, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (060111 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, fcockt_9, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070305 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, fcockt_10, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070517 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, fcockt_11, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070822 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, fcockt_12, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070911 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, fcockt_14, fcockt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, fcocktent,ROT0, "Igrosoft", "Fruit Cocktail (090708 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2003, fcockt_9, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070305 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, fcockt_10, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070517 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, fcockt_11, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070822 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, fcockt_12, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (070911 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, fcockt_14, fcockt_8, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, fcocktent,ROT0, "Igrosoft", "Fruit Cocktail (090708 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2003, lhaunt_2, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (030804 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, lhaunt_4, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (031111 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, lhaunt_5, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, lhaunt_2, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (030804 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, lhaunt_4, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (031111 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, lhaunt_5, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2003, lhaunt_6, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (040825 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, lhaunt_7, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (070402 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, lhaunt_8, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (070604 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2003, lhaunt_10, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, lhauntent,ROT0, "Igrosoft", "Lucky Haunter (090712 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2003, lhaunt_11, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, lhauntent,ROT0, "Igrosoft", "Lucky Haunter (100331 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2003, lhaunt_7, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (070402 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, lhaunt_8, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (070604 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2003, lhaunt_10, lhaunt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, lhauntent,ROT0, "Igrosoft", "Lucky Haunter (090712 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2003, lhaunt_11, lhaunt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, lhauntent,ROT0, "Igrosoft", "Lucky Haunter (100331 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2003, rollfr_2, rollfr_parent, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (040318)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2003, rollfr_3, rollfr_parent, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (080327)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, rollfr_2, rollfr_4, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (040318)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2003, rollfr_3, rollfr_4, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (080327)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2003, rollfr_4, 0, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (080331)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, garage_4, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040219 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2004, garage_4, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040219 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2004, garage_5, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (050311 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, garage_6, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (070213 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2004, garage_7, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (070329 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2004, garage_9, garage_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, garageent,ROT0, "Igrosoft", "Garage (090715 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2004, garage_6, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (070213 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, garage_7, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (070329 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, garage_9, garage_5, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, garageent,ROT0, "Igrosoft", "Garage (090715 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2004, rclimb, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (040815 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2004, rclimb, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (040815 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2004, rclimb_3, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (040827 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, rclimb_4, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (070322 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2004, rclimb_5, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (070621 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2004, rclimb_7, rclimb_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, rclimbent,ROT0, "Igrosoft", "Rock Climber (090716 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2004, rclimb_4, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (070322 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, rclimb_5, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (070621 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, rclimb_7, rclimb_3, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, rclimbent,ROT0, "Igrosoft", "Rock Climber (090716 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ GAME( 2004, sweetl, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life (041220 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, sweetl_2, sweetl_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life (070412 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, sweetl_2, sweetl, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life (070412 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2004, resdnt, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (040415 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, resdnt_2, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (040513 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, resdnt_3, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (070222 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, resdnt, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (040415 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2004, resdnt_2, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (040513 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2004, resdnt_3, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (070222 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ GAME( 2004, resdnt_6, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (100311 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2004, resdnt_8, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, resdntent,ROT0, "Igrosoft", "Resident (100311 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2004, resdnt_9, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (100316 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2004, resdnt_8, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, resdntent,ROT0, "Igrosoft", "Resident (100311 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2004, resdnt_9, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (100316 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ GAME( 2005, island, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island (050713 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2005, island_2, island_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island (070409 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2005, island_2, island, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island (070409 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2005, pirate_2, pirate_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (060210 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2005, pirate_2, pirate_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (060210 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2005, pirate_3, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (060803 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2005, pirate_4, pirate_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (070412 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2005, pirate_4, pirate_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (070412 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ GAME( 2006, island2, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (060529 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2006, island2_3, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (061218 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2006, island2_4, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (070205 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2006, island2_5, island2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, island2l, ROT0, "Igrosoft", "Island 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2006, island2_6, island2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,island2ent,ROT0, "Igrosoft", "Island 2 (090724 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2006, island2_3, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (061218 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2006, island2_4, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (070205 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2006, island2_5, island2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, island2l, ROT0, "Igrosoft", "Island 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2006, island2_6, island2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,island2ent,ROT0, "Igrosoft", "Island 2 (090724 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ GAME( 2006, pirate2, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate 2 (061005 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2006, pirate2_2, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate 2 (070126 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2006, pirate2_3, pirate2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, pirate2l, ROT0, "Igrosoft", "Pirate 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2006, pirate2_4, pirate2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,pirate2ent,ROT0, "Igrosoft", "Pirate 2 (090730 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2006, pirate2_2, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate 2 (070126 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2006, pirate2_3, pirate2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, pirate2l, ROT0, "Igrosoft", "Pirate 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2006, pirate2_4, pirate2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,pirate2ent,ROT0, "Igrosoft", "Pirate 2 (090730 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2006, keks, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Keks (060328 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2006, keks, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Keks (060328 World)", MACHINE_SUPPORTS_SAVE ) /* World */ GAME( 2006, keks_2, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Keks (060403 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2006, keks_3, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Keks (070119 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2006, keks_4, keks_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, keksl, ROT0, "Igrosoft", "Keks (090604 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2006, keks_5, keks_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, keksent, ROT0, "Igrosoft", "Keks (090727 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2006, keks_3, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Keks (070119 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2006, keks_4, keks_2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, keksl, ROT0, "Igrosoft", "Keks (090604 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2006, keks_5, keks_2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, keksent, ROT0, "Igrosoft", "Keks (090727 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2007, gnome, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (070906 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2007, gnome_2, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (071115 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2007, gnome_3, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (080303 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2007, gnome_4, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (090402 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2007, gnome_5, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (090406 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2007, gnome_7, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (090708 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2007, gnome, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (070906 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2007, gnome_2, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (071115 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2007, gnome_3, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (080303 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2007, gnome_4, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (090402 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2007, gnome_5, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (090406 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2007, gnome_7, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (090708 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ GAME( 2007, gnome_9, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (100326 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2007, gnome_10, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (100326 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2007, gnome_11, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomeent, ROT0, "Igrosoft", "Gnome (100326 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -GAME( 2007, gnome_12, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (100326 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2007, gnome_10, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (100326 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2007, gnome_11, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomeent, ROT0, "Igrosoft", "Gnome (100326 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2007, gnome_12, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Gnome (100326 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ GAME( 2007, sweetl2, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life 2 (071217 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2007, sweetl2_2, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life 2 (080320 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2007, sweetl2_3, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, sweetl2l, ROT0, "Igrosoft", "Sweet Life 2 (090525 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2007, sweetl2_4, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,sweetl2ent,ROT0, "Igrosoft", "Sweet Life 2 (090812 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2007, sweetl2_2, sweetl2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Sweet Life 2 (080320 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2007, sweetl2_3, sweetl2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, sweetl2l, ROT0, "Igrosoft", "Sweet Life 2 (090525 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2007, sweetl2_4, sweetl2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,sweetl2ent,ROT0, "Igrosoft", "Sweet Life 2 (090812 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ GAME( 2008, fcockt2, 0, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (080707 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2008, fcockt2_3, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (080909 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2008, fcockt2_4, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (081105 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -GAME( 2008, fcockt2_5, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (081106 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ -GAME( 2008, fcockt2_6, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, fcockt2l, ROT0, "Igrosoft", "Fruit Cocktail 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2008, fcockt2_7, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,fcockt2ent,ROT0, "Igrosoft", "Fruit Cocktail 2 (090813 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2008, fcockt2_3, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (080909 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2008, fcockt2_4, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (081105 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +GAME( 2008, fcockt2_5, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (081106 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +GAME( 2008, fcockt2_6, fcockt2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, fcockt2l, ROT0, "Igrosoft", "Fruit Cocktail 2 (090528 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2008, fcockt2_7, fcockt2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,fcockt2ent,ROT0, "Igrosoft", "Fruit Cocktail 2 (090813 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ GAME( 2010, crzmon2, 0, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,crzmon2, ROT0, "Igrosoft", "Crazy Monkey 2 (100310)", MACHINE_NOT_WORKING|MACHINE_SUPPORTS_SAVE ) /* World */ // xored and bitswapped palette and gfx roms -GAME( 2010, crzmon2_2, crzmon2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,crzmon2lot,ROT0, "Igrosoft", "Crazy Monkey 2 (100311 Lottery)", MACHINE_NOT_WORKING|MACHINE_SUPPORTS_SAVE ) /* Lottery */ -GAME( 2010, crzmon2_3, crzmon2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,crzmon2ent,ROT0, "Igrosoft", "Crazy Monkey 2 (100315 Entertainment)", MACHINE_NOT_WORKING|MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +GAME( 2010, crzmon2_2, crzmon2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,crzmon2lot,ROT0, "Igrosoft", "Crazy Monkey 2 (100311 Lottery)", MACHINE_NOT_WORKING|MACHINE_SUPPORTS_SAVE ) /* Lottery */ +GAME( 2010, crzmon2_3, crzmon2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state,crzmon2ent,ROT0, "Igrosoft", "Crazy Monkey 2 (100315 Entertainment)", MACHINE_NOT_WORKING|MACHINE_SUPPORTS_SAVE ) /* Entertainment */ diff --git a/src/mame/drivers/multfish_boot.cpp b/src/mame/drivers/multfish_boot.cpp index a821b7b681b..61f560bac8d 100644 --- a/src/mame/drivers/multfish_boot.cpp +++ b/src/mame/drivers/multfish_boot.cpp @@ -1710,128 +1710,128 @@ ROM_START( fcockt2_4f ) // 081105 custom alteras, modified graphics, bank F9, ma ROM_END -GAME( 2002, mfish_3a, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Multi Fish (bootleg, 021124, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2002, mfish_12a, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Multi Fish (bootleg, 040308, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2002, mfish_3a, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Multi Fish (bootleg, 021124, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2002, mfish_12a, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Multi Fish (bootleg, 040308, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2003, czmon_7a, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 031110, backdoor set 1)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, czmon_7b, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 031110, backdoor set 2)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 5,5 1,7 3,2 3,3 3,4 -GAME( 2003, czmon_8a, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, czmon_8b, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070315 -GAME( 2003, czmon_8c, czmon_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, VIDEO GAME-1 CM01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 CM01" -GAME( 2003, czmon_8d, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2003, czmon_8e, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTO PROGRAM V-CM2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-CM2" -GAME( 2003, czmon_8f, czmon_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTOS CM01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS CM01" -GAME( 2003, czmon_9a, czmon_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, VIDEO GAME-1 O01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 O01" -GAME( 2003, czmon_9b, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, VIDEO GAME-1 O01 set 2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "VIDEO GAME-1 O01" (czmon_9a, decoded gfx) -GAME( 2003, czmon_9c, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% +GAME( 2003, czmon_7a, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 031110, backdoor set 1)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, czmon_7b, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 031110, backdoor set 2)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 5,5 1,7 3,2 3,3 3,4 +GAME( 2003, czmon_8a, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, czmon_8b, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070315 +GAME( 2003, czmon_8c, czmon_13, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, VIDEO GAME-1 CM01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 CM01" +GAME( 2003, czmon_8d, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2003, czmon_8e, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTO PROGRAM V-CM2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-CM2" +GAME( 2003, czmon_8f, czmon_13, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 050120, LOTOS CM01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS CM01" +GAME( 2003, czmon_9a, czmon_13, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, VIDEO GAME-1 O01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 O01" +GAME( 2003, czmon_9b, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, VIDEO GAME-1 O01 set 2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "VIDEO GAME-1 O01" (czmon_9a, decoded gfx) +GAME( 2003, czmon_9c, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Crazy Monkey (bootleg, 070315, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% -GAME( 2003, fcockt_6a, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F8 -GAME( 2003, fcockt_6b, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, fcockt_6c, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, LotoRossy+)", MACHINE_SUPPORTS_SAVE ) // modified graphics, some code changes, description says "for Lat-02 terminals", older set -GAME( 2003, fcockt_6d, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, VIDEO GAME-1 FR01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, some code changes, changed version text to "VIDEO GAME-1 FR01", description says "for Lat-02 terminals", newer set -GAME( 2003, fcockt_7a, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, fcockt_7b, fcockt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, VIDEO GAME-1 FR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 FR01" -GAME( 2003, fcockt_7c, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 40)", MACHINE_SUPPORTS_SAVE ) // payout percentage 40% -GAME( 2003, fcockt_7d, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // payout percentage 60% -GAME( 2003, fcockt_7e, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% -GAME( 2003, fcockt_7f, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070305 -GAME( 2003, fcockt_7g, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, LOTO PROGRAM V-FC2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-FC2" -GAME( 2003, fcockt_7h, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, LOTOS FR01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTOS FR01" -GAME( 2003, fcockt_8a, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 060111, LOTO COCKTAIL V01-0001)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO COCKTAIL V01-0001" -GAME( 2003, fcockt_8b, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 060111, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2003, fcockt_6a, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F8 +GAME( 2003, fcockt_6b, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, fcockt_6c, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, LotoRossy+)", MACHINE_SUPPORTS_SAVE ) // modified graphics, some code changes, description says "for Lat-02 terminals", older set +GAME( 2003, fcockt_6d, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 040216, VIDEO GAME-1 FR01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, some code changes, changed version text to "VIDEO GAME-1 FR01", description says "for Lat-02 terminals", newer set +GAME( 2003, fcockt_7a, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, fcockt_7b, fcockt_8, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, VIDEO GAME-1 FR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 FR01" +GAME( 2003, fcockt_7c, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 40)", MACHINE_SUPPORTS_SAVE ) // payout percentage 40% +GAME( 2003, fcockt_7d, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // payout percentage 60% +GAME( 2003, fcockt_7e, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% +GAME( 2003, fcockt_7f, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070305 +GAME( 2003, fcockt_7g, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, LOTO PROGRAM V-FC2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-FC2" +GAME( 2003, fcockt_7h, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 050118, LOTOS FR01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTOS FR01" +GAME( 2003, fcockt_8a, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 060111, LOTO COCKTAIL V01-0001)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO COCKTAIL V01-0001" +GAME( 2003, fcockt_8b, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail (bootleg, 060111, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2003, lhaunt_4a, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 031111, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, lhaunt_5a, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040216, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2003, lhaunt_6a, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 -GAME( 2003, lhaunt_6b, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, VIDEO GAME-1 PB01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 PB01" -GAME( 2003, lhaunt_6c, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070604 -GAME( 2003, lhaunt_6d, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2003, lhaunt_6e, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTO PROGRAM V-LH2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-LH2" -GAME( 2003, lhaunt_6f, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTOS PB01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS PB01" +GAME( 2003, lhaunt_4a, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 031111, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, lhaunt_5a, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040216, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2003, lhaunt_6a, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 +GAME( 2003, lhaunt_6b, lhaunt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, VIDEO GAME-1 PB01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 PB01" +GAME( 2003, lhaunt_6c, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070604 +GAME( 2003, lhaunt_6d, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2003, lhaunt_6e, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTO PROGRAM V-LH2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-LH2" +GAME( 2003, lhaunt_6f, lhaunt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Lucky Haunter (bootleg, 040825, LOTOS PB01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS PB01" -GAME( 2004, garage_4a, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2004, garage_4b, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070329 -GAME( 2004, garage_4c, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, LOTO PROGRAM V-GG2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-GG2" -GAME( 2004, garage_5a, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2004, garage_5b, garage_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Garage (bootleg, 050311, VIDEO GAME-1 GA01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 GA01" -GAME( 2004, garage_5c, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% -GAME( 2004, garage_5d, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2004, garage_5e, garage_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Garage (bootleg, 050311, LOTOS GA01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS GA01" +GAME( 2004, garage_4a, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2004, garage_4b, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, changed version text)", MACHINE_SUPPORTS_SAVE ) // changed version text to 070329 +GAME( 2004, garage_4c, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 040219, LOTO PROGRAM V-GG2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-GG2" +GAME( 2004, garage_5a, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2004, garage_5b, garage_5, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Garage (bootleg, 050311, VIDEO GAME-1 GA01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 GA01" +GAME( 2004, garage_5c, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // payout percentage 70% +GAME( 2004, garage_5d, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Garage (bootleg, 050311, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2004, garage_5e, garage_5, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Garage (bootleg, 050311, LOTOS GA01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS GA01" -GAME( 2004, rclimb_3a, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 -GAME( 2004, rclimb_3b, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, new service menu)", MACHINE_SUPPORTS_SAVE ) // new service menu -GAME( 2004, rclimb_3c, rclimb_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Rock Climber (bootleg, 040827, VIDEO GAME-1 SK01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 SK01" -GAME( 2004, rclimb_3d, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2004, rclimb_3e, rclimb_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Rock Climber (bootleg, 040827, LOTOS SK01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS SK01" +GAME( 2004, rclimb_3a, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 +GAME( 2004, rclimb_3b, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, new service menu)", MACHINE_SUPPORTS_SAVE ) // new service menu +GAME( 2004, rclimb_3c, rclimb_3, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Rock Climber (bootleg, 040827, VIDEO GAME-1 SK01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 SK01" +GAME( 2004, rclimb_3d, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Rock Climber (bootleg, 040827, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2004, rclimb_3e, rclimb_3, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Rock Climber (bootleg, 040827, LOTOS SK01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS SK01" -GAME( 2004, sweetla, sweetl_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life (bootleg, 041220, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,3 1,5 3,3 3,4 -GAME( 2004, sweetlb, sweetl_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life (bootleg, 041220, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070412 +GAME( 2004, sweetla, sweetl, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life (bootleg, 041220, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,3 1,5 3,3 3,4 +GAME( 2004, sweetlb, sweetl, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life (bootleg, 041220, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070412 -GAME( 2004, resdnt_2a, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 -GAME( 2004, resdnt_2b, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 SE01" -GAME( 2004, resdnt_2c, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 2)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 SE01" -GAME( 2004, resdnt_2d, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 3)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 SE01" -GAME( 2004, resdnt_2e, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2004, resdnt_2f, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, LOTO PROGRAM V-RS2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-RS2" -GAME( 2004, resdnt_2g, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, LOTOS SE01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS SE01" +GAME( 2004, resdnt_2a, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,5 9,1 5,1 1,5 3,3 3,4 +GAME( 2004, resdnt_2b, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 SE01" +GAME( 2004, resdnt_2c, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 2)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, changed version text to "VIDEO GAME-1 SE01" +GAME( 2004, resdnt_2d, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, VIDEO GAME-1 SE01 set 3)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 SE01" +GAME( 2004, resdnt_2e, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2004, resdnt_2f, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Resident (bootleg, 040513, LOTO PROGRAM V-RS2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, many texts changed, changed version text to "LOTO PROGRAM V-RS2" +GAME( 2004, resdnt_2g, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Resident (bootleg, 040513, LOTOS SE01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS SE01" -GAME( 2005, islanda, island_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island (bootleg, 050713, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2005, islandb, island_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Island (bootleg, 050713, VIDEO GAME-1 OS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 OS01" -GAME( 2005, islandc, island_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Island (bootleg, 050713, LOTOS OS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS OS01" +GAME( 2005, islanda, island, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island (bootleg, 050713, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2005, islandb, island, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Island (bootleg, 050713, VIDEO GAME-1 OS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 OS01" +GAME( 2005, islandc, island, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Island (bootleg, 050713, LOTOS OS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS OS01" -GAME( 2006, island2a, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 (not standart, game not work) -GAME( 2006, island2b, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070205, skip some start tests -GAME( 2006, island2c, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2006, island2_3a, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 061218, VIDEO GAME-1 OS2-01)", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "VIDEO GAME-1 OS2-01" -GAME( 2006, island2_4a, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 070205, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, island2a, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 (not standart, game not work) +GAME( 2006, island2b, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070205, skip some start tests +GAME( 2006, island2c, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 060529, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2006, island2_3a, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 061218, VIDEO GAME-1 OS2-01)", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "VIDEO GAME-1 OS2-01" +GAME( 2006, island2_4a, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Island 2 (bootleg, 070205, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, pirate2a, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, pirate2b, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, skip raster beam position check -GAME( 2006, pirate2c, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126 -GAME( 2006, pirate2d, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126 -GAME( 2006, pirate2e, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 3)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126, skip some start tests -GAME( 2006, pirate2f, pirate2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Pirate 2 (bootleg, 061005, VIDEO GAME-1 PR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 PR01" -GAME( 2006, pirate2g, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2006, pirate2h, pirate2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Pirate 2 (bootleg, 061005, LOTOS PR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS PR01" -GAME( 2006, pirate2_2a, pirate2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 070126, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, pirate2a, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, pirate2b, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, skip raster beam position check +GAME( 2006, pirate2c, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126 +GAME( 2006, pirate2d, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126 +GAME( 2006, pirate2e, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, banking address hack, changed version text set 3)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070126, skip some start tests +GAME( 2006, pirate2f, pirate2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Pirate 2 (bootleg, 061005, VIDEO GAME-1 PR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 PR01" +GAME( 2006, pirate2g, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 061005, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2006, pirate2h, pirate2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Pirate 2 (bootleg, 061005, LOTOS PR01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "LOTOS PR01" +GAME( 2006, pirate2_2a, pirate2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Pirate 2 (bootleg, 070126, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, keksa, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, keksb, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 -GAME( 2006, keksc, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070119 -GAME( 2006, keks_2a, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, keks_2b, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070119 -GAME( 2006, keks_2c, keks_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Keks (bootleg, 060403, VIDEO GAME-1 KS01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, changed version text to "VIDEO GAME-1 KS01" -GAME( 2006, keks_2d, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, VIDEO GAME-1 KS01 set 2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, bank F9, changed version text to "VIDEO GAME-1 KS01" (keks_2c, decoded gfx) -GAME( 2006, keks_2e, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // bank F9, payout percentage 60% -GAME( 2006, keks_2f, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2006, keks_2g, keks_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Keks (bootleg, 060403, LOTOS KS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS KS01" -GAME( 2006, keks_3a, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 070119, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2006, keks_3b, keks_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 070119, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, keksa, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, keksb, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, backdoor)", MACHINE_SUPPORTS_SAVE ) // backdoor 1,1 1,3 1,5 1,7 3,3 3,4 +GAME( 2006, keksc, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060328, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070119 +GAME( 2006, keks_2a, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, keks_2b, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack, changed version text)", MACHINE_SUPPORTS_SAVE ) // bank F9, changed version text to 070119 +GAME( 2006, keks_2c, keks_2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Keks (bootleg, 060403, VIDEO GAME-1 KS01 set 1)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, changed version text to "VIDEO GAME-1 KS01" +GAME( 2006, keks_2d, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, VIDEO GAME-1 KS01 set 2)", MACHINE_SUPPORTS_SAVE ) // modified graphics, bank F9, changed version text to "VIDEO GAME-1 KS01" (keks_2c, decoded gfx) +GAME( 2006, keks_2e, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, banking address hack, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // bank F9, payout percentage 60% +GAME( 2006, keks_2f, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 060403, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2006, keks_2g, keks_2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Keks (bootleg, 060403, LOTOS KS01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS KS01" +GAME( 2006, keks_3a, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 070119, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2006, keks_3b, keks_2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Keks (bootleg, 070119, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnomea, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnomeb, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnomec, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 3)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnomed, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Gnome (bootleg, 070906, VIDEO GAME-1 GN01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 GN01" -GAME( 2007, gnomee, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Gnome (bootleg, 070906, LOTOS GN01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS GN01" -GAME( 2007, gnome_2a, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 071115, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnome_3a, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, gnome_3b, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack, payout percentage 45)", MACHINE_SUPPORTS_SAVE ) // bank F9 payout percentage 45% -GAME( 2007, gnome_3c, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // bank F9 payout percentage 60% -GAME( 2007, gnome_5a, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 090406, banking address hack, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // bank F9, payout percentage 70% -GAME( 2007, gnome_5b, gnome_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 090406, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2007, gnomea, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, gnomeb, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, gnomec, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 070906, banking address hack set 3)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, gnomed, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Gnome (bootleg, 070906, VIDEO GAME-1 GN01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, many texts changed, changed version text to "VIDEO GAME-1 GN01" +GAME( 2007, gnomee, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Gnome (bootleg, 070906, LOTOS GN01)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS GN01" +GAME( 2007, gnome_2a, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 071115, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, gnome_3a, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, gnome_3b, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack, payout percentage 45)", MACHINE_SUPPORTS_SAVE ) // bank F9 payout percentage 45% +GAME( 2007, gnome_3c, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 080303, banking address hack, payout percentage 60)", MACHINE_SUPPORTS_SAVE ) // bank F9 payout percentage 60% +GAME( 2007, gnome_5a, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 090406, banking address hack, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // bank F9, payout percentage 70% +GAME( 2007, gnome_5b, gnome_9, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Gnome (bootleg, 090406, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2007, sweetl2_2a, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2007, sweetl2_2b, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, some fixes -GAME( 2007, sweetl2_2c, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, VIDEO GAME-1 MD01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, bank F9, changed version text to "VIDEO GAME-1 MD01" -GAME( 2007, sweetl2_2d, sweetl2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2007, sweetl2_2a, sweetl2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, banking address hack set 1)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2007, sweetl2_2b, sweetl2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, banking address hack set 2)", MACHINE_SUPPORTS_SAVE ) // bank F9, some fixes +GAME( 2007, sweetl2_2c, sweetl2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, VIDEO GAME-1 MD01)", MACHINE_SUPPORTS_SAVE ) // modified graphics, bank F9, changed version text to "VIDEO GAME-1 MD01" +GAME( 2007, sweetl2_2d, sweetl2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Sweet Life 2 (bootleg, 080320, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2008, fcockt2a, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 080707, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2008, fcockt2_4a, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 -GAME( 2008, fcockt2_4b, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack, no credit limit)", MACHINE_SUPPORTS_SAVE ) // bank F9, no credit limit, "MaxVin" signature -GAME( 2008, fcockt2_4c, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, VIDEO GAME-1 FR02)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "VIDEO GAME-1 FR02" -GAME( 2008, fcockt2_4d, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // bank F9, no credit limit, "MaxVin" signature, payout percentage 70% -GAME( 2008, fcockt2_4e, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" -GAME( 2008, fcockt2_4f, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, LOTOS FR02)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS FR02" +GAME( 2008, fcockt2a, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 080707, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2008, fcockt2_4a, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack)", MACHINE_SUPPORTS_SAVE ) // bank F9 +GAME( 2008, fcockt2_4b, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack, no credit limit)", MACHINE_SUPPORTS_SAVE ) // bank F9, no credit limit, "MaxVin" signature +GAME( 2008, fcockt2_4c, fcockt2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, VIDEO GAME-1 FR02)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "VIDEO GAME-1 FR02" +GAME( 2008, fcockt2_4d, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, banking address hack, payout percentage 70)", MACHINE_SUPPORTS_SAVE ) // bank F9, no credit limit, "MaxVin" signature, payout percentage 70% +GAME( 2008, fcockt2_4e, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, LOTTOGAME (I))", MACHINE_SUPPORTS_SAVE ) // bank F9, modified graphics, changed version text to "MDS_is_the_best_ LOTTOGAME (I)" +GAME( 2008, fcockt2_4f, fcockt2, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, customl,ROT0, "bootleg", "Fruit Cocktail 2 (bootleg, 081105, LOTOS FR02)", MACHINE_SUPPORTS_SAVE ) // custom alteras, modified graphics, bank F9, many texts changed, changed version text to "LOTOS FR02" /* 0x000000 - 0x03ffff Crazy Monkey V03-1110 diff --git a/src/mame/drivers/multfish_ref.cpp b/src/mame/drivers/multfish_ref.cpp index 529292d9bfa..e5e4f13102f 100644 --- a/src/mame/drivers/multfish_ref.cpp +++ b/src/mame/drivers/multfish_ref.cpp @@ -575,54 +575,54 @@ ROM_START( fcockt2_2 ) // 080904 ROM_LOAD( "fruitcocktail2_old.008", 0x380000, 0x80000, CRC(a27c49a2) SHA1(7c9ee0e01f76ca3ab6716579f5dde7036050970b) ) ROM_END -//GAME( 2002, mfish, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021120)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_2, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021121)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_4, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021219)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_5, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021227)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_7, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030511)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_9, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031026)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2002, mfish_10, mfish_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031117)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021120)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_2, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021121)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_4, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021219)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_5, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (021227)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_7, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (030511)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_9, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031026)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2002, mfish_10, mfish_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Multi Fish (031117)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, crzmon, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030217 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, czmon_2, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030225 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, czmon_3, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030227 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, czmon_4, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030404 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, czmon_6, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (031016 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, czmon_10, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (081027 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2003, czmon_11, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (081113 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2003, czmon_12, czmon_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, crzmonent,ROT0, "Igrosoft", "Crazy Monkey (090711 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -//GAME( 2003, czmon_14, czmon_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (100311 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2003, crzmon, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030217 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, czmon_2, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030225 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, czmon_3, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030227 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, czmon_4, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (030404 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, czmon_6, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (031016 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, czmon_10, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (081027 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2003, czmon_11, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (081113 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2003, czmon_12, czmon_13, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, crzmonent,ROT0, "Igrosoft", "Crazy Monkey (090711 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +//GAME( 2003, czmon_14, czmon_13, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Crazy Monkey (100311 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2003, fcockt, fcockt_parent igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030505 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, fcockt_2, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030512 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, fcockt_4, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (031028 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, fcockt_13, fcockt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (081124 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2003, fcockt, fcockt_8 igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030505 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, fcockt_2, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (030512 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, fcockt_4, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (031028 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, fcockt_13, fcockt_8, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail (081124 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2003, lhaunt, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (030707 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, lhaunt_3, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (031027 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2003, lhaunt_9, lhaunt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (081208 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2003, lhaunt, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (030707 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, lhaunt_3, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (031027 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, lhaunt_9, lhaunt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Lucky Haunter (081208 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2003, rollfr, rollfr_parent, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (030821)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2003, rollfr, rollfr_4, rollfr, rollfr, driver_device, 0, ROT0, "Igrosoft", "Roll Fruit (030821)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2004, garage, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040122 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2004, garage_2, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040123 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2004, garage_3, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2004, garage_8, garage_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (081229 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2004, garage, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040122 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2004, garage_2, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040123 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2004, garage_3, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (040216 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2004, garage_8, garage_5, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Garage (081229 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2004, rclimb_2, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (040823 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2004, rclimb_6, rclimb_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (090217 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2004, rclimb_2, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (040823 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2004, rclimb_6, rclimb_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Rock Climber (090217 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2004, resdnt_4, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (090129 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2004, resdnt_5, resdnt_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, resdntent,ROT0, "Igrosoft", "Resident (090722 Entertainment)", GANE_SUPPORTS_SAVE ) /* Entertainment */ -//GAME( 2004, resdnt_7, resdnt_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (100311 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2004, resdnt_4, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (090129 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2004, resdnt_5, resdnt_6, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, resdntent,ROT0, "Igrosoft", "Resident (090722 Entertainment)", GANE_SUPPORTS_SAVE ) /* Entertainment */ +//GAME( 2004, resdnt_7, resdnt_6, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Resident (100311 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2005, pirate, pirate_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (051229 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2005, pirate, pirate_3, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Pirate (051229 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2006, island2_2, island2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (061214 World)", MACHINE_SUPPORTS_SAVE ) /* World */ +//GAME( 2006, island2_2, island2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Island 2 (061214 World)", MACHINE_SUPPORTS_SAVE ) /* World */ -//GAME( 2007, gnome_6, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (090604 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ -//GAME( 2007, gnome_8, gnome_parent, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomeent, ROT0, "Igrosoft", "Gnome (090810 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ +//GAME( 2007, gnome_6, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomel, ROT0, "Igrosoft", "Gnome (090604 Lottery)", MACHINE_SUPPORTS_SAVE ) /* Lottery */ +//GAME( 2007, gnome_8, gnome_9, igrosoft_gamble, igrosoft_gamble, igrosoft_gamble_state, gnomeent, ROT0, "Igrosoft", "Gnome (090810 Entertainment)", MACHINE_SUPPORTS_SAVE ) /* Entertainment */ -//GAME( 2008, fcockt2_2, fcockt2_parent, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (080904 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ +//GAME( 2008, fcockt2_2, fcockt2, igrosoft_gamble, igrosoft_gamble, driver_device, 0, ROT0, "Igrosoft", "Fruit Cocktail 2 (080904 Russia)", MACHINE_SUPPORTS_SAVE ) /* Russia */ #endif diff --git a/src/mame/drivers/pasogo.cpp b/src/mame/drivers/pasogo.cpp index dad0174a079..463e2de34d2 100644 --- a/src/mame/drivers/pasogo.cpp +++ b/src/mame/drivers/pasogo.cpp @@ -528,7 +528,7 @@ void pasogo_state::machine_reset() membank("bank27")->set_base(m_cart_rom->base()); m_ems_index = 0; memset(m_ems_bank, 0, sizeof(m_ems_bank)); - contrast(*color->first_field(), nullptr, 0, color->read()); + contrast(*color->fields().first(), nullptr, 0, color->read()); } static MACHINE_CONFIG_START( pasogo, pasogo_state ) diff --git a/src/mame/drivers/spyhuntertec.cpp b/src/mame/drivers/spyhuntertec.cpp index c41dde50fac..9524b8bf2f1 100644 --- a/src/mame/drivers/spyhuntertec.cpp +++ b/src/mame/drivers/spyhuntertec.cpp @@ -15,14 +15,14 @@ non-interlaced sound system appears to be the same as 'spartanxtec.cpp' -analog inputs seem to be read by the sound CPU, with serial communication + */ #include "emu.h" #include "cpu/z80/z80.h" #include "sound/ay8910.h" - +#include "spyhunttec.lh" #define MASTER_CLOCK XTAL_20MHz // ?? @@ -575,19 +575,11 @@ static INPUT_PORTS_START( spyhuntertec ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_START("IN2") - PORT_DIPNAME( 0x0001, 0x0001, "2" ) - PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) - PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0010, 0x0010, "handbrake?" ) - PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Right Button / Smoke Screen") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Center Button / Weapons Van") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Left Trigger / Missiles") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Left Button / Oil Slick") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Gear Shift") PORT_TOGGLE PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) @@ -616,7 +608,7 @@ static INPUT_PORTS_START( spyhuntertec ) PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("Right Trigger / Machine Guns") PORT_START("PEDAL") PORT_BIT( 0xff, 0x02, IPT_PEDAL ) PORT_MINMAX(0x02,0xff) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_REVERSE @@ -843,4 +835,4 @@ DRIVER_INIT_MEMBER(spyhuntertec_state,spyhuntertec) } -GAME (1983, spyhuntpr,spyhunt, spyhuntertec, spyhuntertec,spyhuntertec_state, spyhuntertec,ROT90, "Bally Midway (Recreativos Franco S.A. license)", "Spy Hunter (Spain, Tecfri / Recreativos Franco S.A. PCB)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAMEL(1983, spyhuntpr,spyhunt, spyhuntertec, spyhuntertec,spyhuntertec_state, spyhuntertec,ROT90, "bootleg (Recreativos Franco S.A. license, Tecfri)", "Spy Hunter (Spain, Recreativos Franco S.A., Tecfri PCB)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE, layout_spyhunttec ) diff --git a/src/mame/drivers/ti99_4p.cpp b/src/mame/drivers/ti99_4p.cpp index 0f48e57772b..7da4302262b 100644 --- a/src/mame/drivers/ti99_4p.cpp +++ b/src/mame/drivers/ti99_4p.cpp @@ -439,12 +439,16 @@ READ16_MEMBER( ti99_4p_state::datamux_read ) UINT8 hbyte = 0; UINT16 addroff = (offset << 1); + m_peribox->memen_in(ASSERT_LINE); + m_peribox->readz(space, addroff+1, &m_latch, mem_mask); m_lowbyte = m_latch; m_peribox->readz(space, addroff, &hbyte, mem_mask); m_highbyte = hbyte; + m_peribox->memen_in(CLEAR_LINE); + // use the latch and the currently read byte and put it on the 16bit bus // printf("read address = %04x, value = %04x, memmask = %4x\n", addroff, (hbyte<<8) | sgcpu->latch, mem_mask); @@ -467,11 +471,15 @@ WRITE16_MEMBER( ti99_4p_state::datamux_write ) // read more about the datamux in datamux.c // Write to the PEB + m_peribox->memen_in(ASSERT_LINE); + m_peribox->write(space, addroff+1, data & 0xff); // Write to the PEB m_peribox->write(space, addroff, (data>>8) & 0xff); + m_peribox->memen_in(CLEAR_LINE); + // Insert four wait states and let CPU enter wait state m_waitcount = 6; console_ready_dmux(CLEAR_LINE); diff --git a/src/mame/drivers/ti99_4x.cpp b/src/mame/drivers/ti99_4x.cpp index b8fcb75b3cb..107f3a466e8 100644 --- a/src/mame/drivers/ti99_4x.cpp +++ b/src/mame/drivers/ti99_4x.cpp @@ -48,7 +48,6 @@ #include "bus/ti99x/videowrp.h" #include "bus/ti99x/datamux.h" -#include "bus/ti99x/grom.h" #include "bus/ti99x/gromport.h" #include "bus/ti99x/joyport.h" @@ -103,6 +102,9 @@ public: DECLARE_WRITE_LINE_MEMBER( console_reset ); DECLARE_WRITE_LINE_MEMBER( notconnected ); + // GROM clock + DECLARE_WRITE_LINE_MEMBER( gromclk_in ); + // Connections with the system interface chip 9901 DECLARE_WRITE_LINE_MEMBER( extint ); DECLARE_WRITE_LINE_MEMBER( video_interrupt_in ); @@ -177,16 +179,10 @@ enum }; /* - Memory map. - Most of the work is done in the datamux (see datamux.c). We only keep ROM - and the small 256 byte PAD RAM here because they are directly connected - to the 16bit bus, and the wait state logic is not active during their - accesses. + Memory map. All of the work is done in the datamux (see datamux.c). */ static ADDRESS_MAP_START(memmap, AS_PROGRAM, 16, ti99_4x_state) ADDRESS_MAP_GLOBAL_MASK(0xffff) - AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x8000, 0x80ff) AM_MIRROR(0x0300) AM_RAM AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(DATAMUX_TAG, ti99_datamux_device, read, write) AM_DEVSETOFFSET(DATAMUX_TAG, ti99_datamux_device, setoffset) ADDRESS_MAP_END @@ -365,21 +361,6 @@ INPUT_PORTS_END Components ******************************************************************************/ -static GROM_CONFIG(grom0_config) -{ - false, 0, region_grom, 0x0000, 0x1800, GROMFREQ -}; - -static GROM_CONFIG(grom1_config) -{ - false, 1, region_grom, 0x2000, 0x1800, GROMFREQ -}; - -static GROM_CONFIG(grom2_config) -{ - false, 2, region_grom, 0x4000, 0x1800, GROMFREQ -}; - READ8_MEMBER( ti99_4x_state::cruread ) { // if (TRACE_CRU) logerror("read access to CRU address %04x\n", offset << 4); @@ -631,6 +612,7 @@ READ8_MEMBER( ti99_4x_state::interrupt_level ) WRITE_LINE_MEMBER( ti99_4x_state::clock_out ) { m_datamux->clock_in(state); + m_peribox->clock_in(state); } /* @@ -641,6 +623,15 @@ WRITE_LINE_MEMBER( ti99_4x_state::dbin_line ) m_datamux->dbin_in(state); } +/* + GROMCLK from VDP, propagating to datamux +*/ +WRITE_LINE_MEMBER( ti99_4x_state::gromclk_in ) +{ + m_datamux->gromclk_in(state); +} + + /*****************************************************************************/ /* @@ -708,6 +699,7 @@ void ti99_4x_state::console_ready_join(int id, int state) */ WRITE_LINE_MEMBER( ti99_4x_state::console_ready_grom ) { + if (TRACE_READY) logerror("GROM ready = %d\n", state); console_ready_join(READY_GROM, state); } @@ -757,52 +749,6 @@ WRITE_LINE_MEMBER( ti99_4x_state::notconnected ) if (TRACE_INTERRUPTS) logerror("ti99_4x: Setting a not connected line ... ignored\n"); } -/*****************************************************************************/ - -/* - Devices attached to the databus multiplexer. We cannot solve this with - the common address maps since the multiplexer also inserts wait states - that we want to emulate properly. Also, devices may reside on the same - memory locations (like GROMs) and select themselves according to some - inner state (e.g. GROMs have an own address counter and a given address - area). -*/ -static const dmux_device_list_entry dmux_devices[] = -{ - { VIDEO_SYSTEM_TAG, 0x8800, 0xfc01, 0x0400, nullptr, 0, 0 }, - { GROM0_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { GROM1_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { GROM2_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { TISOUND_TAG, 0x8400, 0xfc01, 0x0000, nullptr, 0, 0 }, - { GROMPORT_TAG, 0x9800, 0xfc01, 0x0400, nullptr, 0, 0 }, - { GROMPORT_TAG, 0x6000, 0xe000, 0x0000, nullptr, 0, 0 }, - { PERIBOX_TAG, 0x0000, 0x0000, 0x0000, nullptr, 0, 0 }, // Peribox needs all addresses - { nullptr, 0, 0, 0, nullptr, 0, 0 } -}; - -static const dmux_device_list_entry dmux_devices_ev[] = -{ - { VIDEO_SYSTEM_TAG, 0x8800, 0xfc01, 0x0400, nullptr, 0, 0 }, - { GROM0_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { GROM1_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { GROM2_TAG, 0x9800, 0xfc01, 0x0400, "GROMENA", 0x01, 0x00 }, - { TISOUND_TAG, 0x8400, 0xfc01, 0x0000, nullptr, 0, 0 }, - { GROMPORT_TAG, 0x9800, 0xfc01, 0x0400, nullptr, 0, 0 }, - { GROMPORT_TAG, 0x6000, 0xe000, 0x0000, nullptr, 0, 0 }, - { PERIBOX_TAG, 0x0000, 0x0000, 0x0000, nullptr, 0, 0 }, // Peribox needs all addresses - { nullptr, 0, 0, 0, nullptr, 0, 0 } -}; - -static DMUX_CONFIG( datamux_conf ) -{ - dmux_devices -}; - -static DMUX_CONFIG( datamux_conf_ev ) -{ - dmux_devices_ev -}; - /****************************************************************************** Machine definitions ******************************************************************************/ @@ -852,9 +798,10 @@ static MACHINE_CONFIG_START( ti99_4, ti99_4x_state ) MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) - MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) + MCFG_DEVICE_ADD( DATAMUX_TAG, DATAMUX, 0) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) - MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) + + MCFG_GROMPORT4_ADD( GROMPORT_TAG ) MCFG_GROMPORT_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_cart) ) MCFG_GROMPORT_RESET_HANDLER( WRITELINE(ti99_4x_state, console_reset) ) @@ -879,13 +826,10 @@ static MACHINE_CONFIG_START( ti99_4, ti99_4x_state ) MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "cass_out", 0.25) - /* GROM devices */ - MCFG_GROM_ADD( GROM0_TAG, grom0_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM1_TAG, grom1_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM2_TAG, grom2_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) + // GROM devices + MCFG_GROM_ADD( GROM0_TAG, 0, region_grom, 0x0000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM1_TAG, 1, region_grom, 0x2000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM2_TAG, 2, region_grom, 0x4000, WRITELINE(ti99_4x_state, console_ready_grom)) // Joystick port MCFG_TI_JOYPORT4_ADD( JOYPORT_TAG ) @@ -896,14 +840,14 @@ MACHINE_CONFIG_END US version: 60 Hz, NTSC */ static MACHINE_CONFIG_DERIVED( ti99_4_60hz, ti99_4 ) - MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /* European version: 50 Hz, PAL */ static MACHINE_CONFIG_DERIVED( ti99_4_50hz, ti99_4 ) - MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /********************************************************************** @@ -951,9 +895,10 @@ static MACHINE_CONFIG_START( ti99_4a, ti99_4x_state ) MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) - MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) + MCFG_DEVICE_ADD( DATAMUX_TAG, DATAMUX, 0) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) - MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) + + MCFG_GROMPORT4_ADD( GROMPORT_TAG ) MCFG_GROMPORT_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_cart) ) MCFG_GROMPORT_RESET_HANDLER( WRITELINE(ti99_4x_state, console_reset) ) @@ -978,13 +923,10 @@ static MACHINE_CONFIG_START( ti99_4a, ti99_4x_state ) MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "cass_out", 0.25) - /* GROM devices */ - MCFG_GROM_ADD( GROM0_TAG, grom0_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM1_TAG, grom1_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM2_TAG, grom2_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) + // GROM devices + MCFG_GROM_ADD( GROM0_TAG, 0, region_grom, 0x0000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM1_TAG, 1, region_grom, 0x2000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM2_TAG, 2, region_grom, 0x4000, WRITELINE(ti99_4x_state, console_ready_grom)) // Joystick port MCFG_TI_JOYPORT4A_ADD( JOYPORT_TAG ) @@ -994,14 +936,14 @@ MACHINE_CONFIG_END US version: 60 Hz, NTSC */ static MACHINE_CONFIG_DERIVED( ti99_4a_60hz, ti99_4a ) - MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /* European version: 50 Hz, PAL */ static MACHINE_CONFIG_DERIVED( ti99_4a_50hz, ti99_4a ) - MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /************************************************************************ @@ -1029,14 +971,14 @@ MACHINE_CONFIG_END US version: 60 Hz, NTSC */ static MACHINE_CONFIG_DERIVED( ti99_4qi_60hz, ti99_4qi ) - MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /* European version: 50 Hz, PAL */ static MACHINE_CONFIG_DERIVED( ti99_4qi_50hz, ti99_4qi ) - MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, 0x4000, ti99_4x_state, video_interrupt_in) + MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, 0x4000, ti99_4x_state, video_interrupt_in, gromclk_in) MACHINE_CONFIG_END /************************************************************************ @@ -1056,6 +998,10 @@ static MACHINE_CONFIG_START( ti99_4ev_60hz, ti99_4x_state ) /* video hardware */ MCFG_DEVICE_ADD(VIDEO_SYSTEM_TAG, V9938VIDEO, 0) + // Removing the TMS9928a requires to add a replacement for the GROMCLK. + // In the real hardware this is a circuit (REPL99x) that fits into the VDP socket + MCFG_ADD_GROMCLK_CB( WRITELINE(ti99_4x_state, gromclk_in) ) + MCFG_V9938_ADD(VDP_TAG, SCREEN_TAG, 0x20000, XTAL_21_4772MHz) /* typical 9938 clock, not verified */ MCFG_V99X8_INTERRUPT_CALLBACK(WRITELINE(ti99_4x_state, video_interrupt_in)) MCFG_V99X8_SCREEN_ADD_NTSC(SCREEN_TAG, VDP_TAG, XTAL_21_4772MHz) @@ -1073,9 +1019,9 @@ static MACHINE_CONFIG_START( ti99_4ev_60hz, ti99_4x_state ) MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) - MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf_ev ) + MCFG_DEVICE_ADD( DATAMUX_TAG, DATAMUX, 0) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) - MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) + MCFG_GROMPORT4_ADD( GROMPORT_TAG ) MCFG_GROMPORT_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_cart) ) MCFG_GROMPORT_RESET_HANDLER( WRITELINE(ti99_4x_state, console_reset) ) @@ -1100,13 +1046,10 @@ static MACHINE_CONFIG_START( ti99_4ev_60hz, ti99_4x_state ) MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "cass_out", 0.25) - /* GROM devices */ - MCFG_GROM_ADD( GROM0_TAG, grom0_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM1_TAG, grom1_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) - MCFG_GROM_ADD( GROM2_TAG, grom2_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_4x_state, console_ready_grom)) + // GROM devices + MCFG_GROM_ADD( GROM0_TAG, 0, region_grom, 0x0000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM1_TAG, 1, region_grom, 0x2000, WRITELINE(ti99_4x_state, console_ready_grom)) + MCFG_GROM_ADD( GROM2_TAG, 2, region_grom, 0x4000, WRITELINE(ti99_4x_state, console_ready_grom)) // Joystick port MCFG_TI_JOYPORT4A_ADD( JOYPORT_TAG ) @@ -1124,7 +1067,7 @@ MACHINE_CONFIG_END ROM_START(ti99_4) // CPU memory space - ROM_REGION16_BE(0x2000, "maincpu", 0) + ROM_REGION16_BE(0x2000, CONSOLEROM, 0) ROM_LOAD16_BYTE("u610.bin", 0x0000, 0x1000, CRC(6fcf4b15) SHA1(d085213c64701d429ae535f9a4ac8a50427a8343)) /* CPU ROMs high */ ROM_LOAD16_BYTE("u611.bin", 0x0001, 0x1000, CRC(491c21d1) SHA1(7741ae9294c51a44a78033d1b77c01568a6bbfb9)) /* CPU ROMs low */ @@ -1137,7 +1080,7 @@ ROM_END ROM_START(ti99_4a) // CPU memory space - ROM_REGION16_BE(0x2000, "maincpu", 0) + ROM_REGION16_BE(0x2000, CONSOLEROM, 0) ROM_LOAD16_WORD("994arom.bin", 0x0000, 0x2000, CRC(db8f33e5) SHA1(6541705116598ab462ea9403c00656d6353ceb85)) /* system ROMs */ // GROM memory space @@ -1147,7 +1090,7 @@ ROM_END ROM_START(ti99_4qi) // CPU memory space - ROM_REGION16_BE(0x2000, "maincpu", 0) + ROM_REGION16_BE(0x2000, CONSOLEROM, 0) ROM_LOAD16_WORD("994qirom.bin", 0x0000, 0x2000, CRC(db8f33e5) SHA1(6541705116598ab462ea9403c00656d6353ceb85)) /* system ROMs */ // GROM memory space @@ -1160,7 +1103,7 @@ ROM_END ROM_START(ti99_4ev) /*CPU memory space*/ - ROM_REGION16_BE(0x2000, "maincpu", 0) + ROM_REGION16_BE(0x2000, CONSOLEROM, 0) ROM_LOAD16_WORD("994arom.bin", 0x0000, 0x2000, CRC(db8f33e5) SHA1(6541705116598ab462ea9403c00656d6353ceb85)) /* system ROMs */ /*GROM memory space*/ diff --git a/src/mame/drivers/ti99_8.cpp b/src/mame/drivers/ti99_8.cpp index 5e3acc85ff6..9b661f71e82 100644 --- a/src/mame/drivers/ti99_8.cpp +++ b/src/mame/drivers/ti99_8.cpp @@ -86,33 +86,6 @@ - Native mode (Armadillo mode): Devices are located at positions above 0xF000 that allow for a contiguous usage of memory. - - ROM contents - ------------ - The ROM0 chip is accessible at addresses 0000-1FFF in the logical address - space of the compatibility mode. It contains the GPL interpreter. In - native mode the ROM0 chip is invisible. - - ROM0 - offset Logical address Name - ----------------------------------- - 0000 0000-1FFF ROM0 - - - The ROM1 chip contains 32 KiB of various system software. It is located in - the physical address space, so it must be mapped into the logical address - space by defining an appropriate map. - - ROM1 - offset Physical address Name - ---------------------------------------------------------- - 0000 FFA000-FFDFFF ROM1 - 4000 FF4000-FF5FFF @CRU>2700 Text-to-speech ROM/DSR - 6000 FF4000-FF5FFF @CRU>1700 Hexbus DSR - - The DSR portions have to be selected via the CRU bits >1700 or >2700. - - Mapper ------ The mapper uses 4K pages (unlike the Geneve mapper with 8K pages) which @@ -200,22 +173,27 @@ Known Issues (MZ, 2010-11-07) #include "emu.h" #include "cpu/tms9900/tms9995.h" +#include "bus/ti99x/ti99defs.h" + #include "sound/sn76496.h" #include "sound/wave.h" #include "machine/tms9901.h" +#include "machine/tmc0430.h" #include "imagedev/cassette.h" #include "bus/ti99x/998board.h" #include "bus/ti99x/videowrp.h" -#include "bus/ti99x/grom.h" #include "bus/ti99x/gromport.h" #include "bus/ti99x/joyport.h" #include "bus/ti99_peb/peribox.h" +#include "softlist.h" + // Debugging #define TRACE_READY 0 #define TRACE_INTERRUPTS 0 +#define TRACE_RESET 0 #define TRACE_CRU 0 /* @@ -228,7 +206,8 @@ enum READY_PBOX = 4, READY_SOUND = 8, READY_CART = 16, - READY_SPEECH = 32 + READY_SPEECH = 32, + READY_MAINBOARD = 64 }; class ti99_8_state : public driver_device @@ -242,8 +221,7 @@ public: m_peribox(*this, PERIBOX_TAG), m_mainboard(*this, MAINBOARD8_TAG), m_joyport(*this, JOYPORT_TAG), - m_video(*this, VIDEO_SYSTEM_TAG), - m_cassette(*this, "cassette") { } + m_cassette(*this, "cassette") { }; // Machine management DECLARE_MACHINE_START(ti99_8); @@ -254,17 +232,17 @@ public: DECLARE_WRITE8_MEMBER( cruwrite ); DECLARE_WRITE8_MEMBER( external_operation ); DECLARE_WRITE_LINE_MEMBER( clock_out ); + DECLARE_WRITE_LINE_MEMBER( dbin_line ); // Connections from outside towards the CPU (callbacks) - DECLARE_WRITE_LINE_MEMBER( console_ready_mapper ); - DECLARE_WRITE_LINE_MEMBER( console_ready_sound ); - DECLARE_WRITE_LINE_MEMBER( console_ready_pbox ); - DECLARE_WRITE_LINE_MEMBER( console_ready_cart ); - DECLARE_WRITE_LINE_MEMBER( console_ready_grom ); - DECLARE_WRITE_LINE_MEMBER( console_ready_speech ); + DECLARE_WRITE_LINE_MEMBER( console_ready ); DECLARE_WRITE_LINE_MEMBER( console_reset ); + DECLARE_WRITE_LINE_MEMBER( cpu_hold ); DECLARE_WRITE_LINE_MEMBER( notconnected ); + // GROM clock (coming from Vaquerro) + DECLARE_WRITE_LINE_MEMBER( gromclk_in ); + // Connections with the system interface chip 9901 DECLARE_WRITE_LINE_MEMBER( extint ); DECLARE_WRITE_LINE_MEMBER( video_interrupt ); @@ -275,8 +253,6 @@ public: DECLARE_WRITE_LINE_MEMBER(keyC1); DECLARE_WRITE_LINE_MEMBER(keyC2); DECLARE_WRITE_LINE_MEMBER(keyC3); - DECLARE_WRITE_LINE_MEMBER(CRUS); - DECLARE_WRITE_LINE_MEMBER(PTGEN); DECLARE_WRITE_LINE_MEMBER(audio_gate); DECLARE_WRITE_LINE_MEMBER(cassette_output); DECLARE_WRITE_LINE_MEMBER(cassette_motor); @@ -288,9 +264,7 @@ private: int m_keyboard_column; // READY handling - int m_nready_combined; - int m_nready_prev; - void console_ready_join(int id, int state); + line_state m_ready_old; // Latch for 9901 INT2, INT1 lines line_state m_int1; @@ -303,7 +277,6 @@ private: required_device m_peribox; required_device m_mainboard; required_device m_joyport; - required_device m_video; required_device m_cassette; }; @@ -312,7 +285,7 @@ private: job to the mapper completely. */ static ADDRESS_MAP_START(memmap, AS_PROGRAM, 8, ti99_8_state) - AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(MAINBOARD8_TAG, mainboard8_device, readm, writem ) + AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(MAINBOARD8_TAG, mainboard8_device, read, write) AM_DEVSETOFFSET(MAINBOARD8_TAG, mainboard8_device, setoffset) ADDRESS_MAP_END /* @@ -432,89 +405,6 @@ static INPUT_PORTS_START(ti99_8) INPUT_PORTS_END -/***************************************************************************** - Components -******************************************************************************/ -#define region_sysgrom "sysgrom" - -static GROM_CONFIG(grom0_config) -{ - false, 0, region_sysgrom, 0x0000, 0x1800, GROMFREQ -}; - -static GROM_CONFIG(grom1_config) -{ - false, 1, region_sysgrom, 0x2000, 0x1800, GROMFREQ -}; - -static GROM_CONFIG(grom2_config) -{ - false, 2, region_sysgrom, 0x4000, 0x1800, GROMFREQ -}; - -/**************************************************** - PASCAL groms, 3 libraries @ 8 GROMs - Do some macro tricks to keep writing effort low -*****************************************************/ - -#define region_gromlib1 "gromlib1" -#define region_gromlib2 "gromlib2" -#define region_gromlib3 "gromlib3" - -#define MCFG_GROM_LIBRARY_ADD8(_tag, _config) \ - MCFG_DEVICE_ADD(#_tag "0", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##0) \ - MCFG_DEVICE_ADD(#_tag "1", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##1) \ - MCFG_DEVICE_ADD(#_tag "2", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##2) \ - MCFG_DEVICE_ADD(#_tag "3", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##3) \ - MCFG_DEVICE_ADD(#_tag "4", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##4) \ - MCFG_DEVICE_ADD(#_tag "5", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##5) \ - MCFG_DEVICE_ADD(#_tag "6", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##6) \ - MCFG_DEVICE_ADD(#_tag "7", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##7) - -#define MCFG_GROM_LIBRARY_ADD3(_tag, _config) \ - MCFG_DEVICE_ADD(#_tag "0", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##0) \ - MCFG_DEVICE_ADD(#_tag "1", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##1) \ - MCFG_DEVICE_ADD(#_tag "2", GROM, 0) \ - MCFG_DEVICE_CONFIG(_config##2) - -#define GROM_LIBRARY_CONFIG8(_conf, _region) \ -static GROM_CONFIG(_conf##0) \ -{ false, 0, _region, 0x0000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##1) \ -{ false, 1, _region, 0x2000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##2) \ -{ false, 2, _region, 0x4000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##3) \ -{ false, 3, _region, 0x6000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##4) \ -{ false, 4, _region, 0x8000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##5) \ -{ false, 5, _region, 0xa000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##6) \ -{ false, 6, _region, 0xc000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##7) \ -{ false, 7, _region, 0xe000, 0x1800, GROMFREQ }; - -#define GROM_LIBRARY_CONFIG3(_conf, _region) \ -static GROM_CONFIG(_conf##0) \ -{ false, 0, _region, 0x0000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##1) \ -{ false, 1, _region, 0x2000, 0x1800, GROMFREQ }; \ -static GROM_CONFIG(_conf##2) \ -{ false, 2, _region, 0x4000, 0x1800, GROMFREQ }; -GROM_LIBRARY_CONFIG8(pascal1, region_gromlib1) -GROM_LIBRARY_CONFIG8(pascal2, region_gromlib2) -GROM_LIBRARY_CONFIG3(pascal3, region_gromlib3) READ8_MEMBER( ti99_8_state::cruread ) { @@ -660,33 +550,6 @@ WRITE_LINE_MEMBER( ti99_8_state::keyC3 ) set_keyboard_column(3, state); } -/* - Set 99/4A compatibility mode (CRUS=1) -*/ -WRITE_LINE_MEMBER( ti99_8_state::CRUS ) -{ - m_mainboard->CRUS_set(state==ASSERT_LINE); - - // In Armadillo mode, GROMs are located at f830; accordingly, the - // gromport must be reconfigured - if (state==ASSERT_LINE) - { - m_gromport->set_grom_base(0x9800, 0xfbf1); - } - else - { - m_gromport->set_grom_base(0xf830, 0xfff1); - } -} - -/* - Set mapper /PTGEN. This is negative logic; we use PTGE as the positive logic signal. -*/ -WRITE_LINE_MEMBER( ti99_8_state::PTGEN ) -{ - m_mainboard->PTGE_set(state==CLEAR_LINE); -} - /* Control cassette tape unit motor (P6) */ @@ -723,11 +586,11 @@ WRITE8_MEMBER( ti99_8_state::tms9901_interrupt ) /*****************************************************************************/ /* - set the state of TMS9901's INT2 (called by the tms9928 core) + set the state of TMS9901's INT2 (called by the VDP) */ WRITE_LINE_MEMBER( ti99_8_state::video_interrupt ) { - if (TRACE_INTERRUPTS) logerror("ti99_8: VDP int 2 on tms9901, level=%02x\n", state); + if (TRACE_INTERRUPTS) logerror("VDP int 2 on tms9901, level=%02x\n", state); m_int2 = (line_state)state; m_tms9901->set_single_int(2, state); } @@ -737,82 +600,59 @@ WRITE_LINE_MEMBER( ti99_8_state::video_interrupt ) ***********************************************************/ /* - We combine the incoming READY signals and propagate them to the CPU. - An alternative would be to let the CPU get the READY state, but this would - be a much higher overhead, as this happens in each clock tick. + Propagate READY signals to the CPU. */ -void ti99_8_state::console_ready_join(int id, int state) +void ti99_8_state::console_ready(int state) { - if (state==CLEAR_LINE) - m_nready_combined |= id; - else - m_nready_combined &= ~id; - if (TRACE_READY) { - if (m_nready_prev != m_nready_combined) logerror("ti99_8: READY bits = %04x\n", ~m_nready_combined); + if (m_ready_old != state) logerror("READY = %d\n", state); } - m_nready_prev = m_nready_combined; - m_cpu->ready_line(m_nready_combined==0); + m_ready_old = (line_state)state; + m_cpu->ready_line(state); } /* - Connections to the READY line. This might look a bit ugly; we need an - implementation of a "Wired AND" device. -*/ -WRITE_LINE_MEMBER( ti99_8_state::console_ready_grom ) -{ - console_ready_join(READY_GROM, state); -} - -WRITE_LINE_MEMBER( ti99_8_state::console_ready_mapper ) -{ - console_ready_join(READY_MAPPER, state); -} - -WRITE_LINE_MEMBER( ti99_8_state::console_ready_pbox ) -{ - console_ready_join(READY_PBOX, state); -} - -WRITE_LINE_MEMBER( ti99_8_state::console_ready_sound ) -{ - console_ready_join(READY_SOUND, state); -} - -WRITE_LINE_MEMBER( ti99_8_state::console_ready_cart ) -{ - console_ready_join(READY_CART, state); -} - -WRITE_LINE_MEMBER( ti99_8_state::console_ready_speech ) -{ - console_ready_join(READY_SPEECH, state); -} - -/* - The RESET line leading to a reset of the CPU. + Enqueue a RESET signal. */ WRITE_LINE_MEMBER( ti99_8_state::console_reset ) { + if (TRACE_RESET) logerror("Incoming RESET line = %d\n", state); if (machine().phase() != MACHINE_PHASE_INIT) { - m_cpu->set_input_line(INT_9995_RESET, state); - m_video->reset_vdp(state); + // RESET the 9901 + m_tms9901->rst1_line(state); + + // Pull up the CRUS and PTGEN lines (9901 outputs have been deactivated, pull-up resistors on the board show effect) + m_mainboard->crus_in(TRUE); // assert + m_mainboard->ptgen_in(TRUE); // clear + + // Setting ready to false so that automatic wait states are enabled + m_cpu->ready_line(CLEAR_LINE); + m_cpu->reset_line(ASSERT_LINE); } } +/* + The HOLD line leading to the CPU entering the HOLD state. +*/ +WRITE_LINE_MEMBER( ti99_8_state::cpu_hold ) +{ + if (TRACE_INTERRUPTS) logerror("Incoming HOLD line = %d\n", state); + m_cpu->hold_line(state); +} + WRITE_LINE_MEMBER( ti99_8_state::extint ) { - if (TRACE_READY) logerror("ti99_8: EXTINT level = %02x\n", state); + if (TRACE_INTERRUPTS) logerror("EXTINT level = %02x\n", state); m_int1 = (line_state)state; m_tms9901->set_single_int(1, state); } WRITE_LINE_MEMBER( ti99_8_state::notconnected ) { - if (TRACE_READY) logerror("ti99_8: Setting a not connected line ... ignored\n"); + if (TRACE_INTERRUPTS) logerror("Setting a not connected line ... ignored\n"); } WRITE8_MEMBER( ti99_8_state::external_operation ) @@ -821,7 +661,7 @@ WRITE8_MEMBER( ti99_8_state::external_operation ) if (offset == IDLE_OP) return; else { - logerror("ti99_4x: External operation %s not implemented on TI-99/8 board\n", extop[offset]); + logerror("External operation %s not implemented on TI-99/8 board\n", extop[offset]); } } @@ -833,119 +673,23 @@ WRITE_LINE_MEMBER( ti99_8_state::clock_out ) m_mainboard->clock_in(state); } -/*****************************************************************************/ - /* - Format: - Name, mode, stop, mask, select, write, read8z function, write8 function - - Multiple devices may have the same select pattern; as in the real hardware, - care must be taken that only one device actually responds. In the case of - GROMs, each chip has an internal address counter and an ID, and the chip - only responds when the ID and the most significant 3 bits match. - - NATIVE <-> CRUS=0 - TI99EM <-> CRUS=1 - - PATGEN <-> PTGEN=1 - - CONT: Mapper continues iterating through devices - STOP: Mapper stops iterating when found - - Access to the mapper registers is done directly in the mapper, not via - this list. - - TODO: This should (must) be improved in terms of performance. Every single - memory access goes through the mapper. Either we use an ordered search list, - or we order the entries according to their frequency. - (I did this right now, putting the Pascal GROMs at the end.) - We should think about a set entry where devices with the same address - are collected as one single entry (think about the Pascal lib with 21 GROMs, - twice eight and once three of them on the same address). + Data bus in (DBIN) line from the CPU. */ - -#define PASCAL_GROM_LIB8(_tag, _addr) \ - { _tag "0", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "1", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "2", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "3", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "4", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "5", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "6", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "7", PATGEN, CONT, _addr, 0xfff1, 0x0000 } - -#define PASCAL_GROM_LIB3(_tag, _addr) \ - { _tag "0", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "1", PATGEN, CONT, _addr, 0xfff1, 0x0000 }, \ - { _tag "2", PATGEN, CONT, _addr, 0xfff1, 0x0000 } - - -static const mapper8_list_entry mapper_devices[] = +WRITE_LINE_MEMBER( ti99_8_state::dbin_line ) { - // TI-99/4A mode (CRUS=1) - // Full/partial decoding has been verified on a real machine - // GROMs: According to the spec, the 99/8 supports up to 4 GROM libraries - // (99/4A supports 256 libraries) - // at 9800, 9804, 9808, 980c. Address counter access is at 9802,6,a,e. Write access +0400. - { ROM0NAME, TI99EM, STOP, 0x0000, 0xe000, 0x0000 }, // 0000-1fff - { TISOUND_TAG, TI99EM, STOP, 0x8400, 0xfff1, 0x0000 }, // 8400-840f - { VIDEO_SYSTEM_TAG, TI99EM, STOP, 0x8800, 0xfff1, 0x0400 }, // 8800,8802 / 8c00,8c02 - { SPEECH_TAG, TI99EM, STOP, 0x9000, 0xfff1, 0x0400 }, // 9000-900f / 9400-940f - { SRAMNAME, TI99EM, STOP, 0x8000, 0xf800, 0x0000 }, // 8000-87ff; must follow the sound generator - { MAINBOARD8_TAG, TI99EM, STOP, 0x8810, 0xfff0, 0x0000 }, - - { GROM0_TAG, TI99EM, CONT, 0x9800, 0xfff1, 0x0400 }, // 9800,2,4,...e/9c00,2,4,...e - { GROM1_TAG, TI99EM, CONT, 0x9800, 0xfff1, 0x0400 }, // dto. - { GROM2_TAG, TI99EM, CONT, 0x9800, 0xfff1, 0x0400 }, // dto. (GROMs are connected in parallel, - { GROMPORT_TAG, TI99EM, CONT, 0x9800, 0xfff1, 0x0400 }, // dto. use internal address counter and id) - - // TI-99/8 mode - // Full/partial decoding has been verified on a real machine - // Sound ports are at f800, f802, f804, ..., f80e - // VDP ports are (f810,f812), (f814,f816), (f818,f81a), (f81c,f81e) - // Note that unmapped GROM accesses (odd addresses like F831) return FF, - // not 00 as in our emulation, so that is not quite consistent, but tolerable ... I guess - - { SRAMNAME, NATIVE, STOP, 0xf000, 0xf800, 0x0000 }, // f000-f7ff - { TISOUND_TAG, NATIVE, STOP, 0xf800, 0xfff1, 0x0000 }, // f800-f80e (even addresses) - { VIDEO_SYSTEM_TAG, NATIVE, STOP, 0xf810, 0xfff1, 0x0000 }, // f810,2 (unlike 99/4A, no different read/write ports) - { SPEECH_TAG, NATIVE, STOP, 0xf820, 0xfff1, 0x0000 }, // f820-f82f - { MAINBOARD8_TAG, NATIVE, STOP, 0xf870, 0xfff0, 0x0000 }, - - { GROM0_TAG, NATIVE, CONT, 0xf830, 0xfff1, 0x0000 }, // f830-f83e (4 banks), no different read/write ports - { GROM1_TAG, NATIVE, CONT, 0xf830, 0xfff1, 0x0000 }, - { GROM2_TAG, NATIVE, CONT, 0xf830, 0xfff1, 0x0000 }, - { GROMPORT_TAG, NATIVE, CONT, 0xf830, 0xfff1, 0x0000 }, - - PASCAL_GROM_LIB8("pascal1_grom", 0xf840), - PASCAL_GROM_LIB8("pascal2_grom", 0xf850), - PASCAL_GROM_LIB3("pascal3_grom", 0xf860), - - // Physical (need to pack this in here as well to keep config simple) - // but these lines will be put into a separate list - { DRAMNAME, PHYSIC, STOP, 0x000000, 0xff0000, 0x000000 }, // 000000-00ffff 64 KiB DRAM - { PCODENAME, PHYSIC, STOP, 0xf00000, 0xffc000, 0x000000 }, // f00000-f03fff P-Code ROM - { MAINBOARD8_TAG, PHYSIC, CONT, 0xff4000, 0xffe000, 0x000000 }, // ff4000-ff5fff Internal DSR - { GROMPORT_TAG, PHYSIC, STOP, 0xff6000, 0xffe000, 0x000000 }, // ff6000-ff7fff Cartridge ROM space - { GROMPORT_TAG, PHYSIC, STOP, 0xff8000, 0xffe000, 0x000000 }, // ff8000-ff9fff Cartridge ROM space - { ROM1A0NAME, PHYSIC, STOP, 0xffa000, 0xffe000, 0x000000 }, // ffa000-ffbfff ROM1 - { ROM1C0NAME, PHYSIC, STOP, 0xffc000, 0xffe000, 0x000000 }, // ffc000-ffdfff ROM1 - { INTSNAME, PHYSIC, STOP, 0xffe000, 0xfffff0, 0x000000 }, // ffe000-ffe00f Interrupt level sense - { PERIBOX_TAG, PHYSIC, STOP, 0x000000, 0x000000, 0x000000 }, // Peripheral Expansion Box - - { nullptr, 0, 0, 0, 0, 0 } -}; - -static MAPPER8_CONFIG( mapper_conf ) -{ - mapper_devices -}; + m_mainboard->dbin_in(state); +} MACHINE_START_MEMBER(ti99_8_state,ti99_8) { - m_nready_combined = 0; m_peribox->senila(CLEAR_LINE); m_peribox->senilb(CLEAR_LINE); + // m_mainboard->set_gromport(m_gromport); + + // Need to configure the speech ROM for inverse bit order + speechrom_device* mem = subdevice(SPEECHROM_REG); + mem->set_reverse_bit_order(true); } MACHINE_RESET_MEMBER(ti99_8_state, ti99_8) @@ -956,9 +700,7 @@ MACHINE_RESET_MEMBER(ti99_8_state, ti99_8) // state on external memory accesses m_cpu->ready_line(CLEAR_LINE); - // But we assert the line here so that the system starts running - m_nready_combined = 0; - m_gromport->set_grom_base(0x9800, 0xfff1); + // m_gromport->set_grom_base(0x9800, 0xfff1); // Clear INT1 and INT2 latch m_int1 = CLEAR_LINE; @@ -972,62 +714,92 @@ static MACHINE_CONFIG_START( ti99_8, ti99_8_state ) MCFG_TMS99xx_ADD("maincpu", TMS9995_MP9537, XTAL_10_738635MHz, memmap, crumap) MCFG_TMS9995_EXTOP_HANDLER( WRITE8(ti99_8_state, external_operation) ) MCFG_TMS9995_CLKOUT_HANDLER( WRITELINE(ti99_8_state, clock_out) ) + MCFG_TMS9995_DBIN_HANDLER( WRITELINE(ti99_8_state, dbin_line) ) + MCFG_TMS9995_HOLDA_HANDLER( DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, holda_line) ) MCFG_MACHINE_START_OVERRIDE(ti99_8_state, ti99_8 ) MCFG_MACHINE_RESET_OVERRIDE(ti99_8_state, ti99_8 ) - /* Main board */ + // 9901 configuration MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, XTAL_10_738635MHz/4.0) MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_8_state, read_by_9901) ) MCFG_TMS9901_P0_HANDLER( WRITELINE( ti99_8_state, keyC0) ) MCFG_TMS9901_P1_HANDLER( WRITELINE( ti99_8_state, keyC1) ) MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_8_state, keyC2) ) MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_8_state, keyC3) ) - MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_8_state, CRUS) ) - MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_8_state, PTGEN) ) + MCFG_TMS9901_P4_HANDLER( DEVWRITELINE( MAINBOARD8_TAG, mainboard8_device, crus_in) ) + MCFG_TMS9901_P5_HANDLER( DEVWRITELINE( MAINBOARD8_TAG, mainboard8_device, ptgen_in) ) MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_8_state, cassette_motor) ) MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_8_state, audio_gate) ) MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_8_state, cassette_output) ) MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_8_state, tms9901_interrupt) ) - MCFG_MAINBOARD8_ADD( MAINBOARD8_TAG, mapper_conf ) - MCFG_MAINBOARD8_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_mapper)) - MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) - MCFG_GROMPORT_READY_HANDLER( WRITELINE(ti99_8_state, console_ready_cart) ) + // Mainboard with custom chips + MCFG_DEVICE_ADD(MAINBOARD8_TAG, MAINBOARD8, 0) + MCFG_MAINBOARD8_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready)) + MCFG_MAINBOARD8_RESET_CALLBACK(WRITELINE(ti99_8_state, console_reset)) + MCFG_MAINBOARD8_HOLD_CALLBACK(WRITELINE(ti99_8_state, cpu_hold)) + + MCFG_GROMPORT8_ADD( GROMPORT_TAG ) + MCFG_GROMPORT_READY_HANDLER( DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, system_grom_ready) ) MCFG_GROMPORT_RESET_HANDLER( WRITELINE(ti99_8_state, console_reset) ) - /* Peripheral expansion box */ + /* Software list */ + MCFG_SOFTWARE_LIST_ADD("cart_list_ti99", "ti99_cart") + + // Peripheral expansion box MCFG_DEVICE_ADD( PERIBOX_TAG, PERIBOX_998, 0) MCFG_PERIBOX_INTA_HANDLER( WRITELINE(ti99_8_state, extint) ) MCFG_PERIBOX_INTB_HANDLER( WRITELINE(ti99_8_state, notconnected) ) - MCFG_PERIBOX_READY_HANDLER( WRITELINE(ti99_8_state, console_ready_pbox) ) + MCFG_PERIBOX_READY_HANDLER( DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, pbox_ready) ) - /* Sound hardware */ - MCFG_TI_SOUND_76496_ADD( TISOUND_TAG ) - MCFG_TI_SOUND_READY_HANDLER( WRITELINE(ti99_8_state, console_ready_sound) ) + // Sound hardware + MCFG_SPEAKER_STANDARD_MONO("sound_out") + MCFG_SOUND_ADD(TISOUNDCHIP_TAG, SN76496, 3579545) /* 3.579545 MHz */ + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "sound_out", 0.75) + MCFG_SN76496_READY_HANDLER(DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, sound_ready)) - /* Cassette drives */ + // Speech hardware + // Note: SPEECHROM uses its tag for referencing the region + MCFG_DEVICE_ADD(SPEECHROM_REG, SPEECHROM, 0) + MCFG_SPEAKER_STANDARD_MONO("speech_out") + MCFG_SOUND_ADD(SPEECHSYN_TAG, CD2501ECD, 640000L) + MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, speech_ready)) + MCFG_TMS52XX_SPEECHROM(SPEECHROM_REG) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speech_out", 0.50) + + // Cassette drive MCFG_SPEAKER_STANDARD_MONO("cass_out") MCFG_CASSETTE_ADD( "cassette" ) MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "cass_out", 0.25) - /* Console GROMs */ - MCFG_GROM_ADD( GROM0_TAG, grom0_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_grom)) - MCFG_GROM_ADD( GROM1_TAG, grom1_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_grom)) - MCFG_GROM_ADD( GROM2_TAG, grom2_config ) - MCFG_GROM_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_grom)) + // GROM library + MCFG_GROM_ADD( SYSGROM0_TAG, 0, SYSGROM_REG, 0x0000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, system_grom_ready)) + MCFG_GROM_ADD( SYSGROM1_TAG, 1, SYSGROM_REG, 0x2000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, system_grom_ready)) + MCFG_GROM_ADD( SYSGROM2_TAG, 2, SYSGROM_REG, 0x4000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, system_grom_ready)) - /* Pascal GROM libraries. */ - MCFG_GROM_LIBRARY_ADD8(pascal1_grom, pascal1) - MCFG_GROM_LIBRARY_ADD8(pascal2_grom, pascal2) - MCFG_GROM_LIBRARY_ADD3(pascal3_grom, pascal3) + MCFG_GROM_ADD( GLIB10_TAG, 0, GROMLIB1_REG, 0x0000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB11_TAG, 1, GROMLIB1_REG, 0x2000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB12_TAG, 2, GROMLIB1_REG, 0x4000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB13_TAG, 3, GROMLIB1_REG, 0x6000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB14_TAG, 4, GROMLIB1_REG, 0x8000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB15_TAG, 5, GROMLIB1_REG, 0xa000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB16_TAG, 6, GROMLIB1_REG, 0xc000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) + MCFG_GROM_ADD( GLIB17_TAG, 7, GROMLIB1_REG, 0xe000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, ptts_grom_ready)) - /* Devices */ - MCFG_DEVICE_ADD(SPEECH_TAG, SPEECH8, 0) - MCFG_SPEECH8_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_speech)) + MCFG_GROM_ADD( GLIB20_TAG, 0, GROMLIB2_REG, 0x0000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB21_TAG, 1, GROMLIB2_REG, 0x2000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB22_TAG, 2, GROMLIB2_REG, 0x4000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB23_TAG, 3, GROMLIB2_REG, 0x6000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB24_TAG, 4, GROMLIB2_REG, 0x8000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB25_TAG, 5, GROMLIB2_REG, 0xa000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB26_TAG, 6, GROMLIB2_REG, 0xc000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + MCFG_GROM_ADD( GLIB27_TAG, 7, GROMLIB2_REG, 0xe000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p8_grom_ready)) + + MCFG_GROM_ADD( GLIB30_TAG, 0, GROMLIB3_REG, 0x0000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p3_grom_ready)) + MCFG_GROM_ADD( GLIB31_TAG, 1, GROMLIB3_REG, 0x2000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p3_grom_ready)) + MCFG_GROM_ADD( GLIB32_TAG, 2, GROMLIB3_REG, 0x4000, DEVWRITELINE(MAINBOARD8_TAG, mainboard8_device, p3_grom_ready)) // Joystick port MCFG_TI_JOYPORT4A_ADD( JOYPORT_TAG ) @@ -1037,14 +809,24 @@ MACHINE_CONFIG_END TI-99/8 US version (NTSC, 60 Hz) */ static MACHINE_CONFIG_DERIVED( ti99_8_60hz, ti99_8 ) - MCFG_TI998_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9118, 0x4000, ti99_8_state, video_interrupt) + // Video hardware + MCFG_DEVICE_ADD( VDP_TAG, TMS9118, XTAL_10_738635MHz / 2 ) + MCFG_TMS9928A_VRAM_SIZE(0x4000) + MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(ti99_8_state, video_interrupt)) + MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG ) + MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) MACHINE_CONFIG_END /* TI-99/8 European version (PAL, 50 Hz) */ static MACHINE_CONFIG_DERIVED( ti99_8_50hz, ti99_8 ) - MCFG_TI998_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9129, 0x4000, ti99_8_state, video_interrupt) + // Video hardware + MCFG_DEVICE_ADD( VDP_TAG, TMS9129, XTAL_10_738635MHz / 2 ) + MCFG_TMS9928A_VRAM_SIZE(0x4000) + MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(ti99_8_state,video_interrupt)) + MCFG_TMS9928A_SCREEN_ADD_PAL( SCREEN_TAG ) + MCFG_SCREEN_UPDATE_DEVICE( VDP_TAG, tms9928a_device, screen_update ) MACHINE_CONFIG_END /* @@ -1055,11 +837,11 @@ MACHINE_CONFIG_END */ ROM_START(ti99_8) // Logical (CPU) memory space: ROM0 - ROM_REGION(0x2000, ROM0_TAG, 0) + ROM_REGION(0x2000, ROM0_REG, 0) ROM_LOAD("u4_rom0.bin", 0x0000, 0x2000, CRC(901eb8d6) SHA1(13190c5e834baa9c0a70066b566cfcef438ed88a)) // Physical memory space (mapped): ROM1 - ROM_REGION(0x8000, ROM1_TAG, 0) + ROM_REGION(0x8000, ROM1_REG, 0) ROM_LOAD("u25_rom1.bin", 0x0000, 0x8000, CRC(b574461a) SHA1(42c6aed44802cfabdd26b565d6e5ddfcd689f11e)) // Physical memory space (mapped): P-Code ROM @@ -1069,20 +851,20 @@ ROM_START(ti99_8) // the required select line for this ROM on the available schematics, so // they seem to be from the earlier version. The location in the address // space was determined by ROM disassembly. - ROM_REGION(0x8000, PCODEROM_TAG, 0) + ROM_REGION(0x8000, PASCAL_REG, 0) ROM_LOAD("u25a_pas.bin", 0x0000, 0x4000, CRC(d7ed6dd6) SHA1(32212ce6426ceccbff73d342d4a3ef699c0ae1e4)) // System GROMs. 3 chips @ f830 // The schematics do not enumerate the circuits but only talk about // "circuits on board" (COB) so we name the GROMs as gM_N.bin where M is the // ID (0-7) and N is the access port in the logical address space. - ROM_REGION(0x6000, region_sysgrom, 0) + ROM_REGION(0x6000, SYSGROM_REG, 0) ROM_LOAD("g0_f830.bin", 0x0000, 0x1800, CRC(1026db60) SHA1(7327095bf4f390476e69d9fd8424e98ea1f2325a)) ROM_LOAD("g1_f830.bin", 0x2000, 0x1800, CRC(93a43d65) SHA1(19be8a07d674bc7554c2bc9c7a5725d81e888e6e)) ROM_LOAD("g2_f830.bin", 0x4000, 0x1800, CRC(06f2b901) SHA1(f65e0fcb2c63e230b4a9563c72f91259b94ce955)) // TTS & Pascal library. 8 chips @ f840 - ROM_REGION(0x10000, region_gromlib1, 0) + ROM_REGION(0x10000, GROMLIB1_REG, 0) ROM_LOAD("g0_f840.bin", 0x0000, 0x1800, CRC(44501071) SHA1(4b5ef7f1aa43a87e7ae4f02090944be5c39b1f26)) ROM_LOAD("g1_f840.bin", 0x2000, 0x1800, CRC(5a271d9e) SHA1(bb95befa2ffba2cc17ac437386e069e8ff621248)) ROM_LOAD("g2_f840.bin", 0x4000, 0x1800, CRC(d52502df) SHA1(17063e33ee8709d0df8030f38bb92c4322d55e1e)) @@ -1093,7 +875,7 @@ ROM_START(ti99_8) ROM_LOAD("g7_f840.bin", 0xE000, 0x1800, CRC(3a9d20df) SHA1(1e6f9f8ec7df4b997a7579be742d0a7d54bc8763)) // Pascal library. 8 chips @ f850 - ROM_REGION(0x10000, region_gromlib2, 0) + ROM_REGION(0x10000, GROMLIB2_REG, 0) ROM_LOAD("g0_f850.bin", 0x0000, 0x1800, CRC(2d948672) SHA1(cf15912d6dae5a450e0cfd796aa36ea5e521dc56)) ROM_LOAD("g1_f850.bin", 0x2000, 0x1800, CRC(7d64a842) SHA1(d5884bb2af21c8027311478ee506beac6f46203d)) ROM_LOAD("g2_f850.bin", 0x4000, 0x1800, CRC(e5ed8900) SHA1(03826882ce10fb5a6b3a9ccc85d3d1fe51979d0b)) @@ -1104,17 +886,15 @@ ROM_START(ti99_8) ROM_LOAD("g7_f850.bin", 0xE000, 0x1800, CRC(71534098) SHA1(75e87123efde885e27dd749e07cb189eb2cc45a8)) // Pascal library. 3 chips @ f860 - ROM_REGION(0x6000, region_gromlib3, 0) + ROM_REGION(0x6000, GROMLIB3_REG, 0) ROM_LOAD("g0_f860.bin", 0x0000, 0x1800, CRC(0ceef210) SHA1(b89957fbff094b758746391a69dea6907c66b950)) ROM_LOAD("g1_f860.bin", 0x2000, 0x1800, CRC(fc87de25) SHA1(4695b7f979f59a01ec16c55e4587c3379482b658)) ROM_LOAD("g2_f860.bin", 0x4000, 0x1800, CRC(e833e350) SHA1(6ffe501981a1112be1af596a489d96e287fc6be5)) - // Built-in RAM - ROM_REGION(SRAM_SIZE, SRAM_TAG, 0) - ROM_FILL(0x0000, SRAM_SIZE, 0x00) - - ROM_REGION(DRAM_SIZE, DRAM_TAG, 0) - ROM_FILL(0x0000, DRAM_SIZE, 0x00) + // Speech ROM + ROM_REGION(0x8000, SPEECHROM_REG, 0) + ROM_LOAD("cd2325a.vsm", 0x0000, 0x4000, CRC(1f58b571) SHA1(0ef4f178716b575a1c0c970c56af8a8d97561ffe)) + ROM_LOAD("cd2326a.vsm", 0x4000, 0x4000, CRC(65d00401) SHA1(a367242c2c96cebf0e2bf21862f3f6734b2b3020)) ROM_END #define rom_ti99_8e rom_ti99_8 diff --git a/src/mame/includes/multfish.h b/src/mame/includes/multfish.h index ed6d3fae67a..b158cb5b8b7 100644 --- a/src/mame/includes/multfish.h +++ b/src/mame/includes/multfish.h @@ -93,24 +93,6 @@ public: required_device m_palette; }; -#define mfish_parent mfish_13 -#define czmon_parent czmon_13 -#define fcockt_parent fcockt_8 -#define lhaunt_parent lhaunt_6 -#define rollfr_parent rollfr_4 -#define garage_parent garage_5 -#define rclimb_parent rclimb_3 -#define sweetl_parent sweetl -#define resdnt_parent resdnt_6 -#define island_parent island -#define pirate_parent pirate_3 -#define island2_parent island2 -#define pirate2_parent pirate2 -#define keks_parent keks_2 -#define gnome_parent gnome_9 -#define sweetl2_parent sweetl2 -#define fcockt2_parent fcockt2 -#define crzmon2_parent crzmon2 MACHINE_CONFIG_EXTERN( igrosoft_gamble ); MACHINE_CONFIG_EXTERN( rollfr ); diff --git a/src/mame/layout/fidel_csc.lay b/src/mame/layout/fidel_csc.lay index 22aed7ef11c..57748249513 100644 --- a/src/mame/layout/fidel_csc.lay +++ b/src/mame/layout/fidel_csc.lay @@ -128,27 +128,27 @@ - + - + - + - + - + - + @@ -424,12 +424,12 @@ - - - - - - + + + + + + diff --git a/src/mame/layout/fidel_eag.lay b/src/mame/layout/fidel_eag.lay index f321527a168..2d57b63b89a 100644 --- a/src/mame/layout/fidel_eag.lay +++ b/src/mame/layout/fidel_eag.lay @@ -113,12 +113,12 @@ - - - - - - + + + + + + @@ -380,12 +380,12 @@ - - - - - - + + + + + + diff --git a/src/mame/layout/fidel_fev.lay b/src/mame/layout/fidel_fev.lay index 93d4abaf163..8c5eefe0598 100644 --- a/src/mame/layout/fidel_fev.lay +++ b/src/mame/layout/fidel_fev.lay @@ -198,27 +198,27 @@ - + - + - + - + - + - + @@ -434,12 +434,12 @@ - - - - - - + + + + + + diff --git a/src/mame/layout/fidel_vsc.lay b/src/mame/layout/fidel_vsc.lay index f9c2c742620..6f94efb0b3c 100644 --- a/src/mame/layout/fidel_vsc.lay +++ b/src/mame/layout/fidel_vsc.lay @@ -126,27 +126,27 @@ - + - + - + - + - + - + @@ -422,12 +422,12 @@ - - - - - - + + + + + + diff --git a/src/mame/layout/gjackpot.lay b/src/mame/layout/gjackpot.lay index 84d57fc9745..b05b961360d 100644 --- a/src/mame/layout/gjackpot.lay +++ b/src/mame/layout/gjackpot.lay @@ -30,20 +30,20 @@ - - + + - - + + - - + + - - + + @@ -138,7 +138,6 @@ - @@ -170,6 +169,5 @@ - diff --git a/src/mame/layout/gpoker.lay b/src/mame/layout/gpoker.lay index 25578e687f2..93ac57a043c 100644 --- a/src/mame/layout/gpoker.lay +++ b/src/mame/layout/gpoker.lay @@ -22,20 +22,20 @@ - - + + - - + + - - + + - - + + @@ -130,7 +130,6 @@ - @@ -151,6 +150,5 @@ - diff --git a/src/mame/layout/sc4fd7tha.lay b/src/mame/layout/sc4fd7tha.lay index 5fdf86c0d3a..83e7f1d3c8e 100644 --- a/src/mame/layout/sc4fd7tha.lay +++ b/src/mame/layout/sc4fd7tha.lay @@ -975,7 +975,7 @@ - + @@ -1001,7 +1001,7 @@ - + @@ -1027,7 +1027,7 @@ - + @@ -1053,7 +1053,7 @@ - + @@ -1079,7 +1079,7 @@ - + @@ -1105,7 +1105,7 @@ - + @@ -1131,7 +1131,7 @@ - + @@ -1157,7 +1157,7 @@ - + @@ -1183,7 +1183,7 @@ - + @@ -2923,7 +2923,7 @@ - + @@ -2955,7 +2955,7 @@ - + @@ -2987,7 +2987,7 @@ - + @@ -3019,7 +3019,7 @@ - + @@ -3051,7 +3051,7 @@ - + @@ -3083,7 +3083,7 @@ - + @@ -3953,7 +3953,7 @@ - + @@ -3979,7 +3979,7 @@ - + @@ -4005,7 +4005,7 @@ - + @@ -4031,7 +4031,7 @@ - + @@ -4057,7 +4057,7 @@ - + @@ -4083,7 +4083,7 @@ - + @@ -4109,7 +4109,7 @@ - + @@ -4135,7 +4135,7 @@ - + @@ -4161,7 +4161,7 @@ - + @@ -4187,7 +4187,7 @@ - + @@ -4213,7 +4213,7 @@ - + @@ -4239,7 +4239,7 @@ - + @@ -4529,7 +4529,7 @@ - + diff --git a/src/mame/layout/spyhunttec.lay b/src/mame/layout/spyhunttec.lay new file mode 100644 index 00000000000..f77457e680e --- /dev/null +++ b/src/mame/layout/spyhunttec.lay @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/supercon.lay b/src/mame/layout/supercon.lay index 831c63d673f..7df19dd70ac 100644 --- a/src/mame/layout/supercon.lay +++ b/src/mame/layout/supercon.lay @@ -87,36 +87,36 @@ - - - - - - + + + + + + - + - + - + - + - + - + @@ -379,12 +379,12 @@ - - - - - - + + + + + + @@ -417,15 +417,6 @@ - - - - - - - - - @@ -435,13 +426,21 @@ - - - - - - + + + + + + + + + + + + + + diff --git a/src/mame/layout/zodiac.lay b/src/mame/layout/zodiac.lay index 04f6089e032..e21e121b21b 100644 --- a/src/mame/layout/zodiac.lay +++ b/src/mame/layout/zodiac.lay @@ -16,18 +16,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -64,19 +64,19 @@ - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp index 634332899c3..3c85b5f4119 100644 --- a/src/osd/modules/debugger/debugwin.cpp +++ b/src/osd/modules/debugger/debugwin.cpp @@ -163,8 +163,8 @@ void debugger_windows::debugger_update() debug_cpu_get_visible_cpu(*m_machine)->debug()->halt_on_next_instruction("User-initiated break\n"); // if we were focused on some window's edit box, reset it to default - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->restore_field(focuswnd); + for (debugwin_info &info : m_window_list) + info.restore_field(focuswnd); } } } @@ -229,16 +229,16 @@ void debugger_windows::remove_window(debugwin_info &info) void debugger_windows::show_all() { - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->show(); + for (debugwin_info &info : m_window_list) + info.show(); } void debugger_windows::hide_all() { SetForegroundWindow(win_window_list->m_hwnd); - for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next()) - info->hide(); + for (debugwin_info &info : m_window_list) + info.hide(); } diff --git a/src/osd/modules/debugger/osx/deviceinfoviewer.mm b/src/osd/modules/debugger/osx/deviceinfoviewer.mm index 1f045870883..dd1b43ccf60 100644 --- a/src/osd/modules/debugger/osx/deviceinfoviewer.mm +++ b/src/osd/modules/debugger/osx/deviceinfoviewer.mm @@ -165,7 +165,7 @@ toView:contentView]; // add interfaces if present - device_interface *interface = device->first_interface(); + device_interface *interface = device->interfaces().first(); if (interface != NULL) { NSBox *const interfacesBox = [self makeBox:@"Interfaces" toFit:contentView]; diff --git a/src/osd/modules/debugger/osx/devicesviewer.mm b/src/osd/modules/debugger/osx/devicesviewer.mm index ddf08602bc6..356cc2d1393 100644 --- a/src/osd/modules/debugger/osx/devicesviewer.mm +++ b/src/osd/modules/debugger/osx/devicesviewer.mm @@ -34,7 +34,7 @@ - (void)wrapChildren { NSMutableArray *const tmp = [[NSMutableArray alloc] init]; - for (device_t *child = device->first_subdevice(); child != NULL; child = child->next()) + for (device_t *child = device->subdevices().first(); child != NULL; child = child->next()) { MAMEDeviceWrapper *const wrap = [[MAMEDeviceWrapper alloc] initWithMachine:*machine device:*child]; diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp index ae8f1ff35e3..3a430f67a84 100644 --- a/src/osd/modules/debugger/qt/dasmwindow.cpp +++ b/src/osd/modules/debugger/qt/dasmwindow.cpp @@ -265,11 +265,9 @@ void DasmWindow::populateComboBox() return; m_cpuComboBox->clear(); - for (const debug_view_source* source = m_dasmView->view()->first_source(); - source != NULL; - source = source->next()) + for (const debug_view_source &source : m_dasmView->view()->source_list()) { - m_cpuComboBox->addItem(source->name()); + m_cpuComboBox->addItem(source.name()); } } diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp index 54cc4406d23..12a286ff2b6 100644 --- a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp +++ b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp @@ -51,7 +51,7 @@ void DeviceInformationWindow::fill_device_information() gl1->addWidget(new QLabel(QString(m_device->shortname()), primaryFrame), 2, 1); int cpos = 3; - device_interface *intf = m_device->first_interface(); + device_interface *intf = m_device->interfaces().first(); if(intf) { gl1->addWidget(new QLabel(QString("Interfaces"), primaryFrame), cpos, 0); while(intf) { diff --git a/src/osd/modules/debugger/qt/deviceswindow.cpp b/src/osd/modules/debugger/qt/deviceswindow.cpp index b9c8f276f69..e14e552fc81 100644 --- a/src/osd/modules/debugger/qt/deviceswindow.cpp +++ b/src/osd/modules/debugger/qt/deviceswindow.cpp @@ -55,7 +55,7 @@ QModelIndex DevicesWindowModel::index(int row, int column, const QModelIndex &pa } else { device_t *dparent = static_cast(parent.internalPointer()); int count = row; - for(target = dparent->first_subdevice(); count && target; target = target->next()) + for(target = dparent->subdevices().first(); count && target; target = target->next()) count--; } @@ -79,7 +79,7 @@ QModelIndex DevicesWindowModel::parent(const QModelIndex &index) const device_t *dpp = dparent->owner(); int row = 0; if(dpp) { - for(device_t *child = dpp->first_subdevice(); child && child != dparent; child = child->next()) + for(device_t *child = dpp->subdevices().first(); child && child != dparent; child = child->next()) row++; } return createIndex(row, 0, dparent); @@ -92,8 +92,11 @@ int DevicesWindowModel::rowCount(const QModelIndex &parent) const device_t *dparent = static_cast(parent.internalPointer()); int count = 0; - for(device_t *child = dparent->first_subdevice(); child; child = child->next()) + for (device_t &child : dparent->subdevices()) + { + (void)child; count++; + } return count; } diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp index 3992dc0fd85..7b86740fe51 100644 --- a/src/osd/modules/debugger/qt/memorywindow.cpp +++ b/src/osd/modules/debugger/qt/memorywindow.cpp @@ -282,11 +282,9 @@ void MemoryWindow::populateComboBox() return; m_memoryComboBox->clear(); - for (const debug_view_source* source = m_memTable->view()->first_source(); - source != NULL; - source = source->next()) + for (const debug_view_source &source : m_memTable->view()->source_list()) { - m_memoryComboBox->addItem(source->name()); + m_memoryComboBox->addItem(source.name()); } } diff --git a/src/osd/modules/debugger/win/debugviewinfo.cpp b/src/osd/modules/debugger/win/debugviewinfo.cpp index 3a8aab66d74..3f355cf8a34 100644 --- a/src/osd/modules/debugger/win/debugviewinfo.cpp +++ b/src/osd/modules/debugger/win/debugviewinfo.cpp @@ -110,9 +110,9 @@ UINT32 debugview_info::maxwidth() { UINT32 max = m_view->total_size().x; debug_view_source const *const cursource = m_view->source(); - for (debug_view_source const *source = m_view->first_source(); source != NULL; source = source->next()) + for (const debug_view_source &source : m_view->source_list()) { - m_view->set_source(*source); + m_view->set_source(source); UINT32 const chars = m_view->total_size().x; if (max < chars) max = chars; diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp index 03e924b5a71..0f6116fa048 100644 --- a/src/osd/modules/input/input_sdlcommon.cpp +++ b/src/osd/modules/input/input_sdlcommon.cpp @@ -139,14 +139,13 @@ void sdl_osd_interface::customize_input_type_list(simple_list { input_item_id mameid_code; input_code ui_code; - input_type_entry *entry; const char* uimode; char fullmode[64]; // loop over the defaults - for (entry = typelist.first(); entry != NULL; entry = entry->next()) + for (input_type_entry &entry : typelist) { - switch (entry->type()) + switch (entry.type()) { // configurable UI mode switch case IPT_UI_TOGGLE_UI: @@ -165,23 +164,23 @@ void sdl_osd_interface::customize_input_type_list(simple_list mameid_code = keyboard_trans_table::instance().lookup_mame_code(fullmode); } ui_code = input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, input_item_id(mameid_code)); - entry->defseq(SEQ_TYPE_STANDARD).set(ui_code); + entry.defseq(SEQ_TYPE_STANDARD).set(ui_code); break; // alt-enter for fullscreen case IPT_OSD_1: - entry->configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT); + entry.configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT); break; // disable UI_SELECT when LALT is down, this stops selecting // things in the menu when toggling fullscreen with LALT+ENTER /* case IPT_UI_SELECT: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT); break;*/ // page down for fastforward (must be OSD_3 as per src/emu/ui.c) case IPT_UI_FAST_FORWARD: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_PGDN); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_PGDN); break; // OSD hotkeys use LCTRL and start at F3, they start at @@ -191,63 +190,63 @@ void sdl_osd_interface::customize_input_type_list(simple_list // LCTRL-F3 to toggle fullstretch case IPT_OSD_2: - entry->configure_osd("TOGGLE_FULLSTRETCH", "Toggle Uneven stretch"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_FULLSTRETCH", "Toggle Uneven stretch"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the reset key case IPT_UI_SOFT_RESET: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F3, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); break; // LCTRL-F4 to toggle keep aspect case IPT_OSD_4: - entry->configure_osd("TOGGLE_KEEP_ASPECT", "Toggle Keepaspect"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_KEEP_ASPECT", "Toggle Keepaspect"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the show gfx key case IPT_UI_SHOW_GFX: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F4, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F5 to toggle OpenGL filtering case IPT_OSD_5: - entry->configure_osd("TOGGLE_FILTER", "Toggle Filter"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LCONTROL); + entry.configure_osd("TOGGLE_FILTER", "Toggle Filter"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the toggle debug key case IPT_UI_TOGGLE_DEBUG: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F6 to decrease OpenGL prescaling case IPT_OSD_6: - entry->configure_osd("DECREASE_PRESCALE", "Decrease Prescaling"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, KEYCODE_LCONTROL); + entry.configure_osd("DECREASE_PRESCALE", "Decrease Prescaling"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the toggle cheat key case IPT_UI_TOGGLE_CHEAT: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F6, input_seq::not_code, KEYCODE_LCONTROL); break; // LCTRL-F7 to increase OpenGL prescaling case IPT_OSD_7: - entry->configure_osd("INCREASE_PRESCALE", "Increase Prescaling"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, KEYCODE_LCONTROL); + entry.configure_osd("INCREASE_PRESCALE", "Increase Prescaling"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, KEYCODE_LCONTROL); break; // add a Not lcrtl condition to the load state key case IPT_UI_LOAD_STATE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F7, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LSHIFT); break; // add a Not lcrtl condition to the throttle key case IPT_UI_THROTTLE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F10, input_seq::not_code, KEYCODE_LCONTROL); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F10, input_seq::not_code, KEYCODE_LCONTROL); break; // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between apps) case IPT_UI_CONFIGURE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; // leave everything else alone diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp index 1ad092e1281..2132247b828 100644 --- a/src/osd/modules/input/input_windows.cpp +++ b/src/osd/modules/input/input_windows.cpp @@ -54,17 +54,16 @@ void windows_osd_interface::poll_input(running_machine &machine) const void windows_osd_interface::customize_input_type_list(simple_list &typelist) { - input_type_entry *entry; const char* uimode; // loop over the defaults - for (entry = typelist.first(); entry != nullptr; entry = entry->next()) - switch (entry->type()) + for (input_type_entry &entry : typelist) + switch (entry.type()) { // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between windows apps) case IPT_UI_CONFIGURE: - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; // configurable UI mode switch @@ -78,50 +77,50 @@ void windows_osd_interface::customize_input_type_list(simple_listdefseq(SEQ_TYPE_STANDARD).set(ui_code); + entry.defseq(SEQ_TYPE_STANDARD).set(ui_code); } } break; // alt-enter for fullscreen case IPT_OSD_1: - entry->configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT, input_seq::or_code, KEYCODE_ENTER, KEYCODE_RALT); + entry.configure_osd("TOGGLE_FULLSCREEN", "Toggle Fullscreen"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_ENTER, KEYCODE_LALT, input_seq::or_code, KEYCODE_ENTER, KEYCODE_RALT); break; // lalt-F12 for fullscreen snap (HLSL) case IPT_OSD_2: - entry->configure_osd("RENDER_SNAP", "Take Rendered Snapshot"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LALT, input_seq::not_code, KEYCODE_LSHIFT); + entry.configure_osd("RENDER_SNAP", "Take Rendered Snapshot"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LALT, input_seq::not_code, KEYCODE_LSHIFT); break; // add a NOT-lalt to our default F12 case IPT_UI_SNAPSHOT: // emu/input.c: input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // lshift-lalt-F12 for fullscreen video (HLSL) case IPT_OSD_3: - entry->configure_osd("RENDER_AVI", "Record Rendered Video"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LALT); + entry.configure_osd("RENDER_AVI", "Record Rendered Video"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LALT); break; // add a NOT-lalt to our default shift-F12 case IPT_UI_RECORD_MOVIE: // emu/input.c: input_seq(KEYCODE_F12, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // add a NOT-lalt to write timecode file case IPT_UI_TIMECODE: // emu/input.c: input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LALT); break; // lctrl-lalt-F5 to toggle post-processing case IPT_OSD_4: - entry->configure_osd("POST_PROCESS", "Toggle Post-Processing"); - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LALT, KEYCODE_LCONTROL); + entry.configure_osd("POST_PROCESS", "Toggle Post-Processing"); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, KEYCODE_LALT, KEYCODE_LCONTROL); break; // add a NOT-lctrl-lalt to our default F5 case IPT_UI_TOGGLE_DEBUG: // emu/input.c: input_seq(KEYCODE_F5) - entry->defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT); + entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_F5, input_seq::not_code, KEYCODE_LCONTROL, input_seq::not_code, KEYCODE_LALT); break; // leave everything else alone diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp index f189fc48cca..79356d4ea22 100644 --- a/src/osd/modules/render/draw13.cpp +++ b/src/osd/modules/render/draw13.cpp @@ -248,17 +248,17 @@ void texture_info::set_coloralphamode(SDL_Texture *texture_id, const render_colo } } -void texture_info::render_quad(const render_primitive *prim, const int x, const int y) +void texture_info::render_quad(const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; - target_rect.w = round_nearest(prim->bounds.x1) - round_nearest(prim->bounds.x0); - target_rect.h = round_nearest(prim->bounds.y1) - round_nearest(prim->bounds.y0); + target_rect.w = round_nearest(prim.bounds.x1) - round_nearest(prim.bounds.x0); + target_rect.h = round_nearest(prim.bounds.y1) - round_nearest(prim.bounds.y0); SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); - set_coloralphamode(m_texture_id, &prim->color); + set_coloralphamode(m_texture_id, &prim.color); //printf("%d %d %d %d\n", target_rect.x, target_rect.y, target_rect.w, target_rect.h); // Arghhh .. Just another bug. SDL_RenderCopy has severe issues with scaling ... SDL_RenderCopy(m_renderer->m_sdl_renderer, m_texture_id, nullptr, &target_rect); @@ -266,14 +266,14 @@ void texture_info::render_quad(const render_primitive *prim, const int x, const //SDL_RenderCopyEx(m_renderer->m_sdl_renderer, m_texture_id, nullptr, nullptr, 0, nullptr, SDL_FLIP_NONE); } -void renderer_sdl1::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) +void renderer_sdl1::render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y) { SDL_Rect target_rect; target_rect.x = x; target_rect.y = y; - target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); - target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); + target_rect.w = round_nearest(prim.bounds.x1 - prim.bounds.x0); + target_rect.h = round_nearest(prim.bounds.y1 - prim.bounds.y0); if (texture) { @@ -292,12 +292,12 @@ void renderer_sdl1::render_quad(texture_info *texture, const render_primitive *p } else { - UINT32 sr = (UINT32)(255.0f * prim->color.r); - UINT32 sg = (UINT32)(255.0f * prim->color.g); - UINT32 sb = (UINT32)(255.0f * prim->color.b); - UINT32 sa = (UINT32)(255.0f * prim->color.a); + UINT32 sr = (UINT32)(255.0f * prim.color.r); + UINT32 sg = (UINT32)(255.0f * prim.color.g); + UINT32 sb = (UINT32)(255.0f * prim.color.b); + UINT32 sa = (UINT32)(255.0f * prim.color.a); - SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); + SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); SDL_RenderFillRect(m_sdl_renderer, &target_rect); } @@ -499,7 +499,6 @@ void renderer_sdl1::destroy_all_textures() int renderer_sdl1::draw(int update) { - render_primitive *prim; texture_info *texture=nullptr; float vofs, hofs; int blit_pixels = 0; @@ -559,30 +558,30 @@ int renderer_sdl1::draw(int update) window().m_primlist->acquire_lock(); // now draw - for (prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { Uint8 sr, sg, sb, sa; - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - sr = (int)(255.0f * prim->color.r); - sg = (int)(255.0f * prim->color.g); - sb = (int)(255.0f * prim->color.b); - sa = (int)(255.0f * prim->color.a); + sr = (int)(255.0f * prim.color.r); + sg = (int)(255.0f * prim.color.g); + sb = (int)(255.0f * prim.color.b); + sa = (int)(255.0f * prim.color.a); - SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); + SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags))); SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa); - SDL_RenderDrawLine(m_sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, - prim->bounds.x1 + hofs, prim->bounds.y1 + vofs); + SDL_RenderDrawLine(m_sdl_renderer, prim.bounds.x0 + hofs, prim.bounds.y0 + vofs, + prim.bounds.x1 + hofs, prim.bounds.y1 + vofs); break; case render_primitive::QUAD: - texture = texture_update(*prim); + texture = texture_update(prim); if (texture) blit_pixels += (texture->raw_height() * texture->raw_width()); render_quad(texture, prim, - round_nearest(hofs + prim->bounds.x0), - round_nearest(vofs + prim->bounds.y0)); + round_nearest(hofs + prim.bounds.x0), + round_nearest(vofs + prim.bounds.y0)); break; default: throw emu_fatalerror("Unexpected render_primitive type\n"); diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h index e6d15a757bb..3bd8acf608b 100644 --- a/src/osd/modules/render/draw13.h +++ b/src/osd/modules/render/draw13.h @@ -62,7 +62,7 @@ public: ~texture_info(); void set_data(const render_texinfo &texsource, const UINT32 flags); - void render_quad(const render_primitive *prim, const int x, const int y); + void render_quad(const render_primitive &prim, const int x, const int y); bool matches(const render_primitive &prim, const quad_setup_data &setup); copy_info_t *compute_size_type(); @@ -176,7 +176,7 @@ private: void expand_copy_info(const copy_info_t *list); void add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm); - void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); + void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y); texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup); texture_info *texture_update(const render_primitive &prim); diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 0b98fe24d6b..85b76864b23 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -1226,21 +1226,21 @@ bool renderer_bgfx::check_for_dirty_atlas() bool atlas_dirty = false; std::map acquired_infos; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - bool pack = prim->packable(PACKABLE_SIZE); - if (prim->type == render_primitive::QUAD && prim->texture.base != nullptr && pack) + bool pack = prim.packable(PACKABLE_SIZE); + if (prim.type == render_primitive::QUAD && prim.texture.base != nullptr && pack) { - const UINT32 hash = get_texture_hash(prim); + const UINT32 hash = get_texture_hash(&prim); // If this texture is packable and not currently in the atlas, prepare the texture for putting in the atlas if ((hash != 0 && m_hash_to_entry[hash].hash() == 0 && acquired_infos[hash].hash() == 0) || (hash != 0 && m_hash_to_entry[hash].hash() != hash && acquired_infos[hash].hash() == 0)) { // Create create the texture and mark the atlas dirty atlas_dirty = true; - m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim->flags & PRIMFLAG_TEXFORMAT_MASK, - prim->texture.width, prim->texture.height, - prim->texture.rowpixels, prim->texture.palette, prim->texture.base)); + m_texinfo.push_back(rectangle_packer::packable_rectangle(hash, prim.flags & PRIMFLAG_TEXFORMAT_MASK, + prim.texture.width, prim.texture.height, + prim.texture.rowpixels, prim.texture.palette, prim.texture.base)); acquired_infos[hash] = m_texinfo[m_texinfo.size() - 1]; } } diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 708ed01cd6c..8f18bae8aac 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -630,50 +630,50 @@ int renderer_d3d9::pre_window_draw_check() void d3d_texture_manager::update_textures() { - for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *m_renderer->window().m_primlist) { - if (prim->texture.base != nullptr) + if (prim.texture.base != nullptr) { - texture_info *texture = find_texinfo(&prim->texture, prim->flags); + texture_info *texture = find_texinfo(&prim.texture, prim.flags); if (texture == nullptr) { if (m_renderer->get_shaders()->enabled()) { // if there isn't one, create a new texture without prescale - texture = global_alloc(texture_info(this, &prim->texture, 1, prim->flags)); + texture = global_alloc(texture_info(this, &prim.texture, 1, prim.flags)); } else { // if there isn't one, create a new texture - texture = global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags)); + texture = global_alloc(texture_info(this, &prim.texture, m_renderer->window().prescale(), prim.flags)); } } else { // if there is one, but with a different seqid, copy the data - if (texture->get_texinfo().seqid != prim->texture.seqid) + if (texture->get_texinfo().seqid != prim.texture.seqid) { - texture->set_data(&prim->texture, prim->flags); - texture->get_texinfo().seqid = prim->texture.seqid; + texture->set_data(&prim.texture, prim.flags); + texture->get_texinfo().seqid = prim.texture.seqid; } } if (m_renderer->get_shaders()->enabled()) { - if (!m_renderer->get_shaders()->get_texture_target(prim, texture)) + if (!m_renderer->get_shaders()->get_texture_target(&prim, texture)) { - if (!m_renderer->get_shaders()->register_texture(prim, texture)) + if (!m_renderer->get_shaders()->register_texture(&prim, texture)) { d3dintf->post_fx_available = false; } } } } - else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags)) + else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim.flags)) { - if (!m_renderer->get_shaders()->get_vector_target(prim)) + if (!m_renderer->get_shaders()->get_vector_target(&prim)) { - m_renderer->get_shaders()->create_vector_target(prim); + m_renderer->get_shaders()->create_vector_target(&prim); } } } @@ -706,9 +706,9 @@ void renderer_d3d9::begin_frame() // loop over line primitives m_line_count = 0; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags)) + if (prim.type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim.flags)) { m_line_count++; } @@ -718,12 +718,12 @@ void renderer_d3d9::begin_frame() void renderer_d3d9::process_primitives() { // Rotating index for vector time offsets - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - if (PRIMFLAG_GET_VECTOR(prim->flags)) + if (PRIMFLAG_GET_VECTOR(prim.flags)) { if (m_line_count > 0) batch_vectors(); @@ -1404,12 +1404,12 @@ void renderer_d3d9::batch_vectors() int line_index = 0; float period = options.screen_vector_time_period(); UINT32 cached_flags = 0; - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - switch (prim->type) + switch (prim.type) { case render_primitive::LINE: - if (PRIMFLAG_GET_VECTOR(prim->flags)) + if (PRIMFLAG_GET_VECTOR(prim.flags)) { if (period == 0.0f || m_line_count == 0) { @@ -1420,15 +1420,15 @@ void renderer_d3d9::batch_vectors() batch_vector(prim, (float)(start_index + line_index) / ((float)m_line_count * period)); line_index++; } - cached_flags = prim->flags; + cached_flags = prim.flags; } break; case render_primitive::QUAD: - if (PRIMFLAG_GET_VECTORBUF(prim->flags)) + if (PRIMFLAG_GET_VECTORBUF(prim.flags)) { - width = prim->bounds.x1 - prim->bounds.x0; - height = prim->bounds.y1 - prim->bounds.y0; + width = prim.bounds.x1 - prim.bounds.x0; + height = prim.bounds.y1 - prim.bounds.y0; } break; @@ -1452,10 +1452,10 @@ void renderer_d3d9::batch_vectors() m_line_count = 0; } -void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) +void renderer_d3d9::batch_vector(const render_primitive &prim, float line_time) { // compute the effective width based on the direction of the line - float effwidth = prim->width; + float effwidth = prim.width; if (effwidth < 0.5f) { effwidth = 0.5f; @@ -1463,10 +1463,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) // determine the bounds of a quad to draw this line render_bounds b0, b1; - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // iterate over AA steps - for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; + for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { // get a pointer to the vertex buffer @@ -1492,10 +1492,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) float line_length = sqrtf(dx * dx + dy * dy); // determine the color of the line - INT32 r = (INT32)(prim->color.r * step->weight * 255.0f); - INT32 g = (INT32)(prim->color.g * step->weight * 255.0f); - INT32 b = (INT32)(prim->color.b * step->weight * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * step->weight * 255.0f); + INT32 g = (INT32)(prim.color.g * step->weight * 255.0f); + INT32 b = (INT32)(prim.color.b * step->weight * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); if (r > 255 || g > 255 || b > 255) { if (r > 2*255 || g > 2*255 || b > 2*255) @@ -1554,10 +1554,10 @@ void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) // draw_line //============================================================ -void renderer_d3d9::draw_line(const render_primitive *prim) +void renderer_d3d9::draw_line(const render_primitive &prim) { // compute the effective width based on the direction of the line - float effwidth = prim->width; + float effwidth = prim.width; if (effwidth < 0.5f) { effwidth = 0.5f; @@ -1565,10 +1565,10 @@ void renderer_d3d9::draw_line(const render_primitive *prim) // determine the bounds of a quad to draw this line render_bounds b0, b1; - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // iterate over AA steps - for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; + for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { // get a pointer to the vertex buffer @@ -1593,10 +1593,10 @@ void renderer_d3d9::draw_line(const render_primitive *prim) vertex[3].y = b1.y1 + step->yoffs; // determine the color of the line - INT32 r = (INT32)(prim->color.r * step->weight * 255.0f); - INT32 g = (INT32)(prim->color.g * step->weight * 255.0f); - INT32 b = (INT32)(prim->color.b * step->weight * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * step->weight * 255.0f); + INT32 g = (INT32)(prim.color.g * step->weight * 255.0f); + INT32 b = (INT32)(prim.color.b * step->weight * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; @@ -1627,7 +1627,7 @@ void renderer_d3d9::draw_line(const render_primitive *prim) } // now add a polygon entry - m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, get_vector_texture(), + m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f); m_numpolys++; } @@ -1638,9 +1638,9 @@ void renderer_d3d9::draw_line(const render_primitive *prim) // draw_quad //============================================================ -void renderer_d3d9::draw_quad(const render_primitive *prim) +void renderer_d3d9::draw_quad(const render_primitive &prim) { - texture_info *texture = m_texture_manager->find_texinfo(&prim->texture, prim->flags); + texture_info *texture = m_texture_manager->find_texinfo(&prim.texture, prim.flags); if (texture == nullptr) { @@ -1653,16 +1653,16 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) return; // fill in the vertexes clockwise - vertex[0].x = prim->bounds.x0; - vertex[0].y = prim->bounds.y0; - vertex[1].x = prim->bounds.x1; - vertex[1].y = prim->bounds.y0; - vertex[2].x = prim->bounds.x0; - vertex[2].y = prim->bounds.y1; - vertex[3].x = prim->bounds.x1; - vertex[3].y = prim->bounds.y1; - float width = prim->bounds.x1 - prim->bounds.x0; - float height = prim->bounds.y1 - prim->bounds.y0; + vertex[0].x = prim.bounds.x0; + vertex[0].y = prim.bounds.y0; + vertex[1].x = prim.bounds.x1; + vertex[1].y = prim.bounds.y0; + vertex[2].x = prim.bounds.x0; + vertex[2].y = prim.bounds.y1; + vertex[3].x = prim.bounds.x1; + vertex[3].y = prim.bounds.y1; + float width = prim.bounds.x1 - prim.bounds.x0; + float height = prim.bounds.y1 - prim.bounds.y0; // set the texture coordinates if (texture != nullptr) @@ -1671,21 +1671,21 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) vec2f& stop = texture->get_uvstop(); vec2f delta = stop - start; - vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u; - vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v; - vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u; - vertex[1].v0 = start.c.y + delta.c.y * prim->texcoords.tr.v; - vertex[2].u0 = start.c.x + delta.c.x * prim->texcoords.bl.u; - vertex[2].v0 = start.c.y + delta.c.y * prim->texcoords.bl.v; - vertex[3].u0 = start.c.x + delta.c.x * prim->texcoords.br.u; - vertex[3].v0 = start.c.y + delta.c.y * prim->texcoords.br.v; + vertex[0].u0 = start.c.x + delta.c.x * prim.texcoords.tl.u; + vertex[0].v0 = start.c.y + delta.c.y * prim.texcoords.tl.v; + vertex[1].u0 = start.c.x + delta.c.x * prim.texcoords.tr.u; + vertex[1].v0 = start.c.y + delta.c.y * prim.texcoords.tr.v; + vertex[2].u0 = start.c.x + delta.c.x * prim.texcoords.bl.u; + vertex[2].v0 = start.c.y + delta.c.y * prim.texcoords.bl.v; + vertex[3].u0 = start.c.x + delta.c.x * prim.texcoords.br.u; + vertex[3].v0 = start.c.y + delta.c.y * prim.texcoords.br.v; } // determine the color, allowing for over modulation - INT32 r = (INT32)(prim->color.r * 255.0f); - INT32 g = (INT32)(prim->color.g * 255.0f); - INT32 b = (INT32)(prim->color.b * 255.0f); - INT32 a = (INT32)(prim->color.a * 255.0f); + INT32 r = (INT32)(prim.color.r * 255.0f); + INT32 g = (INT32)(prim.color.g * 255.0f); + INT32 b = (INT32)(prim.color.b * 255.0f); + INT32 a = (INT32)(prim.color.a * 255.0f); DWORD modmode = D3DTOP_MODULATE; if (texture != nullptr) { @@ -1720,7 +1720,7 @@ void renderer_d3d9::draw_quad(const render_primitive *prim) } // now add a polygon entry - m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, texture, modmode, width, height); + m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, modmode, width, height); m_numpolys++; } diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index de8506ebfbd..2f4b675cba2 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -85,9 +85,9 @@ public: void begin_frame(); void end_frame(); - void draw_line(const render_primitive *prim); - void draw_quad(const render_primitive *prim); - void batch_vector(const render_primitive *prim, float line_time); + void draw_line(const render_primitive &prim); + void draw_quad(const render_primitive &prim); + void batch_vector(const render_primitive &prim, float line_time); void batch_vectors(); vertex * mesh_alloc(int numverts); diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp index 96c1559b23a..452a3c570ab 100644 --- a/src/osd/modules/render/drawogl.cpp +++ b/src/osd/modules/render/drawogl.cpp @@ -1014,7 +1014,6 @@ void renderer_ogl::loadGLExtensions() int renderer_ogl::draw(const int update) { - render_primitive *prim; ogl_texture_info *texture=nullptr; float vofs, hofs; int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE; @@ -1160,11 +1159,11 @@ int renderer_ogl::draw(const int update) window().m_primlist->acquire_lock(); // now draw - for (prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { int i; - switch (prim->type) + switch (prim.type) { /** * Try to stay in one Begin/End block as long as possible, @@ -1173,7 +1172,7 @@ int renderer_ogl::draw(const int update) case render_primitive::LINE: #if !USE_WIN32_STYLE_LINES // check if it's really a point - if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0)) + if (((prim.bounds.x1 - prim.bounds.x0) == 0) && ((prim.bounds.y1 - prim.bounds.y0) == 0)) { curPrimitive=GL_POINTS; } else { @@ -1188,10 +1187,10 @@ int renderer_ogl::draw(const int update) if ( pendingPrimitive==GL_NO_PRIMITIVE ) { - set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)); } - glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a); + glColor4f(prim.color.r, prim.color.g, prim.color.b, prim.color.a); if(pendingPrimitive!=curPrimitive) { @@ -1202,12 +1201,12 @@ int renderer_ogl::draw(const int update) // check if it's really a point if (curPrimitive==GL_POINTS) { - glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs); + glVertex2f(prim.bounds.x0+hofs, prim.bounds.y0+vofs); } else { - glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs); - glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs); + glVertex2f(prim.bounds.x0+hofs, prim.bounds.y0+vofs); + glVertex2f(prim.bounds.x1+hofs, prim.bounds.y1+vofs); } #else { @@ -1223,15 +1222,15 @@ int renderer_ogl::draw(const int update) pendingPrimitive=GL_NO_PRIMITIVE; } - set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim.flags)); // compute the effective width based on the direction of the line - effwidth = prim->width(); + effwidth = prim.width(); if (effwidth < 0.5f) effwidth = 0.5f; // determine the bounds of a quad to draw this line - render_line_to_quad(&prim->bounds, effwidth, &b0, &b1); + render_line_to_quad(&prim.bounds, effwidth, &b0, &b1); // fix window position b0.x0 += hofs; @@ -1244,7 +1243,7 @@ int renderer_ogl::draw(const int update) b1.y1 += vofs; // iterate over AA steps - for (step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) + for (step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++) { glBegin(GL_TRIANGLE_STRIP); @@ -1261,17 +1260,17 @@ int renderer_ogl::draw(const int update) glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs); // determine the color of the line - r = (prim->color.r * step->weight); - g = (prim->color.g * step->weight); - b = (prim->color.b * step->weight); - a = (prim->color.a * 255.0f); + r = (prim.color.r * step->weight); + g = (prim.color.g * step->weight); + b = (prim.color.b * step->weight); + a = (prim.color.a * 255.0f); if (r > 1.0) r = 1.0; if (g > 1.0) g = 1.0; if (b > 1.0) b = 1.0; if (a > 1.0) a = 1.0; glColor4f(r, g, b, a); -// texture = texture_update(window, prim, 0); +// texture = texture_update(window, &prim, 0); // if (texture) printf("line has texture!\n"); // if we have a texture to use for the vectors, use it here @@ -1306,11 +1305,11 @@ int renderer_ogl::draw(const int update) pendingPrimitive=GL_NO_PRIMITIVE; } - glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a); + glColor4f(prim.color.r, prim.color.g, prim.color.b, prim.color.a); - set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)); + set_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)); - texture = texture_update(prim, 0); + texture = texture_update(&prim, 0); if ( texture && texture->type==TEXTURE_TYPE_SHADER ) { @@ -1319,14 +1318,14 @@ int renderer_ogl::draw(const int update) if ( i==m_glsl_program_mb2sc ) { // i==glsl_program_mb2sc -> transformation mamebm->scrn - m_texVerticex[0]=prim->bounds.x0 + hofs; - m_texVerticex[1]=prim->bounds.y0 + vofs; - m_texVerticex[2]=prim->bounds.x1 + hofs; - m_texVerticex[3]=prim->bounds.y0 + vofs; - m_texVerticex[4]=prim->bounds.x1 + hofs; - m_texVerticex[5]=prim->bounds.y1 + vofs; - m_texVerticex[6]=prim->bounds.x0 + hofs; - m_texVerticex[7]=prim->bounds.y1 + vofs; + m_texVerticex[0]=prim.bounds.x0 + hofs; + m_texVerticex[1]=prim.bounds.y0 + vofs; + m_texVerticex[2]=prim.bounds.x1 + hofs; + m_texVerticex[3]=prim.bounds.y0 + vofs; + m_texVerticex[4]=prim.bounds.x1 + hofs; + m_texVerticex[5]=prim.bounds.y1 + vofs; + m_texVerticex[6]=prim.bounds.x0 + hofs; + m_texVerticex[7]=prim.bounds.y1 + vofs; } else { // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1) on texture dimensions m_texVerticex[0]=(GLfloat)0.0; @@ -1341,19 +1340,19 @@ int renderer_ogl::draw(const int update) if(i>0) // first fetch already done { - texture = texture_update(prim, i); + texture = texture_update(&prim, i); } glDrawArrays(GL_QUADS, 0, 4); } } else { - m_texVerticex[0]=prim->bounds.x0 + hofs; - m_texVerticex[1]=prim->bounds.y0 + vofs; - m_texVerticex[2]=prim->bounds.x1 + hofs; - m_texVerticex[3]=prim->bounds.y0 + vofs; - m_texVerticex[4]=prim->bounds.x1 + hofs; - m_texVerticex[5]=prim->bounds.y1 + vofs; - m_texVerticex[6]=prim->bounds.x0 + hofs; - m_texVerticex[7]=prim->bounds.y1 + vofs; + m_texVerticex[0]=prim.bounds.x0 + hofs; + m_texVerticex[1]=prim.bounds.y0 + vofs; + m_texVerticex[2]=prim.bounds.x1 + hofs; + m_texVerticex[3]=prim.bounds.y0 + vofs; + m_texVerticex[4]=prim.bounds.x1 + hofs; + m_texVerticex[5]=prim.bounds.y1 + vofs; + m_texVerticex[6]=prim.bounds.x0 + hofs; + m_texVerticex[7]=prim.bounds.y1 + vofs; glDrawArrays(GL_QUADS, 0, 4); } diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp index 932f88acc2b..2450dd1b8b3 100644 --- a/src/osd/modules/render/drawsdl.cpp +++ b/src/osd/modules/render/drawsdl.cpp @@ -397,12 +397,12 @@ int renderer_sdl2::draw(int update) // FIXME: this could be a lot easier if we get the primlist here! // Bounds would be set fit for purpose and done! - for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + for (render_primitive &prim : *window().m_primlist) { - prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f); - prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f); - prim->bounds.y0 = floor(fh * prim->bounds.y0 + 0.5f); - prim->bounds.y1 = floor(fh * prim->bounds.y1 + 0.5f); + prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f); + prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f); + prim.bounds.y0 = floor(fh * prim.bounds.y0 + 0.5f); + prim.bounds.y1 = floor(fh * prim.bounds.y1 + 0.5f); } // render to it diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index c4a1c458768..55cbde387e6 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -1049,7 +1049,7 @@ const char *symbol_manager::symbol_for_address(FPTR address) if (!query_system_for_address(address)) { // if that fails, scan the cache if we have one - if (m_cache.first() != nullptr) + if (!m_cache.empty()) scan_cache_for_address(address); // or else try to open a sym/map file and find it there @@ -1172,13 +1172,13 @@ void symbol_manager::scan_cache_for_address(FPTR address) FPTR best_addr = 0; // walk the cache, looking for valid entries - for (cache_entry *entry = m_cache.first(); entry != nullptr; entry = entry->next()) + for (cache_entry &entry : m_cache) // if this is the best one so far, remember it - if (entry->m_address <= address && entry->m_address > best_addr) + if (entry.m_address <= address && entry.m_address > best_addr) { - best_addr = entry->m_address; - best_symbol = entry->m_name; + best_addr = entry.m_address; + best_symbol = entry.m_name; } // format the symbol and remember the last base